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