monkeypatchlist 0.0.0-stage → 0.1.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 +202 -0
- package/NOTICE +61 -0
- package/README.md +183 -2
- package/catalog/catalog.json +552211 -0
- package/catalog/catalog.schema.json +787 -0
- package/catalog/changelog.json +3 -0
- package/dist/bin/monkeypatchlist.d.ts +2 -0
- package/dist/bin/monkeypatchlist.js +3 -0
- package/dist/catalog.d.ts +561 -0
- package/dist/catalog.js +58 -0
- package/dist/cli.d.ts +84 -0
- package/dist/cli.js +470 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/lockfile-input.d.ts +9 -0
- package/dist/lockfile-input.js +91 -0
- package/dist/packages/analysis/binding.d.ts +2 -0
- package/dist/packages/analysis/binding.js +5 -0
- package/dist/packages/analysis/index.d.ts +10 -0
- package/dist/packages/analysis/index.js +13 -0
- package/dist/packages/analysis/job.d.ts +33 -0
- package/dist/packages/analysis/job.js +85 -0
- package/dist/packages/analysis/lib/absence-tags.d.ts +34 -0
- package/dist/packages/analysis/lib/absence-tags.js +340 -0
- package/dist/packages/analysis/lib/ast.d.ts +28 -0
- package/dist/packages/analysis/lib/ast.js +64 -0
- package/dist/packages/analysis/lib/binding.d.ts +36 -0
- package/dist/packages/analysis/lib/binding.js +66 -0
- package/dist/packages/analysis/lib/budget.d.ts +80 -0
- package/dist/packages/analysis/lib/budget.js +31 -0
- package/dist/packages/analysis/lib/catch-arms.d.ts +19 -0
- package/dist/packages/analysis/lib/catch-arms.js +351 -0
- package/dist/packages/analysis/lib/chunk-loads.d.ts +160 -0
- package/dist/packages/analysis/lib/chunk-loads.js +882 -0
- package/dist/packages/analysis/lib/chunk-registry.d.ts +45 -0
- package/dist/packages/analysis/lib/chunk-registry.js +334 -0
- package/dist/packages/analysis/lib/code-routes.d.ts +52 -0
- package/dist/packages/analysis/lib/code-routes.js +921 -0
- package/dist/packages/analysis/lib/collisions.d.ts +22 -0
- package/dist/packages/analysis/lib/collisions.js +103 -0
- package/dist/packages/analysis/lib/definitions.d.ts +76 -0
- package/dist/packages/analysis/lib/definitions.js +782 -0
- package/dist/packages/analysis/lib/early-exits.d.ts +39 -0
- package/dist/packages/analysis/lib/early-exits.js +161 -0
- package/dist/packages/analysis/lib/effect.d.ts +138 -0
- package/dist/packages/analysis/lib/effect.js +800 -0
- package/dist/packages/analysis/lib/global-object.d.ts +581 -0
- package/dist/packages/analysis/lib/global-object.js +8240 -0
- package/dist/packages/analysis/lib/keys.d.ts +33 -0
- package/dist/packages/analysis/lib/keys.js +82 -0
- package/dist/packages/analysis/lib/line-starts.d.ts +41 -0
- package/dist/packages/analysis/lib/line-starts.js +79 -0
- package/dist/packages/analysis/lib/link-group.d.ts +51 -0
- package/dist/packages/analysis/lib/link-group.js +487 -0
- package/dist/packages/analysis/lib/module-links.d.ts +117 -0
- package/dist/packages/analysis/lib/module-links.js +1060 -0
- package/dist/packages/analysis/lib/nested-code.d.ts +38 -0
- package/dist/packages/analysis/lib/nested-code.js +200 -0
- package/dist/packages/analysis/lib/numeric.d.ts +16 -0
- package/dist/packages/analysis/lib/numeric.js +216 -0
- package/dist/packages/analysis/lib/once-flags.d.ts +12 -0
- package/dist/packages/analysis/lib/once-flags.js +190 -0
- package/dist/packages/analysis/lib/parameter-arguments.d.ts +12 -0
- package/dist/packages/analysis/lib/parameter-arguments.js +34 -0
- package/dist/packages/analysis/lib/parse.d.ts +10 -0
- package/dist/packages/analysis/lib/parse.js +39 -0
- package/dist/packages/analysis/lib/partial.d.ts +60 -0
- package/dist/packages/analysis/lib/partial.js +518 -0
- package/dist/packages/analysis/lib/print.d.ts +3 -0
- package/dist/packages/analysis/lib/print.js +150 -0
- package/dist/packages/analysis/lib/reachability.d.ts +137 -0
- package/dist/packages/analysis/lib/reachability.js +1295 -0
- package/dist/packages/analysis/lib/resolver.d.ts +13 -0
- package/dist/packages/analysis/lib/resolver.js +2886 -0
- package/dist/packages/analysis/lib/restores.d.ts +42 -0
- package/dist/packages/analysis/lib/restores.js +482 -0
- package/dist/packages/analysis/lib/rewritten-deletes.d.ts +6 -0
- package/dist/packages/analysis/lib/rewritten-deletes.js +142 -0
- package/dist/packages/analysis/lib/scope.d.ts +110 -0
- package/dist/packages/analysis/lib/scope.js +443 -0
- package/dist/packages/analysis/lib/script-loads.d.ts +56 -0
- package/dist/packages/analysis/lib/script-loads.js +359 -0
- package/dist/packages/analysis/lib/summaries.d.ts +177 -0
- package/dist/packages/analysis/lib/summaries.js +498 -0
- package/dist/packages/analysis/lib/types.d.ts +632 -0
- package/dist/packages/analysis/lib/types.js +128 -0
- package/dist/packages/analysis/lib/wrap.d.ts +34 -0
- package/dist/packages/analysis/lib/wrap.js +407 -0
- package/dist/packages/analysis/lib/writes.d.ts +358 -0
- package/dist/packages/analysis/lib/writes.js +1612 -0
- package/dist/packages/analysis/visit-order.d.ts +3 -0
- package/dist/packages/analysis/visit-order.js +23 -0
- package/dist/packages/attribution/index.d.ts +233 -0
- package/dist/packages/attribution/index.js +444 -0
- package/dist/packages/attribution/lib/containing-package.d.ts +76 -0
- package/dist/packages/attribution/lib/containing-package.js +304 -0
- package/dist/packages/attribution/lib/first-party.d.ts +37 -0
- package/dist/packages/attribution/lib/first-party.js +153 -0
- package/dist/packages/attribution/lib/lockfile-graph.d.ts +99 -0
- package/dist/packages/attribution/lib/lockfile-graph.js +158 -0
- package/dist/packages/attribution/lib/lockfile.d.ts +33 -0
- package/dist/packages/attribution/lib/lockfile.js +330 -0
- package/dist/packages/attribution/lib/path-rules.d.ts +29 -0
- package/dist/packages/attribution/lib/path-rules.js +84 -0
- package/dist/packages/attribution/lib/pnpm.d.ts +4 -0
- package/dist/packages/attribution/lib/pnpm.js +133 -0
- package/dist/packages/attribution/lib/remote-url.d.ts +7 -0
- package/dist/packages/attribution/lib/remote-url.js +24 -0
- package/dist/packages/attribution/lib/source-map.d.ts +51 -0
- package/dist/packages/attribution/lib/source-map.js +125 -0
- package/dist/packages/attribution/lib/yaml.d.ts +9 -0
- package/dist/packages/attribution/lib/yaml.js +277 -0
- package/dist/packages/attribution/lib/yarn.d.ts +7 -0
- package/dist/packages/attribution/lib/yarn.js +227 -0
- package/dist/packages/baseline/index.d.ts +45 -0
- package/dist/packages/baseline/index.js +41 -0
- package/dist/packages/baseline/lib/error.d.ts +15 -0
- package/dist/packages/baseline/lib/error.js +25 -0
- package/dist/packages/baseline/lib/format.d.ts +49 -0
- package/dist/packages/baseline/lib/format.js +22 -0
- package/dist/packages/baseline/lib/migrations.d.ts +19 -0
- package/dist/packages/baseline/lib/migrations.js +7 -0
- package/dist/packages/baseline/lib/previous.d.ts +23 -0
- package/dist/packages/baseline/lib/previous.js +64 -0
- package/dist/packages/baseline/lib/read.d.ts +39 -0
- package/dist/packages/baseline/lib/read.js +219 -0
- package/dist/packages/baseline/lib/report.d.ts +25 -0
- package/dist/packages/baseline/lib/report.js +104 -0
- package/dist/packages/baseline/lib/skew.d.ts +51 -0
- package/dist/packages/baseline/lib/skew.js +75 -0
- package/dist/packages/compare/index.d.ts +120 -0
- package/dist/packages/compare/index.js +274 -0
- package/dist/packages/compare/lib/catalog-notes.d.ts +73 -0
- package/dist/packages/compare/lib/catalog-notes.js +224 -0
- package/dist/packages/completeness/index.d.ts +246 -0
- package/dist/packages/completeness/index.js +249 -0
- package/dist/packages/confidence/index.d.ts +54 -0
- package/dist/packages/confidence/index.js +71 -0
- package/dist/packages/config/index.d.ts +107 -0
- package/dist/packages/config/index.js +95 -0
- package/dist/packages/config/lib/command-line.d.ts +23 -0
- package/dist/packages/config/lib/command-line.js +239 -0
- package/dist/packages/config/lib/config-file.d.ts +11 -0
- package/dist/packages/config/lib/config-file.js +119 -0
- package/dist/packages/config/lib/scan-config-id.d.ts +28 -0
- package/dist/packages/config/lib/scan-config-id.js +54 -0
- package/dist/packages/config/lib/schema.d.ts +2 -0
- package/dist/packages/config/lib/schema.js +31 -0
- package/dist/packages/config/lib/types.d.ts +64 -0
- package/dist/packages/config/lib/types.js +6 -0
- package/dist/packages/config/lib/urls.d.ts +6 -0
- package/dist/packages/config/lib/urls.js +9 -0
- package/dist/packages/discovery/index.d.ts +277 -0
- package/dist/packages/discovery/index.js +1950 -0
- package/dist/packages/discovery/lib/import-map.d.ts +68 -0
- package/dist/packages/discovery/lib/import-map.js +180 -0
- package/dist/packages/discovery/lib/requests.d.ts +58 -0
- package/dist/packages/discovery/lib/requests.js +591 -0
- package/dist/packages/discovery/lib/scopes.d.ts +6 -0
- package/dist/packages/discovery/lib/scopes.js +286 -0
- package/dist/packages/discovery/lib/source-maps.d.ts +56 -0
- package/dist/packages/discovery/lib/source-maps.js +209 -0
- package/dist/packages/discovery/lib/swept-code.d.ts +27 -0
- package/dist/packages/discovery/lib/swept-code.js +107 -0
- package/dist/packages/discovery/lib/syntax.d.ts +17 -0
- package/dist/packages/discovery/lib/syntax.js +39 -0
- package/dist/packages/findings/index.d.ts +106 -0
- package/dist/packages/findings/index.js +254 -0
- package/dist/packages/findings/lib/scope.d.ts +38 -0
- package/dist/packages/findings/lib/scope.js +110 -0
- package/dist/packages/parallel/index.d.ts +2 -0
- package/dist/packages/parallel/index.js +5 -0
- package/dist/packages/parallel/lib/protocol.d.ts +15 -0
- package/dist/packages/parallel/lib/protocol.js +2 -0
- package/dist/packages/parallel/lib/runner.d.ts +36 -0
- package/dist/packages/parallel/lib/runner.js +96 -0
- package/dist/packages/parallel/lib/schedule.d.ts +16 -0
- package/dist/packages/parallel/lib/schedule.js +52 -0
- package/dist/packages/parallel/lib/worker.d.ts +1 -0
- package/dist/packages/parallel/lib/worker.js +18 -0
- package/dist/packages/policy/index.d.ts +36 -0
- package/dist/packages/policy/index.js +22 -0
- package/dist/packages/report/explain.d.ts +26 -0
- package/dist/packages/report/explain.js +99 -0
- package/dist/packages/report/index.d.ts +210 -0
- package/dist/packages/report/index.js +388 -0
- package/dist/packages/report/terminal.d.ts +11 -0
- package/dist/packages/report/terminal.js +331 -0
- package/dist/packages/source-store/fixture.d.ts +22 -0
- package/dist/packages/source-store/fixture.js +58 -0
- package/dist/packages/source-store/index.d.ts +278 -0
- package/dist/packages/source-store/index.js +322 -0
- package/dist/packages/source-store/lib/addresses.d.ts +6 -0
- package/dist/packages/source-store/lib/addresses.js +91 -0
- package/dist/packages/source-store/lib/connection.d.ts +15 -0
- package/dist/packages/source-store/lib/connection.js +135 -0
- package/dist/packages/source-store/lib/content-types.d.ts +16 -0
- package/dist/packages/source-store/lib/content-types.js +75 -0
- package/dist/packages/source-store/lib/data-urls.d.ts +10 -0
- package/dist/packages/source-store/lib/data-urls.js +85 -0
- package/dist/packages/source-store/lib/deadline.d.ts +18 -0
- package/dist/packages/source-store/lib/deadline.js +44 -0
- package/dist/packages/source-store/lib/exchange.d.ts +29 -0
- package/dist/packages/source-store/lib/exchange.js +112 -0
- package/dist/packages/source-store/lib/integrity.d.ts +19 -0
- package/dist/packages/source-store/lib/integrity.js +86 -0
- package/dist/packages/source-store/lib/outcomes.d.ts +12 -0
- package/dist/packages/source-store/lib/outcomes.js +22 -0
- package/dist/packages/source-store/lib/proxy.d.ts +11 -0
- package/dist/packages/source-store/lib/proxy.js +53 -0
- package/dist/packages/source-store/lib/session.d.ts +12 -0
- package/dist/packages/source-store/lib/session.js +139 -0
- package/dist/packages/source-store/lib/urls.d.ts +6 -0
- package/dist/packages/source-store/lib/urls.js +15 -0
- package/dist/packages/source-store/resolve.d.ts +59 -0
- package/dist/packages/source-store/resolve.js +45 -0
- package/dist/scan.d.ts +65 -0
- package/dist/scan.js +592 -0
- package/package.json +95 -4
- package/schema/config.schema.json +133 -0
- package/schema/report.schema.json +1905 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A specifier map: each specifier key with the URL it maps to, or null when the entry is invalid and blocks the
|
|
3
|
+
* specifier, in the order resolution tries them. One import map's keys are sorted in descending code unit order, so
|
|
4
|
+
* that a longer prefix key is tried before a shorter one. A merge appends a later map's keys without sorting again.
|
|
5
|
+
*/
|
|
6
|
+
type SpecifierMap = [key: string, address: URL | null][];
|
|
7
|
+
/**
|
|
8
|
+
* An import map: its top-level `imports`, its `scopes`, each a scope prefix URL with its specifier map, and its
|
|
9
|
+
* `integrity`, the integrity metadata of each module URL it names (§17 Integrity).
|
|
10
|
+
*/
|
|
11
|
+
export interface ImportMap {
|
|
12
|
+
imports: SpecifierMap;
|
|
13
|
+
scopes: [prefix: string, imports: SpecifierMap][];
|
|
14
|
+
integrity: ReadonlyMap<string, string>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A specifier resolution record (HTML § Resolved module set): a module specifier that resolved through a document's
|
|
18
|
+
* import maps, from a script whose base URL is `base` (serialized), as `specifier` (the specifier's URL, serialized,
|
|
19
|
+
* when it is URL-like) and `asUrl` (that URL, or null for a bare specifier). A later import map's rules that would
|
|
20
|
+
* change its resolution are dropped when they merge (`mergeImportMaps`).
|
|
21
|
+
*/
|
|
22
|
+
export interface ResolvedModule {
|
|
23
|
+
base: string;
|
|
24
|
+
specifier: string;
|
|
25
|
+
asUrl: URL | null;
|
|
26
|
+
}
|
|
27
|
+
/** The empty import map a document starts with. */
|
|
28
|
+
export declare const emptyImportMap: ImportMap;
|
|
29
|
+
/**
|
|
30
|
+
* Parses the text of a `<script type=importmap>` (HTML § Parse an import map string), with addresses and scope
|
|
31
|
+
* prefixes resolved against `base`, the document's base URL. Null when the browser rejects the whole map: text that is
|
|
32
|
+
* not JSON, a map that is not a JSON object, or `imports`, `scopes` (or a scope's map) or `integrity` that is not one.
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseImportMap(text: string, base: string): ImportMap | null;
|
|
35
|
+
/**
|
|
36
|
+
* The integrity metadata an import map gives the module at `url` (HTML § Resolve a module integrity metadata), or the
|
|
37
|
+
* empty string when it gives none.
|
|
38
|
+
*/
|
|
39
|
+
export declare function moduleIntegrity(map: ImportMap, url: URL): string;
|
|
40
|
+
/**
|
|
41
|
+
* Merges a document's next import map into the one it has (HTML § Merge existing and new import maps), given the
|
|
42
|
+
* specifiers the document has resolved so far (`resolved`):
|
|
43
|
+
*
|
|
44
|
+
* - A rule of the new map that could change an already resolved specifier is dropped: a key equal to the specifier, or
|
|
45
|
+
* a prefix key of it (`impacts`). In a scope, only the records whose base URL the scope applies to count. At the top
|
|
46
|
+
* level every record counts, as in the standard's example and Chromium, rather than the standard's step, which drops
|
|
47
|
+
* a key that starts with the specifier (§2 Import maps).
|
|
48
|
+
* - An entry for a specifier key the existing map already has, at the top level or in the same scope, is dropped, and
|
|
49
|
+
* so is an integrity entry for a URL it already has, so the first definition wins.
|
|
50
|
+
* - The new map's other keys, and its new scopes, come after the existing ones, and nothing is sorted again: an
|
|
51
|
+
* earlier map's shorter prefix key, or its less specific scope, is still tried before a later map's longer one.
|
|
52
|
+
*/
|
|
53
|
+
export declare function mergeImportMaps(existing: ImportMap, next: ImportMap, resolved: readonly ResolvedModule[]): ImportMap;
|
|
54
|
+
/**
|
|
55
|
+
* Resolves a module specifier through an import map (HTML § Resolve a module specifier), for a script whose base URL
|
|
56
|
+
* is `base`: its own URL, or for an inline script, its document's. Scopes whose prefix is `base`, or a path prefix of
|
|
57
|
+
* it, are tried in the map's order, then the top-level imports, and a URL-like specifier no entry maps is its URL. The
|
|
58
|
+
* resolution's record is what the document adds to its resolved module set (HTML § Add module to resolved module set).
|
|
59
|
+
* Otherwise the browser throws a TypeError, and this gives why: a bare specifier no entry maps, an entry that blocks
|
|
60
|
+
* it, or a prefix entry the rest of the specifier would climb out of.
|
|
61
|
+
*/
|
|
62
|
+
export declare function resolveSpecifier(map: ImportMap, specifier: string, base: string): {
|
|
63
|
+
url: URL;
|
|
64
|
+
record: ResolvedModule;
|
|
65
|
+
} | {
|
|
66
|
+
error: string;
|
|
67
|
+
};
|
|
68
|
+
export {};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// Import maps (HTML § Import maps): parsing, merging, module specifier resolution and module integrity metadata, as a
|
|
2
|
+
// current browser does them.
|
|
3
|
+
/** The empty import map a document starts with. */
|
|
4
|
+
export const emptyImportMap = { imports: [], scopes: [], integrity: new Map() };
|
|
5
|
+
/**
|
|
6
|
+
* Parses the text of a `<script type=importmap>` (HTML § Parse an import map string), with addresses and scope
|
|
7
|
+
* prefixes resolved against `base`, the document's base URL. Null when the browser rejects the whole map: text that is
|
|
8
|
+
* not JSON, a map that is not a JSON object, or `imports`, `scopes` (or a scope's map) or `integrity` that is not one.
|
|
9
|
+
*/
|
|
10
|
+
export function parseImportMap(text, base) {
|
|
11
|
+
let parsed;
|
|
12
|
+
try {
|
|
13
|
+
parsed = JSON.parse(text);
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
if (!isObject(parsed))
|
|
19
|
+
return null;
|
|
20
|
+
const { imports = {}, scopes = {}, integrity = {} } = parsed;
|
|
21
|
+
if (!isObject(imports) || !isObject(scopes) || !Object.values(scopes).every(isObject))
|
|
22
|
+
return null;
|
|
23
|
+
if (!isObject(integrity))
|
|
24
|
+
return null;
|
|
25
|
+
const normalizedScopes = [];
|
|
26
|
+
for (const [prefix, map] of Object.entries(scopes)) {
|
|
27
|
+
const url = URL.parse(prefix, base);
|
|
28
|
+
if (url !== null)
|
|
29
|
+
normalizedScopes.push([url.href, specifierMap(map, base)]);
|
|
30
|
+
}
|
|
31
|
+
const normalizedIntegrity = integrityMap(integrity, base);
|
|
32
|
+
return { imports: specifierMap(imports, base), scopes: sorted(normalizedScopes), integrity: normalizedIntegrity };
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* HTML § Normalize a module integrity map: each key is a URL-like specifier, resolved against `base`, whose value is a
|
|
36
|
+
* string. A bare key, and a value that is not a string, are dropped.
|
|
37
|
+
*/
|
|
38
|
+
function integrityMap(map, base) {
|
|
39
|
+
const normalized = new Map();
|
|
40
|
+
for (const [key, value] of Object.entries(map)) {
|
|
41
|
+
const url = resolveUrlLike(key, base);
|
|
42
|
+
if (url !== null && typeof value === 'string')
|
|
43
|
+
normalized.set(url.href, value);
|
|
44
|
+
}
|
|
45
|
+
return normalized;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The integrity metadata an import map gives the module at `url` (HTML § Resolve a module integrity metadata), or the
|
|
49
|
+
* empty string when it gives none.
|
|
50
|
+
*/
|
|
51
|
+
export function moduleIntegrity(map, url) {
|
|
52
|
+
return map.integrity.get(url.href) ?? '';
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Merges a document's next import map into the one it has (HTML § Merge existing and new import maps), given the
|
|
56
|
+
* specifiers the document has resolved so far (`resolved`):
|
|
57
|
+
*
|
|
58
|
+
* - A rule of the new map that could change an already resolved specifier is dropped: a key equal to the specifier, or
|
|
59
|
+
* a prefix key of it (`impacts`). In a scope, only the records whose base URL the scope applies to count. At the top
|
|
60
|
+
* level every record counts, as in the standard's example and Chromium, rather than the standard's step, which drops
|
|
61
|
+
* a key that starts with the specifier (§2 Import maps).
|
|
62
|
+
* - An entry for a specifier key the existing map already has, at the top level or in the same scope, is dropped, and
|
|
63
|
+
* so is an integrity entry for a URL it already has, so the first definition wins.
|
|
64
|
+
* - The new map's other keys, and its new scopes, come after the existing ones, and nothing is sorted again: an
|
|
65
|
+
* earlier map's shorter prefix key, or its less specific scope, is still tried before a later map's longer one.
|
|
66
|
+
*/
|
|
67
|
+
export function mergeImportMaps(existing, next, resolved) {
|
|
68
|
+
const scopes = new Map(existing.scopes);
|
|
69
|
+
for (const [prefix, map] of next.scopes) {
|
|
70
|
+
const applies = resolved.filter(({ base }) => scopeApplies(prefix, base));
|
|
71
|
+
const imports = map.filter(([key]) => !applies.some((record) => impacts(key, record)));
|
|
72
|
+
scopes.set(prefix, merged(scopes.get(prefix) ?? [], imports));
|
|
73
|
+
}
|
|
74
|
+
const integrity = new Map([...next.integrity, ...existing.integrity]);
|
|
75
|
+
const imports = next.imports.filter(([key]) => !resolved.some((record) => impacts(key, record)));
|
|
76
|
+
return { imports: merged(existing.imports, imports), scopes: [...scopes], integrity };
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Whether a specifier key would change how a resolved specifier resolves (HTML § Merge existing and new import maps,
|
|
80
|
+
* the scope step's test): it is the specifier, or a prefix key of it.
|
|
81
|
+
*/
|
|
82
|
+
function impacts(key, { specifier, asUrl }) {
|
|
83
|
+
return key === specifier || isPrefixKeyOf(key, specifier, asUrl);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Whether `key` is a prefix key that matches the normalized specifier (HTML § Resolve an imports match): it ends in
|
|
87
|
+
* `/`, the specifier starts with it, and the specifier is bare or a URL with a special scheme.
|
|
88
|
+
*/
|
|
89
|
+
function isPrefixKeyOf(key, normalized, asUrl) {
|
|
90
|
+
return key.endsWith('/') && normalized.startsWith(key) && (asUrl === null || isSpecial(asUrl));
|
|
91
|
+
}
|
|
92
|
+
/** Whether a scope applies to a script whose base URL is `base`: its prefix is `base`, or a path prefix of it. */
|
|
93
|
+
function scopeApplies(prefix, base) {
|
|
94
|
+
return prefix === base || (prefix.endsWith('/') && base.startsWith(prefix));
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Resolves a module specifier through an import map (HTML § Resolve a module specifier), for a script whose base URL
|
|
98
|
+
* is `base`: its own URL, or for an inline script, its document's. Scopes whose prefix is `base`, or a path prefix of
|
|
99
|
+
* it, are tried in the map's order, then the top-level imports, and a URL-like specifier no entry maps is its URL. The
|
|
100
|
+
* resolution's record is what the document adds to its resolved module set (HTML § Add module to resolved module set).
|
|
101
|
+
* Otherwise the browser throws a TypeError, and this gives why: a bare specifier no entry maps, an entry that blocks
|
|
102
|
+
* it, or a prefix entry the rest of the specifier would climb out of.
|
|
103
|
+
*/
|
|
104
|
+
export function resolveSpecifier(map, specifier, base) {
|
|
105
|
+
const asUrl = resolveUrlLike(specifier, base);
|
|
106
|
+
const normalized = asUrl?.href ?? specifier;
|
|
107
|
+
const record = { base, specifier: normalized, asUrl };
|
|
108
|
+
let match = null;
|
|
109
|
+
for (const [prefix, imports] of map.scopes) {
|
|
110
|
+
if (scopeApplies(prefix, base)) {
|
|
111
|
+
match = importsMatch(normalized, asUrl, imports);
|
|
112
|
+
if (match !== null)
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
match ??= importsMatch(normalized, asUrl, map.imports) ?? (asUrl === null ? null : { url: asUrl });
|
|
117
|
+
if (match === null)
|
|
118
|
+
return { error: `the bare specifier ${JSON.stringify(specifier)} is mapped by no import map` };
|
|
119
|
+
return 'error' in match ? match : { url: match.url, record };
|
|
120
|
+
}
|
|
121
|
+
/** HTML § Resolve an imports match: an exact key, or a prefix key ending in `/`. Null when no key matches. */
|
|
122
|
+
function importsMatch(normalized, asUrl, imports) {
|
|
123
|
+
const blocked = { error: `an import map entry blocks the specifier ${JSON.stringify(normalized)}` };
|
|
124
|
+
for (const [key, address] of imports) {
|
|
125
|
+
if (key === normalized)
|
|
126
|
+
return address === null ? blocked : { url: address };
|
|
127
|
+
if (isPrefixKeyOf(key, normalized, asUrl)) {
|
|
128
|
+
if (address === null)
|
|
129
|
+
return blocked;
|
|
130
|
+
const url = URL.parse(normalized.slice(key.length), address.href);
|
|
131
|
+
if (url === null || !url.href.startsWith(address.href)) {
|
|
132
|
+
return { error: `the specifier ${JSON.stringify(normalized)} leaves the prefix its import map entry maps` };
|
|
133
|
+
}
|
|
134
|
+
return { url };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* HTML § Resolve a URL-like module specifier: one that starts with `/`, `./` or `../` is relative to `base`, and any
|
|
141
|
+
* other must be an absolute URL. Null for a bare specifier.
|
|
142
|
+
*/
|
|
143
|
+
function resolveUrlLike(specifier, base) {
|
|
144
|
+
if (specifier.startsWith('/') || specifier.startsWith('./') || specifier.startsWith('../')) {
|
|
145
|
+
return URL.parse(specifier, base);
|
|
146
|
+
}
|
|
147
|
+
return URL.parse(specifier);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* HTML § Sort and normalize a module specifier map. An empty key is dropped, and a URL-like key becomes its URL. An
|
|
151
|
+
* entry is null when its address is not a string, not URL-like, or doesn't end in `/` when its key does.
|
|
152
|
+
*/
|
|
153
|
+
function specifierMap(map, base) {
|
|
154
|
+
const entries = new Map();
|
|
155
|
+
for (const [key, value] of Object.entries(map)) {
|
|
156
|
+
if (key === '')
|
|
157
|
+
continue;
|
|
158
|
+
const normalizedKey = resolveUrlLike(key, base)?.href ?? key;
|
|
159
|
+
const address = typeof value === 'string' ? resolveUrlLike(value, base) : null;
|
|
160
|
+
entries.set(normalizedKey, address !== null && key.endsWith('/') && !address.href.endsWith('/') ? null : address);
|
|
161
|
+
}
|
|
162
|
+
return sorted([...entries]);
|
|
163
|
+
}
|
|
164
|
+
/** HTML § Merge module specifier maps: the existing map, then each new key it doesn't have, in the new map's order. */
|
|
165
|
+
function merged(existing, next) {
|
|
166
|
+
const keys = new Set(existing.map(([key]) => key));
|
|
167
|
+
return [...existing, ...next.filter(([key]) => !keys.has(key))];
|
|
168
|
+
}
|
|
169
|
+
/** Entries in descending code unit order of their keys. */
|
|
170
|
+
function sorted(entries) {
|
|
171
|
+
return entries.sort(([a], [b]) => (a < b ? 1 : a > b ? -1 : 0));
|
|
172
|
+
}
|
|
173
|
+
/** Whether a URL's scheme is special (URL Standard): `ftp`, `file`, `http`, `https`, `ws` or `wss`. */
|
|
174
|
+
function isSpecial(url) {
|
|
175
|
+
return ['ftp:', 'file:', 'http:', 'https:', 'ws:', 'wss:'].includes(url.protocol);
|
|
176
|
+
}
|
|
177
|
+
/** A JSON object: what the import map algorithms call an ordered map. */
|
|
178
|
+
function isObject(value) {
|
|
179
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
180
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A module request in an artifact's code: the specifier it names, or null for a dynamic import whose specifier is not
|
|
3
|
+
* a literal, the UTF-16 range of the specifier's expression, and whether it is a dynamic import. `readableOptions` is
|
|
4
|
+
* false for a dynamic import whose options have a part the analyzer can't read that could decide whether it names a
|
|
5
|
+
* JavaScript module (§2 Import attributes). `follow` is whether any readable branch of the options names one: false
|
|
6
|
+
* for a request with attributes, true for the rest, and for an unreadable one only when another branch names one.
|
|
7
|
+
*/
|
|
8
|
+
export interface ModuleRequest {
|
|
9
|
+
specifier: string | null;
|
|
10
|
+
start: number;
|
|
11
|
+
end: number;
|
|
12
|
+
dynamic: boolean;
|
|
13
|
+
readableOptions: boolean;
|
|
14
|
+
follow: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* How code loads a worker script (§2 Discovery): `new Worker`, `new SharedWorker`, `navigator.serviceWorker.register`,
|
|
18
|
+
* or `importScripts`, which loads a classic script into the worker that calls it.
|
|
19
|
+
*/
|
|
20
|
+
export type WorkerKind = 'worker' | 'shared-worker' | 'service-worker' | 'import-scripts';
|
|
21
|
+
/**
|
|
22
|
+
* A worker script that code loads: `url` is its literal URL (a string literal, or a template literal with no
|
|
23
|
+
* substitutions), or null when the URL argument isn't a literal, which only the resolver can fold (§2 Computed URLs).
|
|
24
|
+
* `sourceType` is `module` when the options' `type` is `"module"`, and null when the options can't be read statically,
|
|
25
|
+
* so that the script's syntax decides it (§2). `through` is the global name the call reaches its function through
|
|
26
|
+
* (`self` in `self.importScripts(…)`), if any, and `start` and `end` the UTF-16 range of the URL.
|
|
27
|
+
*/
|
|
28
|
+
export interface WorkerRequest {
|
|
29
|
+
kind: WorkerKind;
|
|
30
|
+
url: string | null;
|
|
31
|
+
sourceType: 'script' | 'module' | null;
|
|
32
|
+
through?: string;
|
|
33
|
+
start: number;
|
|
34
|
+
end: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The references of a script or module, each list in source order. `unsupported` is true when a static import or
|
|
38
|
+
* re-export has an import attribute a browser doesn't support: a key other than `type`, or a `type` other than `"json"`
|
|
39
|
+
* or `"css"`. That fails every module graph that contains the module (§2 Import attributes, Principle 1).
|
|
40
|
+
*/
|
|
41
|
+
export interface Requests {
|
|
42
|
+
modules: ModuleRequest[];
|
|
43
|
+
workers: WorkerRequest[];
|
|
44
|
+
unsupported: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The references in `text`, parsed with `sourceType`. None when the code doesn't parse, as nothing of it runs: that
|
|
48
|
+
* includes a classic script with an `import` or `export` declaration, which oxc reports only among the semantic errors
|
|
49
|
+
* §5's options leave out.
|
|
50
|
+
*
|
|
51
|
+
* - **Modules:** its static imports and re-exports, and its dynamic imports, except those with an import attribute
|
|
52
|
+
* (§2 Import maps): a `type` names a module that is not JavaScript, and a browser supports no other key. A dynamic
|
|
53
|
+
* import's specifier is a literal when it is a string literal, or a template literal with no substitutions. One
|
|
54
|
+
* whose options have a part that can't be read (`importAttributes`) is a request whose attributes can't be read
|
|
55
|
+
* (`readableOptions: false`), and is followed only when another branch names a JavaScript module (`follow`).
|
|
56
|
+
* - **Workers:** the worker scripts it loads, with a literal URL or not (see `workerRequests`).
|
|
57
|
+
*/
|
|
58
|
+
export declare function requests(text: string, sourceType: 'script' | 'module'): Requests;
|