Files
rea/src/domain/javascript/javascriptPackageImportAliases.ts
T
ShuaixinHuang e9fc8fb30c fix(javascript): preserve runtime path bytes and Electron ownership (#4941)
* fix(javascript): preserve literal percent runtime paths

* fix(javascript): ignore resolve prefixes before the final anchor

* fix(electron): retain application roots for loadFile declarations

* fix(electron): resolve loadFile from enclosing application package

* fix(electron): retain outer application root across package scopes

* fix(electron): derive application ownership from inventoried packages

* fix(electron): retain resolved package entrypoint ownership

* fix(electron): preserve competing application ownership

* fix(electron): retain invalid and omitted runtime ownership

* fix(electron): preserve omitted module ownership and runtime paths

* fix(electron): preserve proven roots before confining page paths

* fix(electron): retain possible owners behind missing imports

* fix(electron): distinguish absent imports and owned page candidates

* fix(electron): keep unavailable JSON out of owner gaps

* fix(electron): retain exact loader formats and default entry status

* fix(electron): retain unavailable entrypoint ownership candidates

* test(ghidra): preserve Windows Node probe prerequisites

* test(ghidra): assert cancellation during profile shutdown

* fix(electron): separate examined imports from frontend ownership

* fix(electron): retain unavailable directory entrypoint owners

* test(jeb): retain Linux ownership prerequisite in isolation

* fix(javascript): retain unchecked loader ownership and literal main paths

* fix(javascript): preserve runtime paths and call-site module aliases

* fix(javascript): bound module alias traversal and preserve projections

* fix(javascript): retain host module and nested artifact path boundaries

* fix(javascript): preserve ESM and archive module loader provenance

* test(javascript): distinguish unmapped containers from missing exports

* fix: retain default module aliases and Electron builtin imports

* fix: preserve host file URL and inward ASAR ownership

* fix: preserve CommonJS file URL classification in CI fixtures

* fix: retain bound module loaders and Windows entrypoint uncertainty

* fix: retain ASAR uncertainty and invalidate changed Electron app roots

* fix(javascript): retain ownership uncertainty across loader boundaries

* fix(javascript): preserve loader sources and bound alias queries

* fix(javascript): retain destructured loader sources

* fix(javascript): preserve loader uncertainty at resolution boundaries

* fix(javascript): preserve callable and package launch ownership

* fix(javascript): preserve captured values across member reads

* test(process): assert tagged filesystem cancellation failures

* fix(javascript): preserve inventory bases and invocation read timing

* fix(javascript): preserve ownership across indirect and unread loads

* test(javascript): order fixture directory creation on Windows

* test(javascript): share ordered filesystem fixture writer

* fix(javascript): unify loader provenance and package validation

* fix(javascript): preserve captured Node require loader values

* fix(javascript): preserve loader invocation authority

* fix(javascript): verify generic loader invocation authority

* fix(javascript): preserve conditional loader method alternatives

* fix(javascript): require proven factories for source association

* fix(javascript): honor replaced Electron app path setters

* fix(javascript): prove path and assignment source ownership

* fix(javascript): retain native delegate eligibility through shared writes

* fix(process): settle stale baseline errors after confirmed absence

* fix(javascript): preserve assignment and path boundary evidence

* fix(javascript): prove source-directory resolve anchors

* fix: preserve application path provenance and portable schemas

* fix(javascript): retain CommonJS exported setter effects

* fix: isolate Linux identity observations and retain native module exports

* fix(javascript): preserve published app and helper provenance

* fix(javascript): normalize typed stores and native path fixtures
2026-10-20 17:25:19 +08:00

100 lines
3.8 KiB
TypeScript

import { packageSubpathPatternMatches } from "./javascriptPackageSubpathPatterns.js";
/**
* Exact package-private import-alias lookup. Node resolves `#` specifiers
* against the importer's enclosing package `imports` map; this module owns the
* specifier and exact-key rules. Condition, array, and null target selection
* stay with the shared package-target machinery. Wildcard keys, recursive
* `#` targets, and external-package targets remain explicit unknowns.
*/
/** How one `#` specifier participates in exact import-alias lookup. */
export type PackageImportSpecifierClassification =
| { readonly kind: "invalid" }
| { readonly kind: "pattern" }
| { readonly kind: "exact"; readonly key: string };
/** Outcome of looking up one exact `#` key in a package `imports` object. */
export type PackageImportExactLookup =
| { readonly kind: "undefined-map" }
| {
readonly kind: "missing-key";
readonly declared: readonly string[];
}
| {
readonly kind: "pattern-unresolved";
readonly declared: readonly string[];
}
| {
readonly kind: "found";
readonly target: unknown;
readonly declared: readonly string[];
};
/** How a selected string target is interpreted for package-private imports. */
export type PackageImportTargetClassification =
| { readonly kind: "relative"; readonly target: string }
| { readonly kind: "invalid"; readonly target: string }
| { readonly kind: "recursive"; readonly target: string }
| { readonly kind: "external-package"; readonly target: string };
/**
* Classify a `#` module specifier before any package-scope walk.
* `#` and names ending in `/` are invalid. Other literal keys, including
* `#/…`, participate in exact lookup; wildcard expansion remains unsupported.
*/
export const classifyPackageImportSpecifier = (
specifier: string,
): PackageImportSpecifierClassification => {
if (specifier === "#" || specifier.endsWith("/")) return { kind: "invalid" };
if (specifier.includes("*")) return { kind: "pattern" };
return { kind: "exact", key: specifier };
};
/** True when an `imports` key is a pattern rather than an exact alias. */
export const isPackageImportPatternKey = (key: string): boolean =>
key.includes("*") || key.endsWith("/");
/**
* Look up one exact `#` key in a package `imports` value.
* Only a matching wildcard keeps an exact miss unresolved. Unrelated patterns
* cannot select a target and therefore do not hide an undefined specifier.
*/
export const lookupExactPackageImport = (
imports: unknown,
key: string,
): PackageImportExactLookup => {
if (typeof imports !== "object" || imports === null || Array.isArray(imports))
return { kind: "undefined-map" };
const declared = Object.keys(imports);
if (Object.hasOwn(imports, key) && !isPackageImportPatternKey(key))
return {
kind: "found",
target: Reflect.get(imports, key),
declared,
};
return declared.some((pattern) => packageSubpathPatternMatches(pattern, key))
? { kind: "pattern-unresolved", declared }
: { kind: "missing-key", declared };
};
/**
* Classify a selected string import target. Only package-local `./` paths are
* resolved as files; recursive `#` aliases and bare packages stay unknown.
* Parent-relative, absolute, and URL targets are invalid, allowing array
* selection to skip them before choosing a package-local fallback.
*/
export const classifyPackageImportTargetString = (
target: string,
): PackageImportTargetClassification => {
if (target.startsWith("./")) return { kind: "relative", target };
if (
target.startsWith("../") ||
target.startsWith("/") ||
URL.canParse(target)
)
return { kind: "invalid", target };
if (target.startsWith("#")) return { kind: "recursive", target };
return { kind: "external-package", target };
};