@maverickcer/env-cap 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +279 -0
- package/dist/.dts/build/assemble-project.d.ts +47 -0
- package/dist/.dts/build/assemble-project.d.ts.map +1 -0
- package/dist/.dts/build/change-model.d.ts +62 -0
- package/dist/.dts/build/change-model.d.ts.map +1 -0
- package/dist/.dts/build/check-artifacts.d.ts +48 -0
- package/dist/.dts/build/check-artifacts.d.ts.map +1 -0
- package/dist/.dts/build/citation-verification.d.ts +62 -0
- package/dist/.dts/build/citation-verification.d.ts.map +1 -0
- package/dist/.dts/build/compatibility.d.ts +76 -0
- package/dist/.dts/build/compatibility.d.ts.map +1 -0
- package/dist/.dts/build/contract-model.d.ts +92 -0
- package/dist/.dts/build/contract-model.d.ts.map +1 -0
- package/dist/.dts/build/deep-equal.d.ts +9 -0
- package/dist/.dts/build/deep-equal.d.ts.map +1 -0
- package/dist/.dts/build/deep-freeze.d.ts +20 -0
- package/dist/.dts/build/deep-freeze.d.ts.map +1 -0
- package/dist/.dts/build/dependency-graph.d.ts +168 -0
- package/dist/.dts/build/dependency-graph.d.ts.map +1 -0
- package/dist/.dts/build/dependency-model.d.ts +79 -0
- package/dist/.dts/build/dependency-model.d.ts.map +1 -0
- package/dist/.dts/build/discover.d.ts +25 -0
- package/dist/.dts/build/discover.d.ts.map +1 -0
- package/dist/.dts/build/display-path.d.ts +24 -0
- package/dist/.dts/build/display-path.d.ts.map +1 -0
- package/dist/.dts/build/docs.d.ts +176 -0
- package/dist/.dts/build/docs.d.ts.map +1 -0
- package/dist/.dts/build/env-example.d.ts +85 -0
- package/dist/.dts/build/env-example.d.ts.map +1 -0
- package/dist/.dts/build/errors.d.ts +78 -0
- package/dist/.dts/build/errors.d.ts.map +1 -0
- package/dist/.dts/build/evidence-cache.d.ts +74 -0
- package/dist/.dts/build/evidence-cache.d.ts.map +1 -0
- package/dist/.dts/build/evidence-model.d.ts +50 -0
- package/dist/.dts/build/evidence-model.d.ts.map +1 -0
- package/dist/.dts/build/evidence-reference.d.ts +67 -0
- package/dist/.dts/build/evidence-reference.d.ts.map +1 -0
- package/dist/.dts/build/evidence-snapshot.d.ts +123 -0
- package/dist/.dts/build/evidence-snapshot.d.ts.map +1 -0
- package/dist/.dts/build/exclusive-group.d.ts +19 -0
- package/dist/.dts/build/exclusive-group.d.ts.map +1 -0
- package/dist/.dts/build/finding-model.d.ts +79 -0
- package/dist/.dts/build/finding-model.d.ts.map +1 -0
- package/dist/.dts/build/generate-documentation.d.ts +176 -0
- package/dist/.dts/build/generate-documentation.d.ts.map +1 -0
- package/dist/.dts/build/generate-env-artifacts.d.ts +176 -0
- package/dist/.dts/build/generate-env-artifacts.d.ts.map +1 -0
- package/dist/.dts/build/generate-evidence.d.ts +77 -0
- package/dist/.dts/build/generate-evidence.d.ts.map +1 -0
- package/dist/.dts/build/generate-manifest.d.ts +101 -0
- package/dist/.dts/build/generate-manifest.d.ts.map +1 -0
- package/dist/.dts/build/generate-usage.d.ts +95 -0
- package/dist/.dts/build/generate-usage.d.ts.map +1 -0
- package/dist/.dts/build/generated-banner.d.ts +52 -0
- package/dist/.dts/build/generated-banner.d.ts.map +1 -0
- package/dist/.dts/build/glob.d.ts +18 -0
- package/dist/.dts/build/glob.d.ts.map +1 -0
- package/dist/.dts/build/governance-fields.d.ts +34 -0
- package/dist/.dts/build/governance-fields.d.ts.map +1 -0
- package/dist/.dts/build/humanize-key.d.ts +14 -0
- package/dist/.dts/build/humanize-key.d.ts.map +1 -0
- package/dist/.dts/build/index.d.ts +107 -0
- package/dist/.dts/build/index.d.ts.map +1 -0
- package/dist/.dts/build/lifecycle-model.d.ts +64 -0
- package/dist/.dts/build/lifecycle-model.d.ts.map +1 -0
- package/dist/.dts/build/link.d.ts +215 -0
- package/dist/.dts/build/link.d.ts.map +1 -0
- package/dist/.dts/build/literal-eval.d.ts +23 -0
- package/dist/.dts/build/literal-eval.d.ts.map +1 -0
- package/dist/.dts/build/live-expirations.d.ts +47 -0
- package/dist/.dts/build/live-expirations.d.ts.map +1 -0
- package/dist/.dts/build/manifest-snapshot.d.ts +229 -0
- package/dist/.dts/build/manifest-snapshot.d.ts.map +1 -0
- package/dist/.dts/build/manifest.d.ts +31 -0
- package/dist/.dts/build/manifest.d.ts.map +1 -0
- package/dist/.dts/build/map-utils.d.ts +8 -0
- package/dist/.dts/build/map-utils.d.ts.map +1 -0
- package/dist/.dts/build/ownership-model.d.ts +57 -0
- package/dist/.dts/build/ownership-model.d.ts.map +1 -0
- package/dist/.dts/build/parse.d.ts +199 -0
- package/dist/.dts/build/parse.d.ts.map +1 -0
- package/dist/.dts/build/reference-projections.d.ts +156 -0
- package/dist/.dts/build/reference-projections.d.ts.map +1 -0
- package/dist/.dts/build/resolution/resolve-import.d.ts +53 -0
- package/dist/.dts/build/resolution/resolve-import.d.ts.map +1 -0
- package/dist/.dts/build/resolution/resolve-package-schema.d.ts +83 -0
- package/dist/.dts/build/resolution/resolve-package-schema.d.ts.map +1 -0
- package/dist/.dts/build/resolution/resolve-tsconfig-paths.d.ts +101 -0
- package/dist/.dts/build/resolution/resolve-tsconfig-paths.d.ts.map +1 -0
- package/dist/.dts/build/resolution/resolve-within-root.d.ts +35 -0
- package/dist/.dts/build/resolution/resolve-within-root.d.ts.map +1 -0
- package/dist/.dts/build/resolve-import.d.ts +50 -0
- package/dist/.dts/build/resolve-import.d.ts.map +1 -0
- package/dist/.dts/build/resolve-package-schema.d.ts +99 -0
- package/dist/.dts/build/resolve-package-schema.d.ts.map +1 -0
- package/dist/.dts/build/resolve-tsconfig-paths.d.ts +100 -0
- package/dist/.dts/build/resolve-tsconfig-paths.d.ts.map +1 -0
- package/dist/.dts/build/resolve-within-root.d.ts +35 -0
- package/dist/.dts/build/resolve-within-root.d.ts.map +1 -0
- package/dist/.dts/build/sarif.d.ts +66 -0
- package/dist/.dts/build/sarif.d.ts.map +1 -0
- package/dist/.dts/build/scan-dependencies.d.ts +47 -0
- package/dist/.dts/build/scan-dependencies.d.ts.map +1 -0
- package/dist/.dts/build/sort-by-identity.d.ts +14 -0
- package/dist/.dts/build/sort-by-identity.d.ts.map +1 -0
- package/dist/.dts/build/source-position.d.ts +69 -0
- package/dist/.dts/build/source-position.d.ts.map +1 -0
- package/dist/.dts/build/tool-version.d.ts +8 -0
- package/dist/.dts/build/tool-version.d.ts.map +1 -0
- package/dist/.dts/build/types.d.ts +53 -0
- package/dist/.dts/build/types.d.ts.map +1 -0
- package/dist/.dts/build/usage-report.d.ts +124 -0
- package/dist/.dts/build/usage-report.d.ts.map +1 -0
- package/dist/.dts/cli/filesystem.d.ts +3 -0
- package/dist/.dts/cli/filesystem.d.ts.map +1 -0
- package/dist/.dts/eslint-plugin/glob.d.ts +18 -0
- package/dist/.dts/eslint-plugin/glob.d.ts.map +1 -0
- package/dist/.dts/eslint-plugin/index.d.ts +27 -0
- package/dist/.dts/eslint-plugin/index.d.ts.map +1 -0
- package/dist/.dts/eslint-plugin/no-node-fs.d.ts +25 -0
- package/dist/.dts/eslint-plugin/no-node-fs.d.ts.map +1 -0
- package/dist/.dts/eslint-plugin/no-raw-process-env.d.ts +23 -0
- package/dist/.dts/eslint-plugin/no-raw-process-env.d.ts.map +1 -0
- package/dist/.dts/evidence/define-projection.d.ts +51 -0
- package/dist/.dts/evidence/define-projection.d.ts.map +1 -0
- package/dist/.dts/evidence/index.d.ts +23 -0
- package/dist/.dts/evidence/index.d.ts.map +1 -0
- package/dist/.dts/helpers/index.d.ts +135 -0
- package/dist/.dts/helpers/index.d.ts.map +1 -0
- package/dist/.dts/helpers/processors.d.ts +32 -0
- package/dist/.dts/helpers/processors.d.ts.map +1 -0
- package/dist/.dts/helpers/validators.d.ts +68 -0
- package/dist/.dts/helpers/validators.d.ts.map +1 -0
- package/dist/.dts/node/index.d.ts +2 -0
- package/dist/.dts/node/index.d.ts.map +1 -0
- package/dist/.dts/runtime/cache.d.ts +20 -0
- package/dist/.dts/runtime/cache.d.ts.map +1 -0
- package/dist/.dts/runtime/create.d.ts +20 -0
- package/dist/.dts/runtime/create.d.ts.map +1 -0
- package/dist/.dts/runtime/document.d.ts +181 -0
- package/dist/.dts/runtime/document.d.ts.map +1 -0
- package/dist/.dts/runtime/errors.d.ts +55 -0
- package/dist/.dts/runtime/errors.d.ts.map +1 -0
- package/dist/.dts/runtime/index.d.ts +24 -0
- package/dist/.dts/runtime/index.d.ts.map +1 -0
- package/dist/.dts/runtime/registry.d.ts +12 -0
- package/dist/.dts/runtime/registry.d.ts.map +1 -0
- package/dist/.dts/runtime/reset.d.ts +8 -0
- package/dist/.dts/runtime/reset.d.ts.map +1 -0
- package/dist/.dts/runtime/types.d.ts +175 -0
- package/dist/.dts/runtime/types.d.ts.map +1 -0
- package/dist/.dts/runtime/validate.d.ts +14 -0
- package/dist/.dts/runtime/validate.d.ts.map +1 -0
- package/dist/build.cjs +83 -0
- package/dist/build.cjs.map +1 -0
- package/dist/build.d.cts +1 -0
- package/dist/build.d.ts +1 -0
- package/dist/build.js +19 -0
- package/dist/build.js.map +1 -0
- package/dist/cli/index.js +134 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/eslint-plugin/index.cjs +12 -0
- package/dist/eslint-plugin/index.cjs.map +1 -0
- package/dist/eslint-plugin/index.d.cts +1 -0
- package/dist/eslint-plugin/index.d.ts +1 -0
- package/dist/eslint-plugin/index.js +5 -0
- package/dist/eslint-plugin/index.js.map +1 -0
- package/dist/evidence.cjs +7 -0
- package/dist/evidence.cjs.map +1 -0
- package/dist/evidence.d.cts +1 -0
- package/dist/evidence.d.ts +1 -0
- package/dist/evidence.js +5 -0
- package/dist/evidence.js.map +1 -0
- package/dist/helpers.cjs +8 -0
- package/dist/helpers.cjs.map +1 -0
- package/dist/helpers.d.cts +1 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +5 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.cjs +15 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/node.cjs +13 -0
- package/dist/node.cjs.map +1 -0
- package/dist/node.d.cts +1 -0
- package/dist/node.d.ts +1 -0
- package/dist/node.js +7 -0
- package/dist/node.js.map +1 -0
- package/package.json +183 -0
- package/schemas/contract-model.schema.json +321 -0
- package/schemas/env-cap-report.schema.json +2369 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import type { ParseWarning } from "../parse.js";
|
|
3
|
+
import type { BuildFileSystem } from "../types.js";
|
|
4
|
+
/**
|
|
5
|
+
* TypeScript path-alias resolution (ADR 0023, Experimental -- see VERSIONING.md).
|
|
6
|
+
*
|
|
7
|
+
* Resolves a bare import specifier (`"@/lib/env.schema.js"`) against a project's own
|
|
8
|
+
* `tsconfig.json` `compilerOptions.paths`/`baseUrl`, so a schema or consumer reached only
|
|
9
|
+
* through an alias isn't misreported by `link.ts`/`dependency-graph.ts` as unresolved or
|
|
10
|
+
* abandoned. Unlike `resolve-package-schema.ts` (ADR 0014), this never crosses a
|
|
11
|
+
* trust/versioning boundary -- every resolved file is already local, already-trusted
|
|
12
|
+
* project source -- so it is on by default (auto-detecting `root/tsconfig.json`) rather
|
|
13
|
+
* than requiring an explicit allowlist.
|
|
14
|
+
*
|
|
15
|
+
* The actual `paths`/`baseUrl` matching algorithm (longest-prefix matching, `*` wildcard
|
|
16
|
+
* substitution, multiple fallback targets, `extends`-chain merging, JSONC parsing) is
|
|
17
|
+
* delegated entirely to the TypeScript compiler via `ts.resolveModuleName()` and
|
|
18
|
+
* `ts.parseJsonConfigFileContent()` -- the same functions `tsc`/`tsserver` themselves use --
|
|
19
|
+
* rather than reimplemented here. This module's own logic is limited to loading the config,
|
|
20
|
+
* caching resolutions, and enforcing the `node_modules` safety boundary below.
|
|
21
|
+
*/
|
|
22
|
+
/** Parsed `tsconfig.json` `paths`/`baseUrl` configuration, immutable for the life of one generate*() run. See {@link loadTsconfigPaths}. */
|
|
23
|
+
export interface TsconfigPathsResolution {
|
|
24
|
+
/** The subset of `compilerOptions` `ts.resolveModuleName()` needs -- at minimum `paths` and/or `baseUrl`. */
|
|
25
|
+
readonly compilerOptions: ts.CompilerOptions;
|
|
26
|
+
/** Absolute path of the tsconfig.json this was loaded from, for diagnostics. */
|
|
27
|
+
readonly configFile: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Opaque memoization for {@link resolveAliasImport}, created once per generate*() run via
|
|
31
|
+
* {@link createAliasResolutionCache} and threaded through `ImportResolutionContext`. Kept
|
|
32
|
+
* distinct from `TsconfigPathsResolution` (immutable config) so the cache's internal
|
|
33
|
+
* representation stays free to change without touching that type's shape.
|
|
34
|
+
*/
|
|
35
|
+
export interface AliasResolutionCache {
|
|
36
|
+
/**
|
|
37
|
+
* Keyed by `` `${importingFile}\0${specifier}` ``, not by `specifier` alone. With one
|
|
38
|
+
* fixed `compilerOptions` object and no project-reference support, `paths`-pattern
|
|
39
|
+
* substitution itself doesn't depend on the importing file -- but `ts.resolveModuleName()`'s
|
|
40
|
+
* fallback behavior when `paths` doesn't match a real file (classic-mode ancestor search,
|
|
41
|
+
* extension-preference edge cases) legitimately can. A `Map`, not a network call, so
|
|
42
|
+
* keying defensively by both costs nothing.
|
|
43
|
+
*/
|
|
44
|
+
readonly resolutions: Map<string, string | undefined>;
|
|
45
|
+
}
|
|
46
|
+
/** Creates a fresh, empty {@link AliasResolutionCache} for one generate*()/computeArtifacts() run. */
|
|
47
|
+
export declare function createAliasResolutionCache(): AliasResolutionCache;
|
|
48
|
+
export interface LoadTsconfigPathsResult {
|
|
49
|
+
readonly resolution: TsconfigPathsResolution | undefined;
|
|
50
|
+
readonly warning: ParseWarning | undefined;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Loads and parses a `tsconfig.json` for alias resolution. Called exactly once per
|
|
54
|
+
* `generate*()`/`computeArtifacts()` invocation, at the same point
|
|
55
|
+
* `resolveAllowlistedPackages()` is already called once -- so at most one tsconfig-related
|
|
56
|
+
* warning is ever produced per run, never once per file scanned.
|
|
57
|
+
*
|
|
58
|
+
* @remarks
|
|
59
|
+
* `tsconfigOption === false` disables alias resolution entirely.
|
|
60
|
+
* `tsconfigOption === undefined` (the default) looks for `root/tsconfig.json` exactly --
|
|
61
|
+
* deliberately not `ts.findConfigFile()`'s upward directory walk, since every other
|
|
62
|
+
* root-relative mechanism in this codebase (schema discovery, `packages` resolution)
|
|
63
|
+
* treats `root` as a hard boundary. A missing default tsconfig is silent (most projects
|
|
64
|
+
* don't use aliases); a missing *explicit* `tsconfigOption` is a real misconfiguration and
|
|
65
|
+
* warns. `jsconfig.json` is intentionally not auto-detected -- pass `tsconfig:
|
|
66
|
+
* "jsconfig.json"` explicitly if needed; this loader only cares about the file's JSON
|
|
67
|
+
* shape, not its name.
|
|
68
|
+
*
|
|
69
|
+
* The gate for building a resolution is "`paths` non-empty OR `baseUrl` set", not `paths`
|
|
70
|
+
* alone -- a `baseUrl`-only tsconfig (no `paths` at all) still makes TypeScript resolve
|
|
71
|
+
* bare specifiers relative to `baseUrl`, and `ts.resolveModuleName()` already handles that
|
|
72
|
+
* once `compilerOptions.baseUrl` is passed through.
|
|
73
|
+
*/
|
|
74
|
+
export declare function loadTsconfigPaths(root: string, tsconfigOption: string | false | undefined, fs: BuildFileSystem): Promise<LoadTsconfigPathsResult>;
|
|
75
|
+
/**
|
|
76
|
+
* Resolves one bare import specifier against a project's `tsconfig.json` `paths`/`baseUrl`,
|
|
77
|
+
* or returns `undefined` if it doesn't resolve through this mechanism.
|
|
78
|
+
*
|
|
79
|
+
* @remarks
|
|
80
|
+
* Necessarily synchronous -- `ts.resolveModuleName()` has no async form, matching how
|
|
81
|
+
* `tsc`/`tsserver` themselves always call it. `ts.sys` is used directly as the resolution
|
|
82
|
+
* host (an existing Node-backed singleton the `typescript` package exports; nothing to
|
|
83
|
+
* construct).
|
|
84
|
+
*
|
|
85
|
+
* Two safety/scope filters apply to any candidate `ts.resolveModuleName()` returns,
|
|
86
|
+
* independent of its own internal fallback behavior:
|
|
87
|
+
* - **Never resolves into `node_modules`.** `ts.resolveModuleName()` can, in principle,
|
|
88
|
+
* fall through to classic Node resolution and land inside `node_modules`; any resolved
|
|
89
|
+
* path containing a `node_modules` path segment (checked after `path.normalize()`, so
|
|
90
|
+
* mixed separators can't slip past it on Windows) is discarded here. Bare package
|
|
91
|
+
* specifiers continue to be handled exclusively by `resolvePackageImport()`
|
|
92
|
+
* (ADR 0014) -- this mechanism never overlaps with that trust boundary.
|
|
93
|
+
* - **`.ts`/`.tsx` only.** Matches `resolveRelativeImport()`'s own existing candidate set
|
|
94
|
+
* and `resolve-package-schema.ts`'s `SCHEMA_FILE_EXTENSIONS` -- this codebase's static-
|
|
95
|
+
* analysis pipeline is `.ts`/`.tsx` only today. A resolved non-`.ts`/`.tsx` file is a
|
|
96
|
+
* real risk, not just a gap: feeding it straight into `ts.createSourceFile()` wouldn't
|
|
97
|
+
* error, it would silently parse garbage -- exactly the "guess" this codebase's
|
|
98
|
+
* warn-don't-guess philosophy exists to avoid.
|
|
99
|
+
*/
|
|
100
|
+
export declare function resolveAliasImport(specifier: string, importingFile: string, resolution: TsconfigPathsResolution, cache: AliasResolutionCache): string | undefined;
|
|
101
|
+
//# sourceMappingURL=resolve-tsconfig-paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-tsconfig-paths.d.ts","sourceRoot":"","sources":["../../../../src/build/resolution/resolve-tsconfig-paths.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,YAAY,CAAA;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD;;;;;;;;;;;;;;;;;GAiBG;AAEH,4IAA4I;AAC5I,MAAM,WAAW,uBAAuB;IACtC,6GAA6G;IAC7G,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,eAAe,CAAA;IAC5C,gFAAgF;IAChF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CACtD;AAED,sGAAsG;AACtG,wBAAgB,0BAA0B,IAAI,oBAAoB,CAEjE;AAcD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,EAAE,uBAAuB,GAAG,SAAS,CAAA;IACxD,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,CAAA;CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,EAC1C,EAAE,EAAE,eAAe,GAClB,OAAO,CAAC,uBAAuB,CAAC,CA4ClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,uBAAuB,EACnC,KAAK,EAAE,oBAAoB,GAC1B,MAAM,GAAG,SAAS,CAiBpB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { CompatibilityIssue } from "../compatibility.js";
|
|
2
|
+
export type ResolveWithinRootResult = {
|
|
3
|
+
readonly ok: true;
|
|
4
|
+
readonly resolved: string;
|
|
5
|
+
} | {
|
|
6
|
+
readonly ok: false;
|
|
7
|
+
readonly issue: CompatibilityIssue;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Plain lexical bounds-check: is `targetPath` inside `baseDir`? Shared by
|
|
11
|
+
* `resolveWithinRoot()` below (output paths, checked lexically since they
|
|
12
|
+
* usually don't exist on disk yet) and `resolve-package-schema.ts` (which
|
|
13
|
+
* additionally re-checks this against `fs.realpath`-resolved paths, since a
|
|
14
|
+
* package-declared schema path both exists on disk and crosses a real trust
|
|
15
|
+
* boundary -- see ADR 0014). Boundary-agnostic on purpose: neither caller's
|
|
16
|
+
* notion of "root" is baked in here.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isWithinDirectory(baseDir: string, targetPath: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Resolves `location` against `root` and checks the result doesn't escape it
|
|
21
|
+
* (e.g. `location: "../../malicious.ts"`, or an absolute path on another
|
|
22
|
+
* branch of the filesystem entirely). Discovery (`include`/`exclude`) is
|
|
23
|
+
* already safe by construction -- it only ever walks *down* from `root` via
|
|
24
|
+
* `readdir`, so a pattern can't make it read outside `root`. Output
|
|
25
|
+
* locations have no such structural guarantee, since `path.resolve` happily
|
|
26
|
+
* walks back out via `..` segments, so this is a plain lexical bounds-check
|
|
27
|
+
* (not a symlink-aware `realpath` check -- these are *output* paths that
|
|
28
|
+
* usually don't exist yet).
|
|
29
|
+
*
|
|
30
|
+
* Never throws itself -- returns a `CompatibilityIssue`-shaped finding on
|
|
31
|
+
* escape so each generator function (`generateEnvManifest`, `generateDocumentation`,
|
|
32
|
+
* `generateUsageReport`, `generateEnvArtifacts`) can wrap it in its own error type.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveWithinRoot(root: string, location: string, optionName: string, functionName: string): ResolveWithinRootResult;
|
|
35
|
+
//# sourceMappingURL=resolve-within-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-within-root.d.ts","sourceRoot":"","sources":["../../../../src/build/resolution/resolve-within-root.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAE7D,MAAM,MAAM,uBAAuB,GAC/B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAA;CAAE,CAAA;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAG9E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,uBAAuB,CAgBzB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { type PackageSchemaResolutionResult } from "./resolve-package-schema.js";
|
|
2
|
+
import { type AliasResolutionCache, type TsconfigPathsResolution } from "./resolve-tsconfig-paths.js";
|
|
3
|
+
/**
|
|
4
|
+
* Resolves a relative import specifier (as written in source: `"./schema.js"`,
|
|
5
|
+
* matching this codebase's own convention of `.js`-suffixed relative imports
|
|
6
|
+
* pointing at `.ts` source files) to an absolute file path, relative to the
|
|
7
|
+
* file that contains the import.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Deliberately narrow: only handles a direct relative specifier resolving to
|
|
11
|
+
* a real `.ts`/`.tsx` file on disk. Bare/package specifiers, namespace
|
|
12
|
+
* imports, and anything requiring real module resolution (re-export chains,
|
|
13
|
+
* `exports` map lookups, etc.) return `undefined` -- the caller treats that
|
|
14
|
+
* as "couldn't statically link" and warns rather than guesses, the same
|
|
15
|
+
* philosophy `evaluateLiteral` already uses for non-literal expressions.
|
|
16
|
+
*
|
|
17
|
+
* @returns The resolved absolute path, or `undefined` when the specifier isn't relative or doesn't resolve to a real file.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveRelativeImport(importingFile: string, specifier: string): Promise<string | undefined>;
|
|
20
|
+
/** Shared inputs threaded through every call to {@link resolveImportSpecifier} for one discovery/link run. */
|
|
21
|
+
export interface ImportResolutionContext {
|
|
22
|
+
/** Absolute path of the project root, used to resolve package specifiers. */
|
|
23
|
+
readonly root: string;
|
|
24
|
+
/** Explicit allowlist -- see ADR 0014. Empty/omitted means package resolution never fires, identical to today's behavior. */
|
|
25
|
+
readonly packages: readonly string[];
|
|
26
|
+
/** Memoizes package resolution per specifier across the whole run -- see `resolvePackageImport`'s own doc comment for why. */
|
|
27
|
+
readonly cache: Map<string, Promise<PackageSchemaResolutionResult>>;
|
|
28
|
+
/** Parsed `tsconfig.json` `paths`/`baseUrl`, or `undefined` when alias resolution found nothing to do or was disabled -- see ADR 0023. */
|
|
29
|
+
readonly tsconfigPaths: TsconfigPathsResolution | undefined;
|
|
30
|
+
/** Memoizes alias resolution across the whole run -- see `resolveAliasImport`'s own doc comment for why. Always allocated, even when `tsconfigPaths` is `undefined`, mirroring `cache` above. */
|
|
31
|
+
readonly aliasCache: AliasResolutionCache;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The one specifier-resolution entry point `link.ts` and `dependency-graph.ts`
|
|
35
|
+
* call, instead of each duplicating a
|
|
36
|
+
* `(await resolveRelativeImport(...)) ?? resolveAliasImport(...) ?? (await resolvePackageImport(...))`
|
|
37
|
+
* chain at every call site.
|
|
38
|
+
*
|
|
39
|
+
* @remarks
|
|
40
|
+
* Purely a composition point -- no new resolution logic lives here. Tries, in order: the
|
|
41
|
+
* relative resolver (cheap, no `fs.stat` beyond the local filesystem check it already
|
|
42
|
+
* does); tsconfig path-alias resolution (ADR 0023, on by default) for a bare specifier
|
|
43
|
+
* matching the project's own `tsconfig.json` `paths`/`baseUrl`; then package resolution
|
|
44
|
+
* (ADR 0014) for a bare specifier matching an allow-listed package name. Alias resolution
|
|
45
|
+
* runs before package resolution because it resolves the consuming project's own local
|
|
46
|
+
* source (already-trusted, no versioning boundary), the same precedence relative
|
|
47
|
+
* resolution already has over package resolution.
|
|
48
|
+
*/
|
|
49
|
+
export declare function resolveImportSpecifier(importingFile: string, specifier: string, context: ImportResolutionContext): Promise<string | undefined>;
|
|
50
|
+
//# sourceMappingURL=resolve-import.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-import.d.ts","sourceRoot":"","sources":["../../../src/build/resolve-import.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,6BAA6B,EACnC,MAAM,6BAA6B,CAAA;AACpC,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC7B,MAAM,6BAA6B,CAAA;AAEpC;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAe7B;AAWD,8GAA8G;AAC9G,MAAM,WAAW,uBAAuB;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,6HAA6H;IAC7H,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,8HAA8H;IAC9H,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,6BAA6B,CAAC,CAAC,CAAA;IACnE,0IAA0I;IAC1I,QAAQ,CAAC,aAAa,EAAE,uBAAuB,GAAG,SAAS,CAAA;IAC3D,iMAAiM;IACjM,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAA;CAC1C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAe7B"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { ParseWarning } from "./parse.js";
|
|
2
|
+
/**
|
|
3
|
+
* Cross-package schema discovery (ADR 0014, Experimental -- see VERSIONING.md).
|
|
4
|
+
*
|
|
5
|
+
* Resolves an explicitly allow-listed installed package name to the one
|
|
6
|
+
* schema file it declares via its own `"envCap": { "schema": "<path>" }`
|
|
7
|
+
* package.json field. Every step here is `createRequire(...).resolve(...)`,
|
|
8
|
+
* `fs.stat`/`fs.realpath`/`fs.readFile` on a path already fully known --
|
|
9
|
+
* never a `readdir` walk of any directory, named package or not. This is a
|
|
10
|
+
* completely separate code path from `discover.ts`'s `discoverSchemaFiles()`,
|
|
11
|
+
* which continues to unconditionally prune `node_modules` during its own
|
|
12
|
+
* walk exactly as before; the two never overlap.
|
|
13
|
+
*
|
|
14
|
+
* This module only ever locates a file. It never imports, requires, or
|
|
15
|
+
* executes it -- a package-resolved file is fed into the exact same
|
|
16
|
+
* `parseSchemaFile()`/AST-only pipeline as a locally-discovered file,
|
|
17
|
+
* indistinguishable from it after resolution. See ADR 0002 and ADR 0014.
|
|
18
|
+
*/
|
|
19
|
+
export declare const SCHEMA_FILE_EXTENSIONS: readonly [".ts", ".tsx"];
|
|
20
|
+
/** 1 MiB. New hardening specific to this trust tier -- a package crosses a
|
|
21
|
+
* real versioning/trust boundary that locally-discovered source doesn't,
|
|
22
|
+
* so this caps the cost of parsing an oversized or adversarial file before
|
|
23
|
+
* any of its content is even read into memory. See ADR 0014. */
|
|
24
|
+
export declare const MAX_PACKAGE_SCHEMA_FILE_BYTES = 1048576;
|
|
25
|
+
export type PackageResolutionFailureCode = "PACKAGE_NOT_FOUND" | "MALFORMED_PACKAGE_JSON" | "FIELD_MISSING" | "INVALID_EXTENSION" | "OUTSIDE_PACKAGE" | "FILE_TOO_LARGE";
|
|
26
|
+
/** Both the authored and resolved forms are kept -- diagnostics benefit from
|
|
27
|
+
* showing exactly what a package author wrote versus what it resolved to. */
|
|
28
|
+
export interface PackageOrigin {
|
|
29
|
+
/** The allow-listed package name that declared this schema. */
|
|
30
|
+
readonly packageName: string;
|
|
31
|
+
/** The `"envCap.schema"` value exactly as the package author wrote it. */
|
|
32
|
+
readonly declaredField: string;
|
|
33
|
+
/** Absolute, realpath-canonicalized path to the resolved schema file. */
|
|
34
|
+
readonly resolvedFile: string;
|
|
35
|
+
/** Absolute, realpath-canonicalized path to the package's own directory. */
|
|
36
|
+
readonly packageDir: string;
|
|
37
|
+
}
|
|
38
|
+
export type PackageSchemaResolutionResult = {
|
|
39
|
+
readonly ok: true;
|
|
40
|
+
readonly origin: PackageOrigin;
|
|
41
|
+
} | {
|
|
42
|
+
readonly ok: false;
|
|
43
|
+
readonly code: PackageResolutionFailureCode;
|
|
44
|
+
readonly reason: string;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Resolves one allow-listed package name. Memoized in a caller-owned
|
|
48
|
+
* `cache` (one per `generate*()` invocation, shared with linking/dependency-
|
|
49
|
+
* graph resolution) so a name referenced from multiple places -- multiple
|
|
50
|
+
* scanned files bare-importing the same package, or a duplicate entry in
|
|
51
|
+
* `packages` -- is only ever resolved once. The cache is populated with the
|
|
52
|
+
* in-flight promise before it settles, so concurrent callers await the same
|
|
53
|
+
* resolution rather than racing duplicate work.
|
|
54
|
+
*/
|
|
55
|
+
export declare function resolvePackageSchemaFile(packageName: string, root: string, cache: Map<string, Promise<PackageSchemaResolutionResult>>): Promise<PackageSchemaResolutionResult>;
|
|
56
|
+
export interface ResolvedPackageFile {
|
|
57
|
+
readonly packageName: string;
|
|
58
|
+
readonly file: string;
|
|
59
|
+
}
|
|
60
|
+
export interface ResolvePackagesResult {
|
|
61
|
+
readonly files: readonly ResolvedPackageFile[];
|
|
62
|
+
/** Keyed by resolved file path, for `DiscoveredContract.packageOrigin` lookups downstream. */
|
|
63
|
+
readonly origins: ReadonlyMap<string, PackageOrigin>;
|
|
64
|
+
readonly warnings: readonly ParseWarning[];
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Resolves every allow-listed package name. Input is deduplicated first, so
|
|
68
|
+
* a duplicate entry in `packages` (accidental or defensive) produces exactly
|
|
69
|
+
* one resolution attempt and, on failure, exactly one warning -- never two.
|
|
70
|
+
* Never throws: every failure becomes one `ParseWarning`, consistent with
|
|
71
|
+
* every other static-analysis boundary in this codebase.
|
|
72
|
+
*/
|
|
73
|
+
export declare function resolveAllowlistedPackages(packages: readonly string[], root: string, cache: Map<string, Promise<PackageSchemaResolutionResult>>): Promise<ResolvePackagesResult>;
|
|
74
|
+
/**
|
|
75
|
+
* Combines local schema-discovery hits with package-resolved files into one
|
|
76
|
+
* deduplicated list, keyed by realpath rather than lexical absolute path --
|
|
77
|
+
* package-resolved files are already realpath-canonicalized (see
|
|
78
|
+
* `resolveUncached` above), but local `discoverSchemaFiles()` hits are plain
|
|
79
|
+
* `readdir`-derived absolute paths that may themselves traverse a symlink (a
|
|
80
|
+
* symlinked `root`, or an included path reached through one). Deduplicating
|
|
81
|
+
* on the lexical path alone would miss the case where the same physical file
|
|
82
|
+
* is reached twice through two different symlinked routes -- one via local
|
|
83
|
+
* glob discovery, one via package resolution -- and silently double-count it
|
|
84
|
+
* into two identical contracts, including the more mundane case of a package
|
|
85
|
+
* that's both locally glob-reachable (e.g. during a monorepo migration) and
|
|
86
|
+
* explicitly allow-listed. On a collision, the local path string identity
|
|
87
|
+
* wins (the package-resolved duplicate is dropped).
|
|
88
|
+
*/
|
|
89
|
+
export declare function mergeLocalAndPackageFiles(localFiles: readonly string[], packageFiles: readonly string[]): Promise<string[]>;
|
|
90
|
+
/**
|
|
91
|
+
* Bare-specifier-to-allowlist matching, used by `resolve-import.ts`'s
|
|
92
|
+
* `resolveImportSpecifier()` as its package-resolution fallback. Only ever
|
|
93
|
+
* attempts resolution for a specifier that is (or is a subpath of) an
|
|
94
|
+
* allow-listed package name -- any other bare specifier is not this
|
|
95
|
+
* mechanism's concern and returns `undefined` immediately, identical to
|
|
96
|
+
* `resolveRelativeImport()`'s existing bare-specifier no-op.
|
|
97
|
+
*/
|
|
98
|
+
export declare function resolvePackageImport(specifier: string, allowedPackages: readonly string[], root: string, cache: Map<string, Promise<PackageSchemaResolutionResult>>): Promise<string | undefined>;
|
|
99
|
+
//# sourceMappingURL=resolve-package-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-package-schema.d.ts","sourceRoot":"","sources":["../../../src/build/resolve-package-schema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAG9C;;;;;;;;;;;;;;;;GAgBG;AAEH,eAAO,MAAM,sBAAsB,0BAA2B,CAAA;AAE9D;;;iEAGiE;AACjE,eAAO,MAAM,6BAA6B,UAAY,CAAA;AAItD,MAAM,MAAM,4BAA4B,GACpC,mBAAmB,GACnB,wBAAwB,GACxB,eAAe,GACf,mBAAmB,GACnB,iBAAiB,GACjB,gBAAgB,CAAA;AAEpB;8EAC8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,0EAA0E;IAC1E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,yEAAyE;IACzE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,MAAM,6BAA6B,GACrC;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AA0LhG;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,6BAA6B,CAAC,CAAC,GACzD,OAAO,CAAC,6BAA6B,CAAC,CAOxC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,mBAAmB,EAAE,CAAA;IAC9C,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IACpD,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAA;CAC3C;AAED;;;;;;GAMG;AACH,wBAAsB,0BAA0B,CAC9C,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,6BAA6B,CAAC,CAAC,GACzD,OAAO,CAAC,qBAAqB,CAAC,CAuBhC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,YAAY,EAAE,SAAS,MAAM,EAAE,GAC9B,OAAO,CAAC,MAAM,EAAE,CAAC,CAuBnB;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,SAAS,MAAM,EAAE,EAClC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,6BAA6B,CAAC,CAAC,GACzD,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAO7B"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import type { ParseWarning } from "./parse.js";
|
|
3
|
+
/**
|
|
4
|
+
* TypeScript path-alias resolution (ADR 0023, Experimental -- see VERSIONING.md).
|
|
5
|
+
*
|
|
6
|
+
* Resolves a bare import specifier (`"@/lib/env.schema.js"`) against a project's own
|
|
7
|
+
* `tsconfig.json` `compilerOptions.paths`/`baseUrl`, so a schema or consumer reached only
|
|
8
|
+
* through an alias isn't misreported by `link.ts`/`dependency-graph.ts` as unresolved or
|
|
9
|
+
* abandoned. Unlike `resolve-package-schema.ts` (ADR 0014), this never crosses a
|
|
10
|
+
* trust/versioning boundary -- every resolved file is already local, already-trusted
|
|
11
|
+
* project source -- so it is on by default (auto-detecting `root/tsconfig.json`) rather
|
|
12
|
+
* than requiring an explicit allowlist.
|
|
13
|
+
*
|
|
14
|
+
* The actual `paths`/`baseUrl` matching algorithm (longest-prefix matching, `*` wildcard
|
|
15
|
+
* substitution, multiple fallback targets, `extends`-chain merging, JSONC parsing) is
|
|
16
|
+
* delegated entirely to the TypeScript compiler via `ts.resolveModuleName()` and
|
|
17
|
+
* `ts.parseJsonConfigFileContent()` -- the same functions `tsc`/`tsserver` themselves use --
|
|
18
|
+
* rather than reimplemented here. This module's own logic is limited to loading the config,
|
|
19
|
+
* caching resolutions, and enforcing the `node_modules` safety boundary below.
|
|
20
|
+
*/
|
|
21
|
+
/** Parsed `tsconfig.json` `paths`/`baseUrl` configuration, immutable for the life of one generate*() run. See {@link loadTsconfigPaths}. */
|
|
22
|
+
export interface TsconfigPathsResolution {
|
|
23
|
+
/** The subset of `compilerOptions` `ts.resolveModuleName()` needs -- at minimum `paths` and/or `baseUrl`. */
|
|
24
|
+
readonly compilerOptions: ts.CompilerOptions;
|
|
25
|
+
/** Absolute path of the tsconfig.json this was loaded from, for diagnostics. */
|
|
26
|
+
readonly configFile: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Opaque memoization for {@link resolveAliasImport}, created once per generate*() run via
|
|
30
|
+
* {@link createAliasResolutionCache} and threaded through `ImportResolutionContext`. Kept
|
|
31
|
+
* distinct from `TsconfigPathsResolution` (immutable config) so the cache's internal
|
|
32
|
+
* representation stays free to change without touching that type's shape.
|
|
33
|
+
*/
|
|
34
|
+
export interface AliasResolutionCache {
|
|
35
|
+
/**
|
|
36
|
+
* Keyed by `` `${importingFile}\0${specifier}` ``, not by `specifier` alone. With one
|
|
37
|
+
* fixed `compilerOptions` object and no project-reference support, `paths`-pattern
|
|
38
|
+
* substitution itself doesn't depend on the importing file -- but `ts.resolveModuleName()`'s
|
|
39
|
+
* fallback behavior when `paths` doesn't match a real file (classic-mode ancestor search,
|
|
40
|
+
* extension-preference edge cases) legitimately can. A `Map`, not a network call, so
|
|
41
|
+
* keying defensively by both costs nothing.
|
|
42
|
+
*/
|
|
43
|
+
readonly resolutions: Map<string, string | undefined>;
|
|
44
|
+
}
|
|
45
|
+
/** Creates a fresh, empty {@link AliasResolutionCache} for one generate*()/computeArtifacts() run. */
|
|
46
|
+
export declare function createAliasResolutionCache(): AliasResolutionCache;
|
|
47
|
+
export interface LoadTsconfigPathsResult {
|
|
48
|
+
readonly resolution: TsconfigPathsResolution | undefined;
|
|
49
|
+
readonly warning: ParseWarning | undefined;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Loads and parses a `tsconfig.json` for alias resolution. Called exactly once per
|
|
53
|
+
* `generate*()`/`computeArtifacts()` invocation, at the same point
|
|
54
|
+
* `resolveAllowlistedPackages()` is already called once -- so at most one tsconfig-related
|
|
55
|
+
* warning is ever produced per run, never once per file scanned.
|
|
56
|
+
*
|
|
57
|
+
* @remarks
|
|
58
|
+
* `tsconfigOption === false` disables alias resolution entirely.
|
|
59
|
+
* `tsconfigOption === undefined` (the default) looks for `root/tsconfig.json` exactly --
|
|
60
|
+
* deliberately not `ts.findConfigFile()`'s upward directory walk, since every other
|
|
61
|
+
* root-relative mechanism in this codebase (schema discovery, `packages` resolution)
|
|
62
|
+
* treats `root` as a hard boundary. A missing default tsconfig is silent (most projects
|
|
63
|
+
* don't use aliases); a missing *explicit* `tsconfigOption` is a real misconfiguration and
|
|
64
|
+
* warns. `jsconfig.json` is intentionally not auto-detected -- pass `tsconfig:
|
|
65
|
+
* "jsconfig.json"` explicitly if needed; this loader only cares about the file's JSON
|
|
66
|
+
* shape, not its name.
|
|
67
|
+
*
|
|
68
|
+
* The gate for building a resolution is "`paths` non-empty OR `baseUrl` set", not `paths`
|
|
69
|
+
* alone -- a `baseUrl`-only tsconfig (no `paths` at all) still makes TypeScript resolve
|
|
70
|
+
* bare specifiers relative to `baseUrl`, and `ts.resolveModuleName()` already handles that
|
|
71
|
+
* once `compilerOptions.baseUrl` is passed through.
|
|
72
|
+
*/
|
|
73
|
+
export declare function loadTsconfigPaths(root: string, tsconfigOption: string | false | undefined): Promise<LoadTsconfigPathsResult>;
|
|
74
|
+
/**
|
|
75
|
+
* Resolves one bare import specifier against a project's `tsconfig.json` `paths`/`baseUrl`,
|
|
76
|
+
* or returns `undefined` if it doesn't resolve through this mechanism.
|
|
77
|
+
*
|
|
78
|
+
* @remarks
|
|
79
|
+
* Necessarily synchronous -- `ts.resolveModuleName()` has no async form, matching how
|
|
80
|
+
* `tsc`/`tsserver` themselves always call it. `ts.sys` is used directly as the resolution
|
|
81
|
+
* host (an existing Node-backed singleton the `typescript` package exports; nothing to
|
|
82
|
+
* construct).
|
|
83
|
+
*
|
|
84
|
+
* Two safety/scope filters apply to any candidate `ts.resolveModuleName()` returns,
|
|
85
|
+
* independent of its own internal fallback behavior:
|
|
86
|
+
* - **Never resolves into `node_modules`.** `ts.resolveModuleName()` can, in principle,
|
|
87
|
+
* fall through to classic Node resolution and land inside `node_modules`; any resolved
|
|
88
|
+
* path containing a `node_modules` path segment (checked after `path.normalize()`, so
|
|
89
|
+
* mixed separators can't slip past it on Windows) is discarded here. Bare package
|
|
90
|
+
* specifiers continue to be handled exclusively by `resolvePackageImport()`
|
|
91
|
+
* (ADR 0014) -- this mechanism never overlaps with that trust boundary.
|
|
92
|
+
* - **`.ts`/`.tsx` only.** Matches `resolveRelativeImport()`'s own existing candidate set
|
|
93
|
+
* and `resolve-package-schema.ts`'s `SCHEMA_FILE_EXTENSIONS` -- this codebase's static-
|
|
94
|
+
* analysis pipeline is `.ts`/`.tsx` only today. A resolved non-`.ts`/`.tsx` file is a
|
|
95
|
+
* real risk, not just a gap: feeding it straight into `ts.createSourceFile()` wouldn't
|
|
96
|
+
* error, it would silently parse garbage -- exactly the "guess" this codebase's
|
|
97
|
+
* warn-don't-guess philosophy exists to avoid.
|
|
98
|
+
*/
|
|
99
|
+
export declare function resolveAliasImport(specifier: string, importingFile: string, resolution: TsconfigPathsResolution, cache: AliasResolutionCache): string | undefined;
|
|
100
|
+
//# sourceMappingURL=resolve-tsconfig-paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-tsconfig-paths.d.ts","sourceRoot":"","sources":["../../../src/build/resolve-tsconfig-paths.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,YAAY,CAAA;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C;;;;;;;;;;;;;;;;;GAiBG;AAEH,4IAA4I;AAC5I,MAAM,WAAW,uBAAuB;IACtC,6GAA6G;IAC7G,QAAQ,CAAC,eAAe,EAAE,EAAE,CAAC,eAAe,CAAA;IAC5C,gFAAgF;IAChF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;;;;;OAOG;IACH,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;CACtD;AAED,sGAAsG;AACtG,wBAAgB,0BAA0B,IAAI,oBAAoB,CAEjE;AAWD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,UAAU,EAAE,uBAAuB,GAAG,SAAS,CAAA;IACxD,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,CAAA;CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,GACzC,OAAO,CAAC,uBAAuB,CAAC,CAqClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,uBAAuB,EACnC,KAAK,EAAE,oBAAoB,GAC1B,MAAM,GAAG,SAAS,CAiBpB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { CompatibilityIssue } from "./compatibility.js";
|
|
2
|
+
export type ResolveWithinRootResult = {
|
|
3
|
+
readonly ok: true;
|
|
4
|
+
readonly resolved: string;
|
|
5
|
+
} | {
|
|
6
|
+
readonly ok: false;
|
|
7
|
+
readonly issue: CompatibilityIssue;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Plain lexical bounds-check: is `targetPath` inside `baseDir`? Shared by
|
|
11
|
+
* `resolveWithinRoot()` below (output paths, checked lexically since they
|
|
12
|
+
* usually don't exist on disk yet) and `resolve-package-schema.ts` (which
|
|
13
|
+
* additionally re-checks this against `fs.realpath`-resolved paths, since a
|
|
14
|
+
* package-declared schema path both exists on disk and crosses a real trust
|
|
15
|
+
* boundary -- see ADR 0014). Boundary-agnostic on purpose: neither caller's
|
|
16
|
+
* notion of "root" is baked in here.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isWithinDirectory(baseDir: string, targetPath: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Resolves `location` against `root` and checks the result doesn't escape it
|
|
21
|
+
* (e.g. `location: "../../malicious.ts"`, or an absolute path on another
|
|
22
|
+
* branch of the filesystem entirely). Discovery (`include`/`exclude`) is
|
|
23
|
+
* already safe by construction -- it only ever walks *down* from `root` via
|
|
24
|
+
* `readdir`, so a pattern can't make it read outside `root`. Output
|
|
25
|
+
* locations have no such structural guarantee, since `path.resolve` happily
|
|
26
|
+
* walks back out via `..` segments, so this is a plain lexical bounds-check
|
|
27
|
+
* (not a symlink-aware `realpath` check -- these are *output* paths that
|
|
28
|
+
* usually don't exist yet).
|
|
29
|
+
*
|
|
30
|
+
* Never throws itself -- returns a `CompatibilityIssue`-shaped finding on
|
|
31
|
+
* escape so each generator function (`generateEnvManifest`, `generateDocumentation`,
|
|
32
|
+
* `generateUsageReport`, `generateEnvArtifacts`) can wrap it in its own error type.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveWithinRoot(root: string, location: string, optionName: string, functionName: string): ResolveWithinRootResult;
|
|
35
|
+
//# sourceMappingURL=resolve-within-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-within-root.d.ts","sourceRoot":"","sources":["../../../src/build/resolve-within-root.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAE5D,MAAM,MAAM,uBAAuB,GAC/B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,kBAAkB,CAAA;CAAE,CAAA;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAG9E;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACnB,uBAAuB,CAgBzB"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SARIF export -- an adapter over Finding Model, not a new fact source.
|
|
3
|
+
* Produces a minimal, spec-conformant SARIF 2.1.0 log
|
|
4
|
+
* (https://docs.oasis-open.org/sarif/sarif/v2.1.0/) so env-cap's findings can
|
|
5
|
+
* be consumed by any SARIF-aware tool (GitHub code scanning, most CI security
|
|
6
|
+
* dashboards) without a bespoke integration.
|
|
7
|
+
*
|
|
8
|
+
* Pure and synchronous: every input is already computed by the time this
|
|
9
|
+
* runs, so this never re-derives a finding, never reads the filesystem, and
|
|
10
|
+
* never decides what is or isn't a problem -- it only re-shapes what
|
|
11
|
+
* `buildFindingModel()` already concluded.
|
|
12
|
+
*/
|
|
13
|
+
import type { FindingModel } from "./finding-model.js";
|
|
14
|
+
/** SARIF's `level` enum -- see the SARIF 2.1.0 spec, section 3.27.10. */
|
|
15
|
+
type SarifLevel = "none" | "note" | "warning" | "error";
|
|
16
|
+
interface SarifLocation {
|
|
17
|
+
readonly physicalLocation: {
|
|
18
|
+
readonly artifactLocation: {
|
|
19
|
+
readonly uri: string;
|
|
20
|
+
};
|
|
21
|
+
readonly region?: {
|
|
22
|
+
readonly startLine: number;
|
|
23
|
+
readonly startColumn: number;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
interface SarifResult {
|
|
28
|
+
readonly ruleId: string;
|
|
29
|
+
readonly level: SarifLevel;
|
|
30
|
+
readonly message: {
|
|
31
|
+
readonly text: string;
|
|
32
|
+
};
|
|
33
|
+
readonly locations?: readonly SarifLocation[];
|
|
34
|
+
}
|
|
35
|
+
/** A minimal SARIF 2.1.0 log -- only the properties this adapter actually populates, not the full spec surface. */
|
|
36
|
+
export interface SarifLog {
|
|
37
|
+
readonly $schema: string;
|
|
38
|
+
readonly version: "2.1.0";
|
|
39
|
+
readonly runs: readonly {
|
|
40
|
+
readonly tool: {
|
|
41
|
+
readonly driver: {
|
|
42
|
+
readonly name: string;
|
|
43
|
+
readonly informationUri: string;
|
|
44
|
+
readonly version: string;
|
|
45
|
+
readonly rules: readonly {
|
|
46
|
+
readonly id: string;
|
|
47
|
+
}[];
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
readonly results: readonly SarifResult[];
|
|
51
|
+
}[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Projects Finding Model into a SARIF 2.1.0 log.
|
|
55
|
+
*
|
|
56
|
+
* @remarks
|
|
57
|
+
* `rules` lists every distinct `FindingCode` actually present in this run,
|
|
58
|
+
* sorted -- not the full `FindingCode` union. A SARIF consumer treats the
|
|
59
|
+
* rules array as "what this tool reported", and advertising rules that
|
|
60
|
+
* produced no result makes a clean run look like it has unexplained silent
|
|
61
|
+
* rules. `results` preserves Finding Model's own order, which a caller wanting
|
|
62
|
+
* a different one sorts themselves.
|
|
63
|
+
*/
|
|
64
|
+
export declare function buildSarifLog(findingModel: FindingModel): SarifLog;
|
|
65
|
+
export {};
|
|
66
|
+
//# sourceMappingURL=sarif.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif.d.ts","sourceRoot":"","sources":["../../../src/build/sarif.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAW,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAG/D,yEAAyE;AACzE,KAAK,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAA;AAOvD,UAAU,aAAa;IACrB,QAAQ,CAAC,gBAAgB,EAAE;QACzB,QAAQ,CAAC,gBAAgB,EAAE;YAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;SAAE,CAAA;QACnD,QAAQ,CAAC,MAAM,CAAC,EAAE;YAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;SAAE,CAAA;KAC/E,CAAA;CACF;AAuCD,UAAU,WAAW;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,OAAO,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAC3C,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,aAAa,EAAE,CAAA;CAC9C;AAED,mHAAmH;AACnH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS;QACtB,QAAQ,CAAC,IAAI,EAAE;YACb,QAAQ,CAAC,MAAM,EAAE;gBACf,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;gBACrB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;gBAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;gBACxB,QAAQ,CAAC,KAAK,EAAE,SAAS;oBAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;iBAAE,EAAE,CAAA;aACnD,CAAA;SACF,CAAA;QACD,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAA;KACzC,EAAE,CAAA;CACJ;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,YAAY,GAAG,QAAQ,CA0BlE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ImportBinding } from "./parse.js";
|
|
2
|
+
/**
|
|
3
|
+
* Why a tracked binding's value flowed somewhere this single-file, syntactic
|
|
4
|
+
* walk cannot follow -- see ADR 0039. Each reason names the exact construct
|
|
5
|
+
* so a downstream "cannot determine whether X is read" message can cite it,
|
|
6
|
+
* rather than a single opaque "escape" label.
|
|
7
|
+
*/
|
|
8
|
+
export type EscapeReason =
|
|
9
|
+
/** `const { ...rest } = contract` -- a rest element captures every remaining key at once. */
|
|
10
|
+
"rest"
|
|
11
|
+
/** `const { X: { Y } } = contract` -- the bound value itself gets destructured again, one level too deep for this pass. */
|
|
12
|
+
| "nested-pattern"
|
|
13
|
+
/** `const { [expr]: v } = contract` where `expr` isn't a string literal -- the bound key can't be read without evaluating `expr`. */
|
|
14
|
+
| "computed-key"
|
|
15
|
+
/** `const e = contract` where `e` isn't file-unique/never-assigned (see `resolveAliasTargets`) -- the read is real, but this pass declines to follow `e` any further. */
|
|
16
|
+
| "reassignment";
|
|
17
|
+
/** One observed use of a tracked contract binding in a consumer file -- see ADR 0039. Consumed by `dependency-graph.ts`. */
|
|
18
|
+
export type AccessSite = {
|
|
19
|
+
readonly kind: "member";
|
|
20
|
+
readonly member: string;
|
|
21
|
+
readonly line: number;
|
|
22
|
+
readonly column: number;
|
|
23
|
+
} | {
|
|
24
|
+
readonly kind: "dynamic";
|
|
25
|
+
readonly line: number;
|
|
26
|
+
readonly column: number;
|
|
27
|
+
} | {
|
|
28
|
+
readonly kind: "reference";
|
|
29
|
+
readonly line: number;
|
|
30
|
+
readonly column: number;
|
|
31
|
+
} | {
|
|
32
|
+
readonly kind: "escape";
|
|
33
|
+
readonly via: EscapeReason;
|
|
34
|
+
readonly line: number;
|
|
35
|
+
readonly column: number;
|
|
36
|
+
};
|
|
37
|
+
export interface FileScanResult {
|
|
38
|
+
readonly file: string;
|
|
39
|
+
readonly imports: ReadonlyMap<string, ImportBinding>;
|
|
40
|
+
readonly accessesByLocalName: ReadonlyMap<string, readonly AccessSite[]>;
|
|
41
|
+
/** True if this file contains a bare `export * from "..."` -- used only to
|
|
42
|
+
* flag ambiguous barrel forwarding elsewhere as "unresolved", never to
|
|
43
|
+
* follow it (see ADR 0010's scope boundary). */
|
|
44
|
+
readonly hasWildcardReExport: boolean;
|
|
45
|
+
}
|
|
46
|
+
export declare function scanFileForDependencies(filePath: string, sourceText: string): FileScanResult;
|
|
47
|
+
//# sourceMappingURL=scan-dependencies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-dependencies.d.ts","sourceRoot":"","sources":["../../../src/build/scan-dependencies.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAG/C;;;;;GAKG;AACH,MAAM,MAAM,YAAY;AACtB,6FAA6F;AAC3F,MAAM;AACR,2HAA2H;GACzH,gBAAgB;AAClB,qIAAqI;GACnI,cAAc;AAChB,yKAAyK;GACvK,cAAc,CAAA;AAElB,4HAA4H;AAC5H,MAAM,MAAM,UAAU,GAClB;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB,GACD;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC5E;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC9E;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB,CAAA;AAEL,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IACpD,QAAQ,CAAC,mBAAmB,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC,CAAA;IACxE;;qDAEiD;IACjD,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAA;CACtC;AAuPD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,CAwK5F"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The canonical ordering every fact model's contract list is sorted by: `file`
|
|
3
|
+
* (root-relative, POSIX) then `exportName`. One definition so `JSON.stringify`
|
|
4
|
+
* output is stable and diffs cleanly across Contract / Ownership / Lifecycle /
|
|
5
|
+
* Dependency Models. Internal -- not re-exported from the public `.` barrel.
|
|
6
|
+
*/
|
|
7
|
+
export declare function byContractIdentity(a: {
|
|
8
|
+
readonly file: string;
|
|
9
|
+
readonly exportName: string;
|
|
10
|
+
}, b: {
|
|
11
|
+
readonly file: string;
|
|
12
|
+
readonly exportName: string;
|
|
13
|
+
}): number;
|
|
14
|
+
//# sourceMappingURL=sort-by-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sort-by-identity.d.ts","sourceRoot":"","sources":["../../../src/build/sort-by-identity.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EACzD,CAAC,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACxD,MAAM,CAER"}
|