weevy_server/
lib.rs

1use anyhow::Context as AnyhowContext;
2use axum::{body::Body, extract::Request};
3use base64::Engine;
4use swc_atoms::Atom;
5use swc_common::{
6    FileName, FilePathMapping, SourceMap, Spanned, SyntaxContext,
7    errors::{ColorConfig, Handler},
8    sync::Lrc,
9};
10use swc_ecma_ast::{EsVersion, Expr, Ident, IdentName, MemberExpr};
11use swc_ecma_parser::{Parser, StringInput, Syntax, lexer::Lexer};
12use swc_ecma_visit::VisitMutWith;
13use weevy_swc_core::{default_source_mapper, wevy};
14
15pub async fn server(a: Request) -> anyhow::Result<Body> {
16    let q2 = a.uri().query().context("in getting the query")?;
17    let q = q2.split("&");
18    let v = match q.clone().find_map(|q| q.strip_prefix("code=")) {
19        Some(a) => base64::engine::general_purpose::STANDARD.decode(a)?,
20        None => {
21            let exter = q
22                .clone()
23                .find_map(|q| q.strip_prefix("extern="))
24                .context("in getting the external url or code")?;
25            let exter = base64::engine::general_purpose::STANDARD.decode(exter)?;
26            let exter = String::from_utf8(exter)?;
27            reqwest::get(exter).await?.bytes().await?.into()
28        }
29    };
30    let v = String::from_utf8(v)?;
31    let mut cm = Lrc::new(SourceMap::new(FilePathMapping::default()));
32    // let a =
33    let fm = cm.new_source_file(FileName::Custom("source.js".into()).into(), v);
34    let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, false, Some(cm.clone()));
35    let lexer = Lexer::new(
36        // We want to parse ecmascript
37        Syntax::Es(Default::default()),
38        // EsVersion defaults to es5
39        EsVersion::latest(),
40        StringInput::from(&*fm),
41        None,
42    );
43
44    let mut parser = Parser::new_from(lexer);
45
46    for e in parser.take_errors() {
47        e.into_diagnostic(&handler).emit();
48    }
49
50    let mut prog = parser
51        .parse_program()
52        .map_err(|mut e| {
53            // Unrecoverable fatal error occurred
54            e.into_diagnostic(&handler).emit()
55        })
56        .expect("failed to parser module");
57
58    prog.visit_mut_with(&mut weevy_swc_core::SourceMapper {
59        sm: cm.clone(),
60        data: Default::default(),
61        id: Ident::new(
62            Atom::new(format!(
63                "__Weevy_{}_Inject",
64                base64::engine::general_purpose::STANDARD.encode(q2)
65            )),
66            prog.span(),
67            SyntaxContext::empty(),
68        ),
69        root: SyntaxContext::empty(),
70        source_mapper: default_source_mapper(&prog, SyntaxContext::empty()),
71    });
72    prog.visit_mut_with(&mut weevy_swc_core::Wimple {
73        root: SyntaxContext::empty(),
74        guest_id: Atom::new("MainContent"),
75    });
76
77    Ok(Body::new(swc_ecma_codegen::to_code(&prog)))
78}