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 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 Syntax::Es(Default::default()),
37 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 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}