swc_ecma_transforms_module/umd/
config.rs

1use std::collections::HashMap;
2
3use inflector::Inflector;
4use serde::{Deserialize, Serialize};
5use swc_atoms::Atom;
6use swc_common::{errors::HANDLER, sync::Lrc, FileName, SourceMap};
7use swc_ecma_ast::{Expr, Ident};
8use swc_ecma_parser::{parse_file_as_expr, Syntax};
9use swc_ecma_utils::quote_ident;
10
11use super::super::util;
12
13#[derive(Debug, Default, Clone, Serialize, Deserialize)]
14#[serde(deny_unknown_fields, rename_all = "camelCase")]
15pub struct Config {
16    #[serde(default)]
17    pub globals: HashMap<String, String>,
18
19    #[serde(flatten, default)]
20    pub config: util::Config,
21}
22
23impl Config {
24    pub(super) fn build(self, cm: Lrc<SourceMap>) -> BuiltConfig {
25        BuiltConfig {
26            config: self.config,
27            globals: self
28                .globals
29                .into_iter()
30                .map(|(k, v)| {
31                    let parse = |s| {
32                        let fm = cm.new_source_file(
33                            FileName::Internal(format!("<umd-config-{}.js>", s)).into(),
34                            s,
35                        );
36
37                        parse_file_as_expr(
38                            &fm,
39                            Syntax::default(),
40                            Default::default(),
41                            None,
42                            &mut Vec::new(),
43                        )
44                        .map_err(|e| {
45                            if HANDLER.is_set() {
46                                HANDLER.with(|h| e.into_diagnostic(h).emit())
47                            }
48                        })
49                        .unwrap()
50                    };
51                    (k, parse(v))
52                })
53                .collect(),
54        }
55    }
56}
57#[derive(Clone)]
58pub(super) struct BuiltConfig {
59    #[allow(dead_code)]
60    pub globals: HashMap<String, Box<Expr>>,
61    pub config: util::Config,
62}
63
64impl BuiltConfig {
65    pub fn global_name(&self, src: &str) -> Atom {
66        if !src.contains('/') {
67            return src.to_camel_case().into();
68        }
69
70        src.split('/').last().unwrap().to_camel_case().into()
71    }
72
73    pub fn determine_export_name(&self, filename: Lrc<FileName>) -> Ident {
74        match &*filename {
75            FileName::Real(ref path) => {
76                let s = match path.file_stem() {
77                    Some(stem) => self.global_name(&stem.to_string_lossy()),
78                    None => self.global_name(&path.display().to_string()),
79                };
80
81                quote_ident!(s).into()
82            }
83            FileName::Custom(s) => {
84                let s = self.global_name(s);
85                quote_ident!(s).into()
86            }
87            _ => unimplemented!("determine_export_name({:?})", filename),
88        }
89    }
90}