1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
//! Wakaru: a JavaScript decompiler exposed as a compiler-like service.
//!
//! The stable crate root offers two end-to-end operations:
//!
//! - [`decompile`] — rewrite one minified/transpiled source into readable,
//! modern JavaScript.
//! - [`unpack`] — split one or more bundle/chunk inputs into modules and
//! decompile each; [`UnpackJob`] is the incremental intake form of the same
//! operation for directory walkers.
//!
//! Optional workflows live in cohesive namespaces: [`bun`] (single-file
//! executable extraction), [`debug`] (normalization, rule tracing, rule
//! metadata), [`sourcemap`] (embedded-source extraction), and [`vue`]
//! (experimental standalone SFC recovery).
//!
//! The API is deliberately not an SWC transformation toolkit: it never exposes
//! SWC AST types, individual rewrite visitors, detector objects, prepared
//! ASTs, or cross-module fact structures. Partial recovery is represented
//! structurally ([`ModuleStatus`], [`Diagnostic`]) instead of being hidden in
//! warning strings.
//!
//! Design decisions, compatibility boundaries, and the internal processing
//! invariants behind this surface are recorded in `docs/public-api.md`.
//!
//! # Publishing model
//!
//! The façade is published as `wakaru`. Cargo cannot package a façade with an
//! unpublished path dependency, so `wakaru-core` is also published as a
//! lockstep, exact-version implementation dependency. It remains explicitly
//! unsupported as an integration surface and may change whenever the façade
//! version changes.
//!
//! # Examples
//!
//! Single-file decompile:
//!
//! ```no_run
//! use wakaru::{decompile, DecompileOptions, Source};
//!
//! # fn main() -> wakaru::Result<()> {
//! let minified = String::from("var a=!0;");
//! let output = decompile(Source::new("input.js", minified), DecompileOptions::default())?;
//!
//! println!("{}", output.module.code);
//! for diagnostic in output.diagnostics {
//! eprintln!("{}", diagnostic.message);
//! }
//! # Ok(())
//! # }
//! ```
//!
//! Bundle/chunk set:
//!
//! ```no_run
//! use wakaru::{
//! unpack, DceMode, ModuleMode, RewriteLevel, RewriteOptions, Source, UnmatchedInput,
//! UnpackMode, UnpackOptions,
//! };
//!
//! # fn main() -> wakaru::Result<()> {
//! # let (entry, chunk) = (String::new(), String::new());
//! let output = unpack(
//! vec![Source::new("entry.js", entry), Source::new("chunk.js", chunk)],
//! UnpackOptions::default()
//! .with_modules(ModuleMode::Decompile(
//! RewriteOptions::default()
//! .with_level(RewriteLevel::Standard)
//! .with_dce(DceMode::TransformOnly),
//! ))
//! .with_mode(UnpackMode::Auto)
//! .with_unmatched(UnmatchedInput::Process)
//! .with_diagnostics(true),
//! )?;
//!
//! for module in output.modules {
//! println!("{}: {} bytes", module.filename, module.code.len());
//! }
//! # Ok(())
//! # }
//! ```
//!
//! Directory-style detected-only processing with bounded intake memory:
//!
//! ```no_run
//! use wakaru::{InputAction, Source, UnmatchedInput, UnpackJob, UnpackOptions};
//!
//! # fn main() -> anyhow::Result<()> {
//! # let javascript_candidate_paths: Vec<std::path::PathBuf> = Vec::new();
//! let mut job = UnpackJob::new(UnpackOptions::default().with_unmatched(UnmatchedInput::Skip))?;
//!
//! for path in javascript_candidate_paths {
//! let code = std::fs::read_to_string(&path)?;
//! job.push(Source::new(path.to_string_lossy(), code))?;
//! }
//!
//! let output = job.finish()?;
//! let skipped = output
//! .inputs
//! .iter()
//! .filter(|input| input.action == InputAction::Skipped)
//! .count();
//! # let _ = skipped;
//! # Ok(())
//! # }
//! ```
pub use decompile;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;