@endo/compartment-mapper 1.5.0 → 1.6.1
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 +1 -1
- package/README.md +278 -111
- package/SECURITY.md +2 -2
- package/bundle.d.ts +1 -1
- package/bundle.js +4 -1
- package/functor-lite.d.ts +3 -0
- package/functor-lite.d.ts.map +1 -0
- package/functor-lite.js +4 -0
- package/functor.d.ts +3 -0
- package/functor.d.ts.map +1 -0
- package/functor.js +4 -0
- package/index.d.ts +1 -1
- package/index.js +4 -1
- package/package.json +15 -11
- package/script-lite.d.ts +3 -0
- package/script-lite.d.ts.map +1 -0
- package/script-lite.js +4 -0
- package/script.d.ts +3 -0
- package/script.d.ts.map +1 -0
- package/script.js +4 -0
- package/src/archive-lite.d.ts +5 -5
- package/src/archive-lite.d.ts.map +1 -1
- package/src/archive-lite.js +1 -1
- package/src/archive.d.ts +5 -5
- package/src/archive.d.ts.map +1 -1
- package/src/archive.js +3 -1
- package/src/bundle-cjs.d.ts +12 -2
- package/src/bundle-cjs.d.ts.map +1 -1
- package/src/bundle-cjs.js +57 -28
- package/src/bundle-json.d.ts.map +1 -1
- package/src/bundle-json.js +2 -3
- package/src/bundle-lite.d.ts +91 -0
- package/src/bundle-lite.d.ts.map +1 -0
- package/src/bundle-lite.js +667 -0
- package/src/bundle-mjs.d.ts +13 -3
- package/src/bundle-mjs.d.ts.map +1 -1
- package/src/bundle-mjs.js +36 -19
- package/src/bundle.d.ts +48 -10
- package/src/bundle.d.ts.map +1 -1
- package/src/bundle.js +392 -126
- package/src/capture-lite.d.ts +1 -1
- package/src/capture-lite.d.ts.map +1 -1
- package/src/capture-lite.js +4 -2
- package/src/compartment-map.d.ts +1 -1
- package/src/compartment-map.d.ts.map +1 -1
- package/src/import-archive-lite.d.ts +2 -2
- package/src/import-archive-lite.d.ts.map +1 -1
- package/src/import-archive-lite.js +3 -1
- package/src/import-archive.d.ts +3 -3
- package/src/import-archive.d.ts.map +1 -1
- package/src/import-archive.js +3 -1
- package/src/import-hook.d.ts +3 -16
- package/src/import-hook.d.ts.map +1 -1
- package/src/import-hook.js +214 -116
- package/src/import-lite.d.ts +1 -1
- package/src/import-lite.d.ts.map +1 -1
- package/src/import-lite.js +7 -3
- package/src/import.d.ts.map +1 -1
- package/src/import.js +3 -1
- package/src/infer-exports.d.ts +5 -7
- package/src/infer-exports.d.ts.map +1 -1
- package/src/infer-exports.js +23 -8
- package/src/link.d.ts.map +1 -1
- package/src/link.js +4 -1
- package/src/map-parser.d.ts.map +1 -1
- package/src/map-parser.js +51 -5
- package/src/node-module-specifier.d.ts.map +1 -1
- package/src/node-module-specifier.js +3 -1
- package/src/node-modules.d.ts +4 -47
- package/src/node-modules.d.ts.map +1 -1
- package/src/node-modules.js +267 -148
- package/src/node-powers.d.ts +1 -1
- package/src/node-powers.d.ts.map +1 -1
- package/src/node-powers.js +3 -1
- package/src/parse-archive-cjs.d.ts +5 -1
- package/src/parse-archive-cjs.d.ts.map +1 -1
- package/src/parse-archive-cjs.js +11 -4
- package/src/parse-archive-mjs.d.ts +5 -1
- package/src/parse-archive-mjs.d.ts.map +1 -1
- package/src/parse-archive-mjs.js +3 -1
- package/src/parse-bytes.d.ts +5 -1
- package/src/parse-bytes.d.ts.map +1 -1
- package/src/parse-bytes.js +3 -1
- package/src/parse-cjs-shared-export-wrapper.d.ts.map +1 -1
- package/src/parse-cjs-shared-export-wrapper.js +5 -11
- package/src/parse-cjs.d.ts +5 -1
- package/src/parse-cjs.d.ts.map +1 -1
- package/src/parse-cjs.js +4 -2
- package/src/parse-json.d.ts +5 -2
- package/src/parse-json.d.ts.map +1 -1
- package/src/parse-mjs.d.ts +5 -1
- package/src/parse-mjs.d.ts.map +1 -1
- package/src/parse-mjs.js +2 -2
- package/src/parse-pre-cjs.d.ts +5 -1
- package/src/parse-pre-cjs.d.ts.map +1 -1
- package/src/parse-pre-cjs.js +3 -1
- package/src/parse-pre-mjs.d.ts +5 -1
- package/src/parse-pre-mjs.d.ts.map +1 -1
- package/src/parse-pre-mjs.js +3 -1
- package/src/parse-text.d.ts +5 -1
- package/src/parse-text.d.ts.map +1 -1
- package/src/parse-text.js +3 -1
- package/src/policy-format.d.ts +2 -1
- package/src/policy-format.d.ts.map +1 -1
- package/src/policy-format.js +5 -2
- package/src/policy.d.ts +2 -2
- package/src/policy.d.ts.map +1 -1
- package/src/policy.js +10 -11
- package/src/powers.d.ts +1 -1
- package/src/powers.d.ts.map +1 -1
- package/src/powers.js +3 -1
- package/src/search.d.ts +7 -12
- package/src/search.d.ts.map +1 -1
- package/src/search.js +32 -13
- package/src/types/compartment-map-schema.d.ts +8 -1
- package/src/types/compartment-map-schema.d.ts.map +1 -1
- package/src/types/compartment-map-schema.ts +8 -1
- package/src/types/external.d.ts +127 -17
- package/src/types/external.d.ts.map +1 -1
- package/src/types/external.ts +142 -17
- package/src/types/internal.d.ts +116 -29
- package/src/types/internal.d.ts.map +1 -1
- package/src/types/internal.ts +144 -31
- package/src/types/node-modules.d.ts +79 -0
- package/src/types/node-modules.d.ts.map +1 -0
- package/src/types/node-modules.ts +89 -0
- package/src/types/node-powers.d.ts +7 -5
- package/src/types/node-powers.d.ts.map +1 -1
- package/src/types/node-powers.ts +7 -5
- package/src/types/policy-schema.d.ts +3 -1
- package/src/types/policy-schema.d.ts.map +1 -1
- package/src/types/policy-schema.ts +3 -1
- package/src/types/policy.d.ts +3 -1
- package/src/types/policy.d.ts.map +1 -1
- package/src/types/policy.ts +3 -1
- package/src/types/powers.d.ts +5 -3
- package/src/types/powers.d.ts.map +1 -1
- package/src/types/powers.ts +5 -3
- package/src/types/typescript.d.ts +3 -1
- package/src/types/typescript.d.ts.map +1 -1
- package/src/types/typescript.ts +3 -1
- package/src/url.d.ts.map +1 -1
- package/src/url.js +3 -1
package/src/node-modules.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Provides functions for constructing a compartment map that has a
|
|
3
3
|
* compartment descriptor corresponding to every reachable package from an
|
|
4
4
|
* entry module and how to create links between them.
|
|
5
5
|
* The resulting compartment map does not describe individual modules but does
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
* wildcard expansion.
|
|
8
8
|
* See {@link link} to expand a compartment map to capture module descriptors
|
|
9
9
|
* for transitive dependencies.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
10
12
|
*/
|
|
11
13
|
|
|
12
14
|
/* eslint no-shadow: 0 */
|
|
@@ -17,57 +19,27 @@
|
|
|
17
19
|
* CompartmentDescriptor,
|
|
18
20
|
* CompartmentMapDescriptor,
|
|
19
21
|
* CompartmentMapForNodeModulesOptions,
|
|
20
|
-
* Language,
|
|
21
22
|
* LanguageForExtension,
|
|
22
23
|
* MapNodeModulesOptions,
|
|
23
24
|
* MaybeReadFn,
|
|
24
25
|
* MaybeReadPowers,
|
|
25
|
-
*
|
|
26
|
+
* PackageDescriptor,
|
|
27
|
+
* ReadDescriptorFn,
|
|
26
28
|
* ReadFn,
|
|
27
29
|
* ReadPowers,
|
|
28
|
-
* ScopeDescriptor,
|
|
29
30
|
* SomePackagePolicy,
|
|
30
31
|
* SomePolicy,
|
|
31
32
|
* } from './types.js'
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @typedef {object} Node
|
|
45
|
-
* @property {string} label
|
|
46
|
-
* @property {string} name
|
|
47
|
-
* @property {Array<string>} path
|
|
48
|
-
* @property {Array<string>} logicalPath
|
|
49
|
-
* @property {boolean} explicitExports
|
|
50
|
-
* @property {Record<string, string>} internalAliases
|
|
51
|
-
* @property {Record<string, string>} externalAliases
|
|
52
|
-
* @property {Record<string, string>} dependencyLocations - from module name to
|
|
53
|
-
* location in storage.
|
|
54
|
-
* @property {LanguageForExtension} parsers - the parser for
|
|
55
|
-
* modules based on their extension.
|
|
56
|
-
* @property {Record<string, Language>} types - the parser for specific
|
|
57
|
-
* modules.
|
|
58
|
-
*/
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* @typedef {object} LanguageOptions
|
|
62
|
-
* @property {LanguageForExtension} commonjsLanguageForExtension
|
|
63
|
-
* @property {LanguageForExtension} moduleLanguageForExtension
|
|
64
|
-
* @property {LanguageForExtension} workspaceCommonjsLanguageForExtension
|
|
65
|
-
* @property {LanguageForExtension} workspaceModuleLanguageForExtension
|
|
66
|
-
* @property {Set<string>} languages
|
|
67
|
-
*/
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* @typedef {Record<string, {spec: string, alias: string}>} CommonDependencyDescriptors
|
|
33
|
+
* @import {
|
|
34
|
+
* Graph,
|
|
35
|
+
* Node,
|
|
36
|
+
* LanguageOptions,
|
|
37
|
+
* CommonDependencyDescriptors,
|
|
38
|
+
* GatherDependencyOptions,
|
|
39
|
+
* GraphPackageOptions,
|
|
40
|
+
* GraphPackagesOptions,
|
|
41
|
+
* PackageDetails,
|
|
42
|
+
* } from './types/node-modules.js'
|
|
71
43
|
*/
|
|
72
44
|
|
|
73
45
|
import { pathCompare } from './compartment-map.js';
|
|
@@ -83,13 +55,18 @@ import {
|
|
|
83
55
|
import { unpackReadPowers } from './powers.js';
|
|
84
56
|
import { search, searchDescriptor } from './search.js';
|
|
85
57
|
|
|
86
|
-
const { assign, create, keys, values } = Object;
|
|
58
|
+
const { assign, create, keys, values, entries } = Object;
|
|
87
59
|
|
|
88
60
|
const decoder = new TextDecoder();
|
|
89
61
|
|
|
90
62
|
// q, as in quote, for enquoting strings in error messages.
|
|
91
63
|
const q = JSON.stringify;
|
|
92
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Default logger that does nothing.
|
|
67
|
+
*/
|
|
68
|
+
const noop = () => {};
|
|
69
|
+
|
|
93
70
|
/**
|
|
94
71
|
* @param {string} rel - a relative URL
|
|
95
72
|
* @param {string} abs - a fully qualified URL
|
|
@@ -99,12 +76,16 @@ const resolveLocation = (rel, abs) => {
|
|
|
99
76
|
return new URL(rel, abs).toString();
|
|
100
77
|
};
|
|
101
78
|
|
|
79
|
+
// Exported for testing:
|
|
102
80
|
/**
|
|
103
81
|
* @param {string} location
|
|
104
82
|
* @returns {string}
|
|
105
83
|
*/
|
|
106
|
-
const basename = location => {
|
|
107
|
-
|
|
84
|
+
export const basename = location => {
|
|
85
|
+
let { pathname } = new URL(location);
|
|
86
|
+
if (pathname.endsWith('/')) {
|
|
87
|
+
pathname = pathname.slice(0, -1);
|
|
88
|
+
}
|
|
108
89
|
const index = pathname.lastIndexOf('/');
|
|
109
90
|
if (index < 0) {
|
|
110
91
|
return pathname;
|
|
@@ -145,27 +126,103 @@ const readDescriptorWithMemo = async (memo, maybeRead, packageLocation) => {
|
|
|
145
126
|
};
|
|
146
127
|
|
|
147
128
|
/**
|
|
148
|
-
*
|
|
129
|
+
* Compares `logicalPath` to the current best logical path in `preferredPackageLogicalPathMap` for `packageLocation`.
|
|
130
|
+
*
|
|
131
|
+
* If no current best path exists, it returns `logicalPath`.
|
|
132
|
+
*
|
|
133
|
+
* @template {string[]} T
|
|
134
|
+
* @template {string[]} U
|
|
135
|
+
* @param {T} logicalPath
|
|
149
136
|
* @param {string} packageLocation
|
|
150
|
-
* @
|
|
137
|
+
* @param {Map<string, U>} preferredPackageLogicalPathMap
|
|
138
|
+
* @returns {T|U}
|
|
151
139
|
*/
|
|
140
|
+
const currentBestLogicalPath = (
|
|
141
|
+
logicalPath,
|
|
142
|
+
packageLocation,
|
|
143
|
+
preferredPackageLogicalPathMap,
|
|
144
|
+
) => {
|
|
145
|
+
const theCurrentBest = preferredPackageLogicalPathMap.get(packageLocation);
|
|
146
|
+
if (theCurrentBest === undefined) {
|
|
147
|
+
return logicalPath;
|
|
148
|
+
}
|
|
149
|
+
return pathCompare(logicalPath, theCurrentBest) < 0
|
|
150
|
+
? logicalPath
|
|
151
|
+
: theCurrentBest;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Updates the shortest paths in a subgraph of `graph` starting with `packageLocation`.
|
|
156
|
+
*
|
|
157
|
+
* This should be called upon the second (and each subsequent) visit to a graph node.
|
|
158
|
+
*
|
|
159
|
+
* @param {Graph} graph Graph
|
|
160
|
+
* @param {string} packageLocation Location of the package to start with
|
|
161
|
+
* @param {string[]} logicalPath Current path parts of the same package
|
|
162
|
+
* @param {Map<string, string[]>} [preferredPackageLogicalPathMap] Mapping of shortest known paths for each package location
|
|
163
|
+
* @returns {void}
|
|
164
|
+
*/
|
|
165
|
+
const updateShortestPaths = (
|
|
166
|
+
graph,
|
|
167
|
+
packageLocation,
|
|
168
|
+
logicalPath,
|
|
169
|
+
preferredPackageLogicalPathMap = new Map(),
|
|
170
|
+
) => {
|
|
171
|
+
const node = graph[packageLocation];
|
|
172
|
+
if (!node) {
|
|
173
|
+
throw new ReferenceError(
|
|
174
|
+
`Cannot find package at ${packageLocation} in graph`,
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const bestLogicalPath = currentBestLogicalPath(
|
|
179
|
+
logicalPath,
|
|
180
|
+
packageLocation,
|
|
181
|
+
preferredPackageLogicalPathMap,
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
if (bestLogicalPath === logicalPath) {
|
|
185
|
+
preferredPackageLogicalPathMap.set(packageLocation, bestLogicalPath);
|
|
186
|
+
|
|
187
|
+
for (const name of keys(node.dependencyLocations).sort()) {
|
|
188
|
+
const packageLocation = node.dependencyLocations[name];
|
|
189
|
+
if (!packageLocation) {
|
|
190
|
+
// "should never happen"
|
|
191
|
+
throw new ReferenceError(
|
|
192
|
+
`Expected graph node ${q(node.name)} to contain a dependency location for ${q(name)}`,
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
updateShortestPaths(
|
|
196
|
+
graph,
|
|
197
|
+
packageLocation,
|
|
198
|
+
[...logicalPath, name],
|
|
199
|
+
preferredPackageLogicalPathMap,
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
152
203
|
|
|
204
|
+
// a path length of 0 means the node represents the eventual entry compartment.
|
|
205
|
+
// we do not want to mess with that path.
|
|
206
|
+
if (node.path.length && node.path !== bestLogicalPath) {
|
|
207
|
+
node.path = bestLogicalPath;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return undefined;
|
|
211
|
+
};
|
|
153
212
|
/**
|
|
154
|
-
* findPackage behaves as Node.js to find third-party modules by searching
|
|
213
|
+
* `findPackage` behaves as Node.js to find third-party modules by searching
|
|
155
214
|
* parent to ancestor directories for a `node_modules` directory that contains
|
|
156
215
|
* the name.
|
|
216
|
+
*
|
|
157
217
|
* Node.js does not actually require these to be packages, but in practice,
|
|
158
|
-
* these are the locations that
|
|
218
|
+
* these are the locations that package managers drop a package so Node.js can
|
|
159
219
|
* find it efficiently.
|
|
160
220
|
*
|
|
161
221
|
* @param {ReadDescriptorFn} readDescriptor
|
|
162
222
|
* @param {CanonicalFn} canonical
|
|
163
223
|
* @param {string} directory
|
|
164
224
|
* @param {string} name
|
|
165
|
-
* @returns {Promise<
|
|
166
|
-
* packageLocation: string,
|
|
167
|
-
* packageDescriptor: object,
|
|
168
|
-
* } | undefined>}
|
|
225
|
+
* @returns {Promise<PackageDetails|undefined>}
|
|
169
226
|
*/
|
|
170
227
|
const findPackage = async (readDescriptor, canonical, directory, name) => {
|
|
171
228
|
await null;
|
|
@@ -198,6 +255,7 @@ const findPackage = async (readDescriptor, canonical, directory, name) => {
|
|
|
198
255
|
}
|
|
199
256
|
};
|
|
200
257
|
|
|
258
|
+
/** @satisfies {LanguageForExtension} */
|
|
201
259
|
const defaultLanguageForExtension = /** @type {const} */ ({
|
|
202
260
|
mjs: 'mjs',
|
|
203
261
|
cjs: 'cjs',
|
|
@@ -205,15 +263,19 @@ const defaultLanguageForExtension = /** @type {const} */ ({
|
|
|
205
263
|
text: 'text',
|
|
206
264
|
bytes: 'bytes',
|
|
207
265
|
});
|
|
266
|
+
|
|
267
|
+
/** @satisfies {LanguageForExtension} */
|
|
208
268
|
const defaultCommonjsLanguageForExtension = /** @type {const} */ ({
|
|
209
269
|
js: 'cjs',
|
|
210
270
|
});
|
|
271
|
+
|
|
272
|
+
/** @satisfies {LanguageForExtension} */
|
|
211
273
|
const defaultModuleLanguageForExtension = /** @type {const} */ ({
|
|
212
274
|
js: 'mjs',
|
|
213
275
|
});
|
|
214
276
|
|
|
215
277
|
/**
|
|
216
|
-
* @param {
|
|
278
|
+
* @param {PackageDescriptor} descriptor
|
|
217
279
|
* @param {string} location
|
|
218
280
|
* @param {LanguageOptions} languageOptions
|
|
219
281
|
* @returns {Record<string, string>}
|
|
@@ -278,7 +340,7 @@ const inferParsers = (descriptor, location, languageOptions) => {
|
|
|
278
340
|
};
|
|
279
341
|
|
|
280
342
|
/**
|
|
281
|
-
* graphPackage and gatherDependency are mutually recursive functions that
|
|
343
|
+
* `graphPackage` and {@link gatherDependency} are mutually recursive functions that
|
|
282
344
|
* gather the metadata for a package and its transitive dependencies.
|
|
283
345
|
* The keys of the graph are the locations of the package descriptors.
|
|
284
346
|
* The metadata include a label (which is informative and not necessarily
|
|
@@ -289,16 +351,12 @@ const inferParsers = (descriptor, location, languageOptions) => {
|
|
|
289
351
|
* @param {ReadDescriptorFn} readDescriptor
|
|
290
352
|
* @param {CanonicalFn} canonical
|
|
291
353
|
* @param {Graph} graph
|
|
292
|
-
* @param {
|
|
293
|
-
* @param {string} packageDetails.packageLocation
|
|
294
|
-
* @param {object} packageDetails.packageDescriptor
|
|
354
|
+
* @param {PackageDetails} packageDetails
|
|
295
355
|
* @param {Set<string>} conditions
|
|
296
356
|
* @param {boolean | undefined} dev
|
|
297
|
-
* @param {CommonDependencyDescriptors} commonDependencyDescriptors
|
|
298
357
|
* @param {LanguageOptions} languageOptions
|
|
299
358
|
* @param {boolean} strict
|
|
300
|
-
* @param {
|
|
301
|
-
* @param {Array<string>} logicalPath
|
|
359
|
+
* @param {GraphPackageOptions} options
|
|
302
360
|
* @returns {Promise<undefined>}
|
|
303
361
|
*/
|
|
304
362
|
const graphPackage = async (
|
|
@@ -309,34 +367,56 @@ const graphPackage = async (
|
|
|
309
367
|
{ packageLocation, packageDescriptor },
|
|
310
368
|
conditions,
|
|
311
369
|
dev,
|
|
312
|
-
commonDependencyDescriptors,
|
|
313
370
|
languageOptions,
|
|
314
371
|
strict,
|
|
315
|
-
|
|
316
|
-
|
|
372
|
+
{
|
|
373
|
+
commonDependencyDescriptors = {},
|
|
374
|
+
preferredPackageLogicalPathMap = new Map(),
|
|
375
|
+
logicalPath = [],
|
|
376
|
+
log = noop,
|
|
377
|
+
} = {},
|
|
317
378
|
) => {
|
|
318
379
|
if (graph[packageLocation] !== undefined) {
|
|
380
|
+
updateShortestPaths(
|
|
381
|
+
graph,
|
|
382
|
+
packageLocation,
|
|
383
|
+
logicalPath,
|
|
384
|
+
preferredPackageLogicalPathMap,
|
|
385
|
+
);
|
|
386
|
+
|
|
319
387
|
// Returning the promise here would create a causal cycle and stall recursion.
|
|
320
388
|
return undefined;
|
|
321
389
|
}
|
|
322
390
|
|
|
323
391
|
if (packageDescriptor.name !== name) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
)})`,
|
|
330
|
-
);
|
|
392
|
+
log('Package name does not match location', {
|
|
393
|
+
name,
|
|
394
|
+
packageDescriptorName: packageDescriptor.name,
|
|
395
|
+
packageLocation,
|
|
396
|
+
});
|
|
331
397
|
}
|
|
332
398
|
|
|
333
|
-
const result = {};
|
|
334
|
-
graph[packageLocation] =
|
|
399
|
+
const result = /** @type {Node} */ ({});
|
|
400
|
+
graph[packageLocation] = result;
|
|
335
401
|
|
|
336
|
-
/** @type {
|
|
402
|
+
/** @type {Node['dependencyLocations']} */
|
|
337
403
|
const dependencyLocations = {};
|
|
404
|
+
/** @type {ReturnType<typeof gatherDependency>[]} */
|
|
338
405
|
const children = [];
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* A set containing dependency names which are considered "optional"
|
|
409
|
+
*/
|
|
339
410
|
const optionals = new Set();
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Contains the names of _all_ dependencies
|
|
414
|
+
*
|
|
415
|
+
* @type {Set<string>}
|
|
416
|
+
*/
|
|
417
|
+
const allDependencies = new Set();
|
|
418
|
+
|
|
419
|
+
// these are fields from package.json containing dependencies
|
|
340
420
|
const {
|
|
341
421
|
dependencies = {},
|
|
342
422
|
peerDependencies = {},
|
|
@@ -345,32 +425,40 @@ const graphPackage = async (
|
|
|
345
425
|
optionalDependencies = {},
|
|
346
426
|
devDependencies = {},
|
|
347
427
|
} = packageDescriptor;
|
|
348
|
-
|
|
349
|
-
for (const [name, descriptor] of
|
|
350
|
-
commonDependencyDescriptors,
|
|
351
|
-
)) {
|
|
428
|
+
|
|
429
|
+
for (const [name, descriptor] of entries(commonDependencyDescriptors)) {
|
|
352
430
|
if (Object(descriptor) === descriptor) {
|
|
353
|
-
|
|
354
|
-
allDependencies[name] = spec;
|
|
431
|
+
allDependencies.add(name);
|
|
355
432
|
}
|
|
356
433
|
}
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
for (const
|
|
434
|
+
|
|
435
|
+
// only consider devDependencies if dev flag is true
|
|
436
|
+
for (const name of keys({
|
|
437
|
+
...dependencies,
|
|
438
|
+
...peerDependencies,
|
|
439
|
+
...bundleDependencies,
|
|
440
|
+
...optionalDependencies,
|
|
441
|
+
...(dev ? devDependencies : {}),
|
|
442
|
+
})) {
|
|
443
|
+
allDependencies.add(name);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// for historical reasons, some packages omit peerDependencies and only
|
|
447
|
+
// use the peerDependenciesMeta field (because there was no way to define
|
|
448
|
+
// an "optional" peerDependency prior to npm v7). this is plainly wrong,
|
|
449
|
+
// but not exactly rare, either
|
|
450
|
+
for (const [name, meta] of entries(peerDependenciesMeta)) {
|
|
360
451
|
if (Object(meta) === meta && meta.optional) {
|
|
361
452
|
optionals.add(name);
|
|
453
|
+
allDependencies.add(name);
|
|
362
454
|
}
|
|
363
455
|
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
for (const name of Object.keys(optionalDependencies)) {
|
|
456
|
+
|
|
457
|
+
for (const name of keys(optionalDependencies)) {
|
|
367
458
|
optionals.add(name);
|
|
368
459
|
}
|
|
369
|
-
if (dev) {
|
|
370
|
-
assign(allDependencies, devDependencies);
|
|
371
|
-
}
|
|
372
460
|
|
|
373
|
-
for (const name of
|
|
461
|
+
for (const name of [...allDependencies].sort()) {
|
|
374
462
|
const optional = optionals.has(name);
|
|
375
463
|
const childLogicalPath = [...logicalPath, name];
|
|
376
464
|
children.push(
|
|
@@ -387,17 +475,24 @@ const graphPackage = async (
|
|
|
387
475
|
preferredPackageLogicalPathMap,
|
|
388
476
|
languageOptions,
|
|
389
477
|
strict,
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
478
|
+
{
|
|
479
|
+
childLogicalPath,
|
|
480
|
+
optional,
|
|
481
|
+
commonDependencyDescriptors,
|
|
482
|
+
log,
|
|
483
|
+
},
|
|
393
484
|
),
|
|
394
485
|
);
|
|
395
486
|
}
|
|
396
487
|
|
|
397
488
|
const { version = '', exports: exportsDescriptor } = packageDescriptor;
|
|
398
|
-
/** @type {
|
|
489
|
+
/** @type {Node['types']} */
|
|
399
490
|
const types = {};
|
|
400
491
|
|
|
492
|
+
/**
|
|
493
|
+
* @param {string} path
|
|
494
|
+
* @returns {Promise<PackageDescriptor>}
|
|
495
|
+
*/
|
|
401
496
|
const readDescriptorUpwards = async path => {
|
|
402
497
|
const location = resolveLocation(path, packageLocation);
|
|
403
498
|
// readDescriptor coming from above is memoized, so this is not awfully slow
|
|
@@ -405,9 +500,9 @@ const graphPackage = async (
|
|
|
405
500
|
return data;
|
|
406
501
|
};
|
|
407
502
|
|
|
408
|
-
/** @type {
|
|
503
|
+
/** @type {Node['externalAliases']} */
|
|
409
504
|
const externalAliases = {};
|
|
410
|
-
/** @type {
|
|
505
|
+
/** @type {Node['internalAliases']} */
|
|
411
506
|
const internalAliases = {};
|
|
412
507
|
|
|
413
508
|
inferExportsAndAliases(
|
|
@@ -424,10 +519,13 @@ const graphPackage = async (
|
|
|
424
519
|
languageOptions,
|
|
425
520
|
);
|
|
426
521
|
|
|
427
|
-
|
|
522
|
+
const sourceDirname = basename(packageLocation);
|
|
523
|
+
|
|
524
|
+
assign(result, {
|
|
428
525
|
name,
|
|
429
526
|
path: logicalPath,
|
|
430
527
|
label: `${name}${version ? `-v${version}` : ''}`,
|
|
528
|
+
sourceDirname,
|
|
431
529
|
explicitExports: exportsDescriptor !== undefined,
|
|
432
530
|
externalAliases,
|
|
433
531
|
internalAliases,
|
|
@@ -448,7 +546,7 @@ const graphPackage = async (
|
|
|
448
546
|
await Promise.all(children);
|
|
449
547
|
|
|
450
548
|
// handle commonDependencyDescriptors package aliases
|
|
451
|
-
for (const [name, { alias }] of
|
|
549
|
+
for (const [name, { alias }] of entries(commonDependencyDescriptors)) {
|
|
452
550
|
// update the dependencyLocations to point to the common dependency
|
|
453
551
|
const targetLocation = dependencyLocations[name];
|
|
454
552
|
if (targetLocation === undefined) {
|
|
@@ -479,6 +577,8 @@ const graphPackage = async (
|
|
|
479
577
|
};
|
|
480
578
|
|
|
481
579
|
/**
|
|
580
|
+
* Adds information for the dependency of the package at `packageLocation` to the `graph` object.
|
|
581
|
+
*
|
|
482
582
|
* @param {ReadDescriptorFn} readDescriptor
|
|
483
583
|
* @param {CanonicalFn} canonical
|
|
484
584
|
* @param {Graph} graph - the partially build graph.
|
|
@@ -488,10 +588,9 @@ const graphPackage = async (
|
|
|
488
588
|
* @param {Set<string>} conditions
|
|
489
589
|
* @param {Map<string, Array<string>>} preferredPackageLogicalPathMap
|
|
490
590
|
* @param {LanguageOptions} languageOptions
|
|
491
|
-
* @param {boolean} strict
|
|
492
|
-
* @param {
|
|
493
|
-
* @
|
|
494
|
-
* @param {object} [commonDependencyDescriptors] - dependencies to be added to all packages
|
|
591
|
+
* @param {boolean} strict - If `true`, a missing dependency will throw an exception
|
|
592
|
+
* @param {GatherDependencyOptions} options
|
|
593
|
+
* @returns {Promise<void>}
|
|
495
594
|
*/
|
|
496
595
|
const gatherDependency = async (
|
|
497
596
|
readDescriptor,
|
|
@@ -504,9 +603,12 @@ const gatherDependency = async (
|
|
|
504
603
|
preferredPackageLogicalPathMap,
|
|
505
604
|
languageOptions,
|
|
506
605
|
strict,
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
606
|
+
{
|
|
607
|
+
childLogicalPath = [],
|
|
608
|
+
optional = false,
|
|
609
|
+
commonDependencyDescriptors = {},
|
|
610
|
+
log = noop,
|
|
611
|
+
} = {},
|
|
510
612
|
) => {
|
|
511
613
|
const dependency = await findPackage(
|
|
512
614
|
readDescriptor,
|
|
@@ -522,15 +624,20 @@ const gatherDependency = async (
|
|
|
522
624
|
throw Error(`Cannot find dependency ${name} for ${packageLocation}`);
|
|
523
625
|
}
|
|
524
626
|
dependencyLocations[name] = dependency.packageLocation;
|
|
525
|
-
|
|
627
|
+
|
|
628
|
+
const bestLogicalPath = currentBestLogicalPath(
|
|
629
|
+
childLogicalPath,
|
|
526
630
|
dependency.packageLocation,
|
|
631
|
+
preferredPackageLogicalPathMap,
|
|
527
632
|
);
|
|
528
|
-
|
|
633
|
+
|
|
634
|
+
if (bestLogicalPath === childLogicalPath) {
|
|
529
635
|
preferredPackageLogicalPathMap.set(
|
|
530
636
|
dependency.packageLocation,
|
|
531
|
-
|
|
637
|
+
bestLogicalPath,
|
|
532
638
|
);
|
|
533
639
|
}
|
|
640
|
+
|
|
534
641
|
await graphPackage(
|
|
535
642
|
name,
|
|
536
643
|
readDescriptor,
|
|
@@ -539,34 +646,35 @@ const gatherDependency = async (
|
|
|
539
646
|
dependency,
|
|
540
647
|
conditions,
|
|
541
648
|
false,
|
|
542
|
-
commonDependencyDescriptors,
|
|
543
649
|
languageOptions,
|
|
544
650
|
strict,
|
|
545
|
-
|
|
546
|
-
|
|
651
|
+
{
|
|
652
|
+
commonDependencyDescriptors,
|
|
653
|
+
preferredPackageLogicalPathMap,
|
|
654
|
+
logicalPath: childLogicalPath,
|
|
655
|
+
log,
|
|
656
|
+
},
|
|
547
657
|
);
|
|
548
658
|
};
|
|
549
659
|
|
|
550
660
|
/**
|
|
551
|
-
*
|
|
552
|
-
*
|
|
553
|
-
* as ${name}@${version}), dependencies: (a list of URLs), and exports: (an
|
|
554
|
-
* object whose keys are the thing being imported, and the values are the names
|
|
555
|
-
* of the matching module, relative to the containing package's root, that is,
|
|
556
|
-
* the URL that was used as the key of graph).
|
|
557
|
-
* The URLs in dependencies will all exist as other keys of graph.
|
|
661
|
+
* Resolves with a {@link Graph} representing the packages for which
|
|
662
|
+
* {@link CompartmentDescriptor CompartmentDescriptors} will be created.
|
|
558
663
|
*
|
|
559
664
|
* @param {MaybeReadFn} maybeRead
|
|
560
665
|
* @param {CanonicalFn} canonical
|
|
561
666
|
* @param {string} packageLocation - location of the main package.
|
|
562
667
|
* @param {Set<string>} conditions
|
|
563
|
-
* @param {
|
|
564
|
-
* package.json
|
|
565
|
-
*
|
|
566
|
-
*
|
|
567
|
-
*
|
|
668
|
+
* @param {PackageDescriptor} mainPackageDescriptor - the parsed contents of the
|
|
669
|
+
* main `package.json`, which was already read when searching for the
|
|
670
|
+
* `package.json`.
|
|
671
|
+
* @param {boolean|undefined} dev - whether to use devDependencies from this
|
|
672
|
+
* package (and only this package).
|
|
673
|
+
* @param {Record<string,string>} commonDependencies - dependencies to be added
|
|
674
|
+
* to all packages
|
|
568
675
|
* @param {LanguageOptions} languageOptions
|
|
569
676
|
* @param {boolean} strict
|
|
677
|
+
* @param {GraphPackagesOptions} options
|
|
570
678
|
*/
|
|
571
679
|
const graphPackages = async (
|
|
572
680
|
maybeRead,
|
|
@@ -578,11 +686,12 @@ const graphPackages = async (
|
|
|
578
686
|
commonDependencies,
|
|
579
687
|
languageOptions,
|
|
580
688
|
strict,
|
|
689
|
+
{ log = noop } = {},
|
|
581
690
|
) => {
|
|
582
691
|
const memo = create(null);
|
|
583
692
|
/**
|
|
584
693
|
* @param {string} packageLocation
|
|
585
|
-
* @returns {Promise<
|
|
694
|
+
* @returns {Promise<PackageDescriptor>}
|
|
586
695
|
*/
|
|
587
696
|
const readDescriptor = packageLocation =>
|
|
588
697
|
readDescriptorWithMemo(memo, maybeRead, packageLocation);
|
|
@@ -608,7 +717,7 @@ const graphPackages = async (
|
|
|
608
717
|
/** @type {CommonDependencyDescriptors} */
|
|
609
718
|
const commonDependencyDescriptors = {};
|
|
610
719
|
const packageDescriptorDependencies = packageDescriptor.dependencies || {};
|
|
611
|
-
for (const [alias, dependencyName] of
|
|
720
|
+
for (const [alias, dependencyName] of entries(commonDependencies)) {
|
|
612
721
|
const spec = packageDescriptorDependencies[dependencyName];
|
|
613
722
|
if (spec === undefined) {
|
|
614
723
|
throw Error(
|
|
@@ -633,16 +742,19 @@ const graphPackages = async (
|
|
|
633
742
|
},
|
|
634
743
|
conditions,
|
|
635
744
|
dev,
|
|
636
|
-
commonDependencyDescriptors,
|
|
637
745
|
languageOptions,
|
|
638
746
|
strict,
|
|
747
|
+
{
|
|
748
|
+
commonDependencyDescriptors,
|
|
749
|
+
log,
|
|
750
|
+
},
|
|
639
751
|
);
|
|
640
752
|
return graph;
|
|
641
753
|
};
|
|
642
754
|
|
|
643
755
|
/**
|
|
644
|
-
* translateGraph converts the graph returned by graph packages (above) into a
|
|
645
|
-
* compartment map.
|
|
756
|
+
* `translateGraph` converts the graph returned by graph packages (above) into a
|
|
757
|
+
* {@link CompartmentMapDescriptor compartment map}.
|
|
646
758
|
*
|
|
647
759
|
* @param {string} entryPackageLocation
|
|
648
760
|
* @param {string} entryModuleSpecifier
|
|
@@ -659,8 +771,8 @@ const translateGraph = (
|
|
|
659
771
|
conditions,
|
|
660
772
|
policy,
|
|
661
773
|
) => {
|
|
662
|
-
/** @type {
|
|
663
|
-
const compartments =
|
|
774
|
+
/** @type {CompartmentMapDescriptor['compartments']} */
|
|
775
|
+
const compartments = create(null);
|
|
664
776
|
|
|
665
777
|
// For each package, build a map of all the external modules the package can
|
|
666
778
|
// import from other packages.
|
|
@@ -676,15 +788,16 @@ const translateGraph = (
|
|
|
676
788
|
name,
|
|
677
789
|
path,
|
|
678
790
|
label,
|
|
791
|
+
sourceDirname,
|
|
679
792
|
dependencyLocations,
|
|
680
793
|
internalAliases,
|
|
681
794
|
parsers,
|
|
682
795
|
types,
|
|
683
796
|
} = graph[dependeeLocation];
|
|
684
|
-
/** @type {
|
|
685
|
-
const moduleDescriptors =
|
|
686
|
-
/** @type {
|
|
687
|
-
const scopes =
|
|
797
|
+
/** @type {CompartmentDescriptor['modules']} */
|
|
798
|
+
const moduleDescriptors = create(null);
|
|
799
|
+
/** @type {CompartmentDescriptor['scopes']} */
|
|
800
|
+
const scopes = create(null);
|
|
688
801
|
|
|
689
802
|
/**
|
|
690
803
|
* List of all the compartments (by name) that this compartment can import from.
|
|
@@ -770,6 +883,7 @@ const translateGraph = (
|
|
|
770
883
|
name,
|
|
771
884
|
path,
|
|
772
885
|
location: dependeeLocation,
|
|
886
|
+
sourceDirname,
|
|
773
887
|
modules: moduleDescriptors,
|
|
774
888
|
scopes,
|
|
775
889
|
parsers,
|
|
@@ -843,10 +957,10 @@ const makeLanguageOptions = ({
|
|
|
843
957
|
};
|
|
844
958
|
|
|
845
959
|
const languages = new Set([
|
|
846
|
-
...
|
|
847
|
-
...
|
|
848
|
-
...
|
|
849
|
-
...
|
|
960
|
+
...values(moduleLanguageForExtension),
|
|
961
|
+
...values(commonjsLanguageForExtension),
|
|
962
|
+
...values(workspaceModuleLanguageForExtension),
|
|
963
|
+
...values(workspaceCommonjsLanguageForExtension),
|
|
850
964
|
...additionalLanguages,
|
|
851
965
|
]);
|
|
852
966
|
|
|
@@ -863,10 +977,11 @@ const makeLanguageOptions = ({
|
|
|
863
977
|
* @param {ReadFn | ReadPowers | MaybeReadPowers} readPowers
|
|
864
978
|
* @param {string} packageLocation
|
|
865
979
|
* @param {Set<string>} conditionsOption
|
|
866
|
-
* @param {
|
|
980
|
+
* @param {PackageDescriptor} packageDescriptor
|
|
867
981
|
* @param {string} moduleSpecifier
|
|
868
982
|
* @param {CompartmentMapForNodeModulesOptions} [options]
|
|
869
983
|
* @returns {Promise<CompartmentMapDescriptor>}
|
|
984
|
+
* @deprecated Use {@link mapNodeModules} instead.
|
|
870
985
|
*/
|
|
871
986
|
export const compartmentMapForNodeModules = async (
|
|
872
987
|
readPowers,
|
|
@@ -881,6 +996,7 @@ export const compartmentMapForNodeModules = async (
|
|
|
881
996
|
commonDependencies = {},
|
|
882
997
|
policy,
|
|
883
998
|
strict = false,
|
|
999
|
+
log = noop,
|
|
884
1000
|
} = options;
|
|
885
1001
|
const { maybeRead, canonical } = unpackReadPowers(readPowers);
|
|
886
1002
|
const languageOptions = makeLanguageOptions(options);
|
|
@@ -902,6 +1018,7 @@ export const compartmentMapForNodeModules = async (
|
|
|
902
1018
|
commonDependencies,
|
|
903
1019
|
languageOptions,
|
|
904
1020
|
strict,
|
|
1021
|
+
{ log },
|
|
905
1022
|
);
|
|
906
1023
|
|
|
907
1024
|
if (policy) {
|
|
@@ -932,6 +1049,11 @@ export const compartmentMapForNodeModules = async (
|
|
|
932
1049
|
};
|
|
933
1050
|
|
|
934
1051
|
/**
|
|
1052
|
+
* Creates a {@link CompartmentMapDescriptor} from the module at
|
|
1053
|
+
* `moduleLocation`, considering dependencies found in `node_modules`.
|
|
1054
|
+
*
|
|
1055
|
+
* Locates the {@link PackageDescriptor} for the module at `moduleLocation`
|
|
1056
|
+
*
|
|
935
1057
|
* @param {ReadFn | ReadPowers | MaybeReadPowers} readPowers
|
|
936
1058
|
* @param {string} moduleLocation
|
|
937
1059
|
* @param {MapNodeModulesOptions} [options]
|
|
@@ -940,20 +1062,17 @@ export const compartmentMapForNodeModules = async (
|
|
|
940
1062
|
export const mapNodeModules = async (
|
|
941
1063
|
readPowers,
|
|
942
1064
|
moduleLocation,
|
|
943
|
-
|
|
1065
|
+
{ tags = new Set(), conditions = tags, log = noop, ...otherOptions } = {},
|
|
944
1066
|
) => {
|
|
945
|
-
const { tags = new Set(), conditions = tags, ...otherOptions } = options;
|
|
946
|
-
|
|
947
1067
|
const {
|
|
948
1068
|
packageLocation,
|
|
949
1069
|
packageDescriptorText,
|
|
950
1070
|
packageDescriptorLocation,
|
|
951
1071
|
moduleSpecifier,
|
|
952
|
-
} = await search(readPowers, moduleLocation);
|
|
1072
|
+
} = await search(readPowers, moduleLocation, { log });
|
|
953
1073
|
|
|
954
|
-
const packageDescriptor =
|
|
955
|
-
packageDescriptorText,
|
|
956
|
-
packageDescriptorLocation,
|
|
1074
|
+
const packageDescriptor = /** @type {PackageDescriptor} */ (
|
|
1075
|
+
parseLocatedJson(packageDescriptorText, packageDescriptorLocation)
|
|
957
1076
|
);
|
|
958
1077
|
|
|
959
1078
|
return compartmentMapForNodeModules(
|
|
@@ -962,6 +1081,6 @@ export const mapNodeModules = async (
|
|
|
962
1081
|
conditions,
|
|
963
1082
|
packageDescriptor,
|
|
964
1083
|
moduleSpecifier,
|
|
965
|
-
otherOptions,
|
|
1084
|
+
{ log, ...otherOptions },
|
|
966
1085
|
);
|
|
967
1086
|
};
|