#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct InputId(u32);
impl InputId {
pub(crate) fn from_index(index: usize) -> Self {
Self(index as u32)
}
pub fn get(self) -> u32 {
self.0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SourceSpan {
pub input: InputId,
pub start: u32,
pub end: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum EntryStatus {
Entry,
NonEntry,
Unknown,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum ModuleStatus {
Decompiled,
Raw,
Preserved,
DecompileFailed,
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct ModuleOutput {
pub filename: String,
pub code: String,
pub source_map: Option<String>,
pub provenance: Vec<SourceSpan>,
pub inspection_context: Vec<SourceSpan>,
pub entry: EntryStatus,
pub status: ModuleStatus,
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct DecompileOutput {
pub module: ModuleOutput,
pub diagnostics: Vec<Diagnostic>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum BundleFormat {
Webpack5,
Webpack4,
Browserify,
ClosureModuleManager,
Metro,
SystemJs,
Esbuild,
Amd,
Turbopack,
}
impl BundleFormat {
pub fn as_str(self) -> &'static str {
match self {
Self::Webpack5 => "webpack5",
Self::Webpack4 => "webpack4",
Self::Browserify => "browserify",
Self::ClosureModuleManager => "closure-module-manager",
Self::Metro => "metro",
Self::SystemJs => "systemjs",
Self::Esbuild => "esbuild",
Self::Amd => "amd",
Self::Turbopack => "turbopack",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum InputDetection {
Structural(BundleFormat),
HeuristicScopeHoisted,
Plain,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum InputAction {
Unpacked,
Processed,
Preserved,
Skipped,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub struct InputReceipt {
pub id: InputId,
pub detection: InputDetection,
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct InputReport {
pub id: InputId,
pub filename: String,
pub detection: InputDetection,
pub action: InputAction,
pub module_indices: Vec<usize>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum OutputSafety {
Normal,
InspectionOnly,
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct UnpackOutput {
pub modules: Vec<ModuleOutput>,
pub inputs: Vec<InputReport>,
pub diagnostics: Vec<Diagnostic>,
pub safety: OutputSafety,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum DiagnosticSeverity {
Info,
Warning,
Error,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum DiagnosticCode {
InputParseRecovered,
RawNormalizationFailed,
FactCollectionFailed,
WebpackFactoryRecoveryFailed,
DecompileFailed,
TdzViolation,
DuplicateDeclaration,
ImportCycle,
CrossModuleClassCall,
CommonJsExportUnrecovered,
RuntimeResidual,
OutputParseRecovered,
OutputParseFailed,
}
impl DiagnosticCode {
pub fn as_str(self) -> &'static str {
match self {
Self::InputParseRecovered => "input_parse_recovered",
Self::RawNormalizationFailed => "raw_normalization_failed",
Self::FactCollectionFailed => "fact_collection_failed",
Self::WebpackFactoryRecoveryFailed => "webpack_factory_recovery_failed",
Self::DecompileFailed => "decompile_failed",
Self::TdzViolation => "tdz_violation",
Self::DuplicateDeclaration => "duplicate_declaration",
Self::ImportCycle => "import_cycle",
Self::CrossModuleClassCall => "cross_module_class_call",
Self::CommonJsExportUnrecovered => "commonjs_export_unrecovered",
Self::RuntimeResidual => "runtime_residual",
Self::OutputParseRecovered => "output_parse_recovered",
Self::OutputParseFailed => "output_parse_failed",
}
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct Diagnostic {
pub severity: DiagnosticSeverity,
pub code: DiagnosticCode,
pub message: String,
pub input: Option<InputId>,
pub module: Option<usize>,
pub span: Option<SourceSpan>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn input_ids_are_call_local_ordered_values() {
assert_eq!(InputId::from_index(0).get(), 0);
assert_eq!(InputId::from_index(7).get(), 7);
}
}