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