1use std::collections::BTreeMap;
2use std::fmt;
3use std::future::Future;
4use std::pin::Pin;
5use std::sync::Arc;
6
7use crate::ast::common::Span;
8use crate::ast::{CssAst, Document};
9use crate::error::SourcePosition;
10use crate::{CompileError, LineColumn};
11use camino::Utf8Path;
12use camino::Utf8PathBuf;
13use lightningcss::stylesheet::ParserOptions as LightningParserOptions;
14use serde::{Deserialize, Deserializer, Serialize, Serializer};
15
16mod runes_mode;
17pub(crate) mod scan;
18pub(crate) mod validation;
19pub(crate) use runes_mode::*;
20pub(crate) use scan::*;
21pub(crate) use svelte_syntax::{
22 ElementKind, SvelteElementKind, classify_element_name, is_custom_element_name,
23 is_valid_component_name, is_valid_element_name, is_void_element_name,
24};
25
26pub static VERSION: &str = "5.53.9";
28
29macro_rules! impl_enum_text_traits {
30 ($ty:ty { $($text:literal => $variant:path),+ $(,)? }) => {
31 impl $ty {
32 #[must_use]
33 pub const fn as_str(self) -> &'static str {
34 match self {
35 $($variant => $text),+
36 }
37 }
38 }
39
40 impl fmt::Display for $ty {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 f.write_str(self.as_str())
43 }
44 }
45
46 impl std::str::FromStr for $ty {
47 type Err = ();
48
49 fn from_str(value: &str) -> Result<Self, Self::Err> {
50 match value {
51 $($text => Ok($variant),)+
52 _ => Err(()),
53 }
54 }
55 }
56 };
57}
58
59#[derive(Clone, Copy)]
60pub struct CssHashInput<'a> {
62 pub name: &'a str,
63 pub filename: &'a str,
64 pub css: &'a str,
65 pub hash: fn(&str) -> String,
66}
67
68impl fmt::Debug for CssHashInput<'_> {
69 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70 f.debug_struct("CssHashInput")
71 .field("name", &self.name)
72 .field("filename", &self.filename)
73 .field("css", &self.css)
74 .finish_non_exhaustive()
75 }
76}
77
78#[derive(Clone)]
79pub struct WarningFilterCallback(Arc<dyn Fn(&Warning) -> bool + 'static>);
81
82impl WarningFilterCallback {
83 #[must_use]
84 pub fn new<F>(callback: F) -> Self
85 where
86 F: Fn(&Warning) -> bool + 'static,
87 {
88 Self(Arc::new(callback))
89 }
90
91 pub(crate) fn call(&self, warning: &Warning) -> bool {
92 (self.0)(warning)
93 }
94}
95
96impl fmt::Debug for WarningFilterCallback {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 f.write_str("WarningFilterCallback(..)")
99 }
100}
101
102#[derive(Clone)]
103pub struct CssHashGetterCallback(Arc<dyn for<'a> Fn(CssHashInput<'a>) -> Arc<str> + 'static>);
105
106impl CssHashGetterCallback {
107 #[must_use]
108 pub fn new<F, S>(callback: F) -> Self
109 where
110 F: for<'a> Fn(CssHashInput<'a>) -> S + 'static,
111 S: Into<Arc<str>>,
112 {
113 Self(Arc::new(move |input| callback(input).into()))
114 }
115
116 pub(crate) fn call(&self, input: CssHashInput<'_>) -> Arc<str> {
117 (self.0)(input)
118 }
119}
120
121impl fmt::Debug for CssHashGetterCallback {
122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
123 f.write_str("CssHashGetterCallback(..)")
124 }
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
128#[serde(rename_all = "kebab-case")]
129pub enum ParseMode {
131 #[default]
132 Legacy,
133 Modern,
134}
135
136impl_enum_text_traits!(ParseMode {
137 "legacy" => ParseMode::Legacy,
138 "modern" => ParseMode::Modern,
139});
140
141#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
142#[serde(default)]
143pub struct ParseOptions {
145 pub filename: Option<Utf8PathBuf>,
147 pub root_dir: Option<Utf8PathBuf>,
149 pub modern: Option<bool>,
151 pub mode: ParseMode,
153 pub loose: bool,
155}
156
157impl ParseOptions {
158 #[must_use]
159 pub fn effective_mode(&self) -> ParseMode {
160 match self.modern {
161 Some(true) => ParseMode::Modern,
162 Some(false) => ParseMode::Legacy,
163 None => self.mode,
164 }
165 }
166}
167
168#[derive(Debug, Clone, Serialize, Deserialize, Default)]
169#[serde(default)]
170pub struct PrintOptions {
172 pub preserve_whitespace: bool,
174}
175
176#[derive(Clone, Copy, Debug)]
177pub enum ModernPrintTarget<'a> {
179 Root {
180 source: &'a str,
181 root: &'a crate::ast::modern::Root,
182 },
183 Fragment {
184 source: &'a str,
185 fragment: &'a crate::ast::modern::Fragment,
186 },
187 Node {
188 source: &'a str,
189 node: &'a crate::ast::modern::Node,
190 },
191 Script {
192 source: &'a str,
193 script: &'a crate::ast::modern::Script,
194 },
195 Css {
196 source: &'a str,
197 stylesheet: &'a crate::ast::modern::Css,
198 },
199 CssNode {
200 source: &'a str,
201 node: &'a crate::ast::modern::CssNode,
202 },
203 Attribute {
204 source: &'a str,
205 attribute: &'a crate::ast::modern::Attribute,
206 },
207 Options {
208 source: &'a str,
209 options: &'a crate::ast::modern::Options,
210 },
211 Comment {
212 source: &'a str,
213 comment: &'a crate::ast::modern::Comment,
214 },
215}
216
217impl<'a> ModernPrintTarget<'a> {
218 pub const fn root(source: &'a str, root: &'a crate::ast::modern::Root) -> Self {
219 Self::Root { source, root }
220 }
221
222 pub const fn fragment(source: &'a str, fragment: &'a crate::ast::modern::Fragment) -> Self {
223 Self::Fragment { source, fragment }
224 }
225
226 pub const fn node(source: &'a str, node: &'a crate::ast::modern::Node) -> Self {
227 Self::Node { source, node }
228 }
229
230 pub const fn script(source: &'a str, script: &'a crate::ast::modern::Script) -> Self {
231 Self::Script { source, script }
232 }
233
234 pub const fn css(source: &'a str, stylesheet: &'a crate::ast::modern::Css) -> Self {
235 Self::Css { source, stylesheet }
236 }
237
238 pub const fn css_node(source: &'a str, node: &'a crate::ast::modern::CssNode) -> Self {
239 Self::CssNode { source, node }
240 }
241
242 pub const fn attribute(source: &'a str, attribute: &'a crate::ast::modern::Attribute) -> Self {
243 Self::Attribute { source, attribute }
244 }
245
246 pub const fn options(source: &'a str, options: &'a crate::ast::modern::Options) -> Self {
247 Self::Options { source, options }
248 }
249
250 pub const fn comment(source: &'a str, comment: &'a crate::ast::modern::Comment) -> Self {
251 Self::Comment { source, comment }
252 }
253
254 pub(crate) const fn source(self) -> &'a str {
255 match self {
256 Self::Root { source, .. }
257 | Self::Fragment { source, .. }
258 | Self::Node { source, .. }
259 | Self::Script { source, .. }
260 | Self::Css { source, .. }
261 | Self::CssNode { source, .. }
262 | Self::Attribute { source, .. }
263 | Self::Options { source, .. }
264 | Self::Comment { source, .. } => source,
265 }
266 }
267
268 pub(crate) fn raw_slice(self) -> Option<&'a str> {
269 let source = self.source();
270 let (start, end) = match self {
271 Self::Root { root, .. } => (root.start, root.end),
272 Self::Fragment { fragment, .. } => {
273 let first = fragment.nodes.first()?;
274 let last = fragment.nodes.last()?;
275 (first.start(), last.end())
276 }
277 Self::Node { node, .. } => (node.start(), node.end()),
278 Self::Script { script, .. } => (script.start, script.end),
279 Self::Css { stylesheet, .. } => (stylesheet.start, stylesheet.end),
280 Self::CssNode { node, .. } => match node {
281 crate::ast::modern::CssNode::Rule(rule) => (rule.start, rule.end),
282 crate::ast::modern::CssNode::Atrule(atrule) => (atrule.start, atrule.end),
283 },
284 Self::Attribute { attribute, .. } => match attribute {
285 crate::ast::modern::Attribute::Attribute(attribute) => {
286 (attribute.start, attribute.end)
287 }
288 crate::ast::modern::Attribute::SpreadAttribute(attribute) => {
289 (attribute.start, attribute.end)
290 }
291 crate::ast::modern::Attribute::BindDirective(attribute)
292 | crate::ast::modern::Attribute::OnDirective(attribute)
293 | crate::ast::modern::Attribute::ClassDirective(attribute)
294 | crate::ast::modern::Attribute::LetDirective(attribute)
295 | crate::ast::modern::Attribute::AnimateDirective(attribute)
296 | crate::ast::modern::Attribute::UseDirective(attribute) => {
297 (attribute.start, attribute.end)
298 }
299 crate::ast::modern::Attribute::StyleDirective(attribute) => {
300 (attribute.start, attribute.end)
301 }
302 crate::ast::modern::Attribute::TransitionDirective(attribute) => {
303 (attribute.start, attribute.end)
304 }
305 crate::ast::modern::Attribute::AttachTag(attribute) => {
306 (attribute.start, attribute.end)
307 }
308 },
309 Self::Options { options, .. } => (options.start, options.end),
310 Self::Comment { comment, .. } => (comment.start, comment.end),
311 };
312
313 source.get(start..end)
314 }
315}
316
317#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
318#[serde(rename_all = "lowercase")]
319pub enum Namespace {
320 #[default]
321 Html,
322 Svg,
323 Mathml,
324}
325
326impl_enum_text_traits!(Namespace {
327 "html" => Namespace::Html,
328 "svg" => Namespace::Svg,
329 "mathml" => Namespace::Mathml,
330});
331
332#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
333#[serde(rename_all = "lowercase")]
334pub enum CssOutputMode {
335 Injected,
336 #[default]
337 External,
338}
339
340impl_enum_text_traits!(CssOutputMode {
341 "injected" => CssOutputMode::Injected,
342 "external" => CssOutputMode::External,
343});
344
345#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
346pub enum CompatibilityComponentApi {
347 V4,
348 #[default]
349 V5,
350}
351
352impl_enum_text_traits!(CompatibilityComponentApi {
353 "4" => CompatibilityComponentApi::V4,
354 "5" => CompatibilityComponentApi::V5,
355});
356
357impl Serialize for CompatibilityComponentApi {
358 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
359 where
360 S: Serializer,
361 {
362 serializer.serialize_u8(match self {
363 Self::V4 => 4,
364 Self::V5 => 5,
365 })
366 }
367}
368
369impl<'de> Deserialize<'de> for CompatibilityComponentApi {
370 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
371 where
372 D: Deserializer<'de>,
373 {
374 #[derive(Deserialize)]
375 #[serde(untagged)]
376 enum CompatibilityComponentApiRepr {
377 Number(u8),
378 String(Arc<str>),
379 }
380
381 match CompatibilityComponentApiRepr::deserialize(deserializer)? {
382 CompatibilityComponentApiRepr::Number(4) => Ok(Self::V4),
383 CompatibilityComponentApiRepr::Number(5) => Ok(Self::V5),
384 CompatibilityComponentApiRepr::Number(other) => Err(serde::de::Error::invalid_value(
385 serde::de::Unexpected::Unsigned(u64::from(other)),
386 &"4 or 5",
387 )),
388 CompatibilityComponentApiRepr::String(value) => value.parse().map_err(|_| {
389 serde::de::Error::invalid_value(
390 serde::de::Unexpected::Str(value.as_ref()),
391 &"\"4\" or \"5\"",
392 )
393 }),
394 }
395 }
396}
397
398#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
399pub struct CompatibilityOptions {
400 #[serde(alias = "componentApi")]
401 pub component_api: Option<CompatibilityComponentApi>,
402}
403
404#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
405#[serde(rename_all = "kebab-case")]
406pub enum GenerateTarget {
407 None,
408 #[default]
409 Client,
410 Server,
411}
412
413impl_enum_text_traits!(GenerateTarget {
414 "none" => GenerateTarget::None,
415 "client" => GenerateTarget::Client,
416 "server" => GenerateTarget::Server,
417});
418
419#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
420#[serde(rename_all = "lowercase")]
421pub enum FragmentStrategy {
422 #[default]
423 Html,
424 Tree,
425}
426
427impl_enum_text_traits!(FragmentStrategy {
428 "html" => FragmentStrategy::Html,
429 "tree" => FragmentStrategy::Tree,
430});
431
432#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
433#[serde(rename_all = "lowercase")]
434pub enum ErrorMode {
435 #[default]
436 Error,
437 Warn,
438}
439
440impl_enum_text_traits!(ErrorMode {
441 "error" => ErrorMode::Error,
442 "warn" => ErrorMode::Warn,
443});
444
445#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
446#[serde(default)]
447pub struct ExperimentalOptions {
449 pub r#async: bool,
450}
451
452#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
453pub struct SourceMap {
455 pub version: u32,
456 pub file: Option<Arc<str>>,
457 #[serde(alias = "sourceRoot")]
458 pub source_root: Option<Arc<str>>,
459 pub sources: Box<[Arc<str>]>,
460 #[serde(alias = "sourcesContent")]
461 pub sources_content: Option<Box<[Option<Arc<str>>]>>,
462 pub names: Box<[Arc<str>]>,
463 pub mappings: Arc<str>,
464}
465
466#[derive(Debug, Clone, Serialize, Deserialize)]
467#[serde(default)]
468pub struct CompileOptions {
470 pub name: Option<Arc<str>>,
471 pub filename: Option<Utf8PathBuf>,
472 #[serde(alias = "rootDir")]
473 pub root_dir: Option<Utf8PathBuf>,
474 pub generate: GenerateTarget,
475 pub fragments: FragmentStrategy,
476 pub dev: bool,
477 pub hmr: bool,
478 #[serde(alias = "customElement")]
479 pub custom_element: bool,
480 pub accessors: bool,
481 pub namespace: Namespace,
482 pub immutable: bool,
483 pub css: CssOutputMode,
484 #[serde(alias = "warningFilterIgnoreCodes")]
485 pub warning_filter_ignore_codes: Box<[Arc<str>]>,
486 #[serde(skip, default)]
487 pub warning_filter: Option<WarningFilterCallback>,
488 pub runes: Option<bool>,
489 #[serde(alias = "errorMode")]
490 pub error_mode: ErrorMode,
491 pub sourcemap: Option<SourceMap>,
492 #[serde(alias = "outputFilename")]
493 pub output_filename: Option<Utf8PathBuf>,
494 #[serde(alias = "cssOutputFilename")]
495 pub css_output_filename: Option<Utf8PathBuf>,
496 #[serde(alias = "cssHash")]
497 pub css_hash: Option<Arc<str>>,
498 #[serde(skip, default)]
499 pub css_hash_getter: Option<CssHashGetterCallback>,
500 #[serde(alias = "preserveComments")]
501 pub preserve_comments: bool,
502 #[serde(alias = "preserveWhitespace")]
503 pub preserve_whitespace: bool,
504 #[serde(alias = "discloseVersion")]
505 pub disclose_version: bool,
506 pub compatibility: Option<CompatibilityOptions>,
507 #[serde(alias = "modernAst")]
508 pub modern_ast: bool,
509 pub experimental: ExperimentalOptions,
510}
511
512impl Default for CompileOptions {
513 fn default() -> Self {
514 Self {
515 name: None,
516 filename: None,
517 root_dir: None,
518 generate: GenerateTarget::default(),
519 fragments: FragmentStrategy::default(),
520 dev: false,
521 hmr: false,
522 custom_element: false,
523 accessors: false,
524 namespace: Namespace::default(),
525 immutable: false,
526 css: CssOutputMode::default(),
527 warning_filter_ignore_codes: Box::default(),
528 warning_filter: None,
529 runes: None,
530 error_mode: ErrorMode::default(),
531 sourcemap: None,
532 output_filename: None,
533 css_output_filename: None,
534 css_hash: None,
535 css_hash_getter: None,
536 preserve_comments: false,
537 preserve_whitespace: false,
538 disclose_version: true,
539 compatibility: None,
540 modern_ast: false,
541 experimental: ExperimentalOptions::default(),
542 }
543 }
544}
545
546#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
547pub struct Warning {
549 pub code: Arc<str>,
550 pub message: Arc<str>,
551 pub filename: Option<Utf8PathBuf>,
552 pub start: Option<LineColumn>,
553 pub end: Option<LineColumn>,
554 pub frame: Option<Arc<str>>,
555 pub position: Option<[usize; 2]>,
556}
557
558#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
559pub struct OutputArtifact {
561 pub code: Arc<str>,
562 pub map: Option<SourceMap>,
563 pub has_global: Option<bool>,
564}
565
566#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
567pub struct CompileMetadata {
569 pub runes: bool,
570}
571
572#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
573pub struct CompileResult {
575 pub js: OutputArtifact,
576 pub css: Option<OutputArtifact>,
577 pub warnings: Box<[Warning]>,
578 pub metadata: CompileMetadata,
579 pub ast: Option<Document>,
580}
581
582#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
583pub struct PrintedOutput {
585 pub code: Arc<str>,
586 pub map: SourceMap,
587}
588
589#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
590#[serde(untagged)]
591pub enum PreprocessAttributeValue {
593 String(Arc<str>),
594 Bool(bool),
595}
596
597impl Default for PreprocessAttributeValue {
598 fn default() -> Self {
599 Self::Bool(true)
600 }
601}
602
603#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
604pub struct PreprocessAttribute {
606 pub name: Arc<str>,
607 pub value: PreprocessAttributeValue,
608}
609
610pub type PreprocessAttributes = BTreeMap<Arc<str>, PreprocessAttributeValue>;
611
612#[derive(Debug, Clone, Copy)]
613pub struct PreprocessMarkup<'a> {
615 pub content: &'a str,
616 pub filename: Option<&'a Utf8Path>,
617}
618
619#[derive(Debug, Clone, Copy)]
620pub struct PreprocessTag<'a> {
622 pub content: &'a str,
623 pub attributes: &'a PreprocessAttributes,
624 pub markup: &'a str,
625 pub filename: Option<&'a Utf8Path>,
626}
627
628#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
629pub struct PreprocessOutput {
631 pub code: Arc<str>,
632 pub dependencies: Box<[Utf8PathBuf]>,
633 pub map: Option<SourceMap>,
634 pub attributes: Option<Box<[PreprocessAttribute]>>,
635}
636
637pub type MarkupPreprocessor = Arc<
638 dyn for<'a> Fn(PreprocessMarkup<'a>) -> Result<Option<PreprocessOutput>, CompileError>
639 + Send
640 + Sync
641 + 'static,
642>;
643
644pub type TagPreprocessor = Arc<
645 dyn for<'a> Fn(PreprocessTag<'a>) -> Result<Option<PreprocessOutput>, CompileError>
646 + Send
647 + Sync
648 + 'static,
649>;
650
651pub type AsyncMarkupPreprocessor = Arc<
652 dyn for<'a> Fn(
653 PreprocessMarkup<'a>,
654 ) -> Pin<
655 Box<dyn Future<Output = Result<Option<PreprocessOutput>, CompileError>> + Send + 'a>,
656 > + Send
657 + Sync
658 + 'static,
659>;
660
661pub type AsyncTagPreprocessor = Arc<
662 dyn for<'a> Fn(
663 PreprocessTag<'a>,
664 ) -> Pin<
665 Box<dyn Future<Output = Result<Option<PreprocessOutput>, CompileError>> + Send + 'a>,
666 > + Send
667 + Sync
668 + 'static,
669>;
670
671#[derive(Clone, Default)]
672pub struct PreprocessorGroup {
674 pub name: Option<Arc<str>>,
675 pub markup: Option<MarkupPreprocessor>,
676 pub script: Option<TagPreprocessor>,
677 pub style: Option<TagPreprocessor>,
678 pub markup_async: Option<AsyncMarkupPreprocessor>,
679 pub script_async: Option<AsyncTagPreprocessor>,
680 pub style_async: Option<AsyncTagPreprocessor>,
681}
682
683impl fmt::Debug for PreprocessorGroup {
684 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
685 f.debug_struct("PreprocessorGroup")
686 .field("name", &self.name)
687 .field("markup", &self.markup.is_some())
688 .field("script", &self.script.is_some())
689 .field("style", &self.style.is_some())
690 .field("markup_async", &self.markup_async.is_some())
691 .field("script_async", &self.script_async.is_some())
692 .field("style_async", &self.style_async.is_some())
693 .finish()
694 }
695}
696
697impl PreprocessorGroup {
698 #[must_use]
699 pub fn new() -> Self {
700 Self::default()
701 }
702}
703
704#[derive(Debug, Clone, Serialize, Deserialize, Default)]
705#[serde(default)]
706pub struct PreprocessOptions {
708 pub filename: Option<Utf8PathBuf>,
709 #[serde(skip, default)]
710 pub groups: Box<[PreprocessorGroup]>,
711}
712
713#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
714pub struct PreprocessResult {
716 pub code: Arc<str>,
717 pub dependencies: Box<[Utf8PathBuf]>,
718 pub map: Option<SourceMap>,
719}
720
721#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
722#[serde(default)]
723pub struct MigrateOptions {
725 pub filename: Option<Utf8PathBuf>,
726 pub use_ts: bool,
727}
728
729#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
730pub struct MigrateResult {
732 pub code: Arc<str>,
733}
734
735#[derive(Debug, Default)]
736pub struct Compiler;
738
739impl Compiler {
740 #[must_use]
741 pub fn new() -> Self {
742 Self
743 }
744
745 pub fn parse(&self, source: &str, options: ParseOptions) -> Result<Document, CompileError> {
746 crate::compiler::phases::parse::parse_component(source, options)
747 }
748
749 pub fn print(
750 &self,
751 ast: &Document,
752 options: PrintOptions,
753 ) -> Result<PrintedOutput, CompileError> {
754 crate::compiler::phases::transform::print_component(ast, options)
755 }
756
757 pub fn print_modern(
758 &self,
759 ast: ModernPrintTarget<'_>,
760 options: PrintOptions,
761 ) -> Result<PrintedOutput, CompileError> {
762 crate::compiler::phases::transform::print_modern_target(ast, options)
763 }
764
765 pub fn compile(
766 &self,
767 source: &str,
768 options: CompileOptions,
769 ) -> Result<CompileResult, CompileError> {
770 crate::compiler::phases::transform::compile_component(source, options)
771 }
772
773 pub fn compile_module(
774 &self,
775 source: &str,
776 options: CompileOptions,
777 ) -> Result<CompileResult, CompileError> {
778 crate::compiler::phases::transform::compile_module(source, options)
779 }
780
781 pub fn parse_css(&self, source: &str) -> Result<CssAst, CompileError> {
782 crate::compiler::phases::parse::parse_css(source)
783 }
784
785 pub fn preprocess(
786 &self,
787 source: &str,
788 options: PreprocessOptions,
789 ) -> Result<PreprocessResult, CompileError> {
790 crate::compiler::phases::preprocess::preprocess(source, options)
791 }
792
793 pub async fn preprocess_async(
794 &self,
795 source: &str,
796 options: PreprocessOptions,
797 ) -> Result<PreprocessResult, CompileError> {
798 crate::compiler::phases::preprocess::preprocess_async(source, options).await
799 }
800
801 pub fn migrate(
802 &self,
803 source: &str,
804 options: MigrateOptions,
805 ) -> Result<MigrateResult, CompileError> {
806 crate::compiler::phases::migrate::migrate(source, options)
807 }
808}