bare-module-traverse 1.2.5 → 1.3.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/README.md +85 -15
- package/index.js +259 -120
- package/lib/errors.js +20 -8
- package/lib/resolve/bare.js +20 -11
- package/lib/resolve/node.js +21 -9
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -10,36 +10,44 @@ npm i bare-module-traverse
|
|
|
10
10
|
|
|
11
11
|
For synchronous traversal:
|
|
12
12
|
|
|
13
|
-
```
|
|
13
|
+
```js
|
|
14
14
|
const traverse = require('bare-module-traverse')
|
|
15
15
|
|
|
16
|
-
function readModule
|
|
16
|
+
function readModule(url) {
|
|
17
17
|
// Read `url` if it exists, otherwise `null`
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
function
|
|
20
|
+
function* listPrefix(url) {
|
|
21
21
|
// Yield URLs that have `url` as a prefix. The list may be empty.
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
for (const dependency of traverse(
|
|
24
|
+
for (const dependency of traverse(
|
|
25
|
+
new URL('file:///directory/file.js'),
|
|
26
|
+
readModule,
|
|
27
|
+
listPrefix
|
|
28
|
+
)) {
|
|
25
29
|
console.log(dependency)
|
|
26
30
|
}
|
|
27
31
|
```
|
|
28
32
|
|
|
29
33
|
For asynchronous traversal:
|
|
30
34
|
|
|
31
|
-
```
|
|
35
|
+
```js
|
|
32
36
|
const traverse = require('bare-module-traverse')
|
|
33
37
|
|
|
34
|
-
async function readModule
|
|
38
|
+
async function readModule(url) {
|
|
35
39
|
// Read `url` if it exists, otherwise `null`
|
|
36
40
|
}
|
|
37
41
|
|
|
38
|
-
async function
|
|
42
|
+
async function* listPrefix(url) {
|
|
39
43
|
// Yield URLs that have `url` as a prefix. The list may be empty.
|
|
40
44
|
}
|
|
41
45
|
|
|
42
|
-
for await (const dependency of traverse(
|
|
46
|
+
for await (const dependency of traverse(
|
|
47
|
+
new URL('file:///directory/file.js'),
|
|
48
|
+
readModule,
|
|
49
|
+
listPrefix
|
|
50
|
+
)) {
|
|
43
51
|
console.log(dependency)
|
|
44
52
|
}
|
|
45
53
|
```
|
|
@@ -53,7 +61,7 @@ Traverse the module graph rooted at `url`, which must be a WHATWG `URL` instance
|
|
|
53
61
|
Options include:
|
|
54
62
|
|
|
55
63
|
```js
|
|
56
|
-
{
|
|
64
|
+
options = {
|
|
57
65
|
resolve: resolve.default
|
|
58
66
|
}
|
|
59
67
|
```
|
|
@@ -65,7 +73,7 @@ Options supported by <https://github.com/holepunchto/bare-module-resolve> and <h
|
|
|
65
73
|
Synchronously iterate the module graph. Each yielded dependency has the following shape:
|
|
66
74
|
|
|
67
75
|
```js
|
|
68
|
-
{
|
|
76
|
+
dependency = {
|
|
69
77
|
url: URL,
|
|
70
78
|
source: 'string' | Buffer, // Source as returned by `readModule()`
|
|
71
79
|
imports: {
|
|
@@ -80,6 +88,8 @@ Asynchronously iterate the module graph. If `readModule` returns a promise or `l
|
|
|
80
88
|
|
|
81
89
|
### Resolution
|
|
82
90
|
|
|
91
|
+
Module and addon resolution is configurable by providing a resolver function. A resolver function is a generator function that yields values matching the shapes defined by <https://github.com/holepunchto/bare-module-resolve#algorithm>. Several resolvers are provided out of the box to support the most common use cases.
|
|
92
|
+
|
|
83
93
|
#### `resolve.module`
|
|
84
94
|
|
|
85
95
|
Convenience export from <https://github.com/holepunchto/bare-module-resolve>.
|
|
@@ -94,15 +104,73 @@ The default resolver, which simply forwards to <https://github.com/holepunchto/b
|
|
|
94
104
|
|
|
95
105
|
#### `resolve.bare`
|
|
96
106
|
|
|
97
|
-
The Bare resolver, which matches the options used by the Bare module system.
|
|
107
|
+
The Bare resolver, which matches the options used by the Bare module system. The resolver accepts the following additional options:
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
options = {
|
|
111
|
+
platform: Bare.platform,
|
|
112
|
+
arch: Bare.arch,
|
|
113
|
+
simulator: false,
|
|
114
|
+
host: `${platform}-${arch}${simulator ? '-simulator' : ''}`,
|
|
115
|
+
target: [host]
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
For single target traversal it is sufficient to pass `platform`, `arch`, `simulator`, and/or `host`. For multi target target traversal pass a list of `target` identifiers instead.
|
|
98
120
|
|
|
99
121
|
#### `resolve.node`
|
|
100
122
|
|
|
101
|
-
The Node.js resolver, which matches the options used by the Node.js module system.
|
|
123
|
+
The Node.js resolver, which matches the options used by the Node.js module system. The resolver accepts the following additional options:
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
options = {
|
|
127
|
+
platform: process.platform,
|
|
128
|
+
arch: process.arch,
|
|
129
|
+
simulator: false,
|
|
130
|
+
host: `${platform}-${arch}${simulator ? '-simulator' : ''}`,
|
|
131
|
+
target: [host]
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
For single target traversal it is sufficient to pass `platform`, `arch`, `simulator`, and/or `host`. For multi target target traversal pass a list of `target` identifiers instead.
|
|
102
136
|
|
|
103
137
|
### Algorithm
|
|
104
138
|
|
|
105
|
-
The following generator functions implement the traversal algorithm.
|
|
139
|
+
The following generator functions implement the traversal algorithm. The yielded values have the following shape:
|
|
140
|
+
|
|
141
|
+
**Source module**
|
|
142
|
+
|
|
143
|
+
```js
|
|
144
|
+
next.value = {
|
|
145
|
+
module: URL
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**File prefix**
|
|
150
|
+
|
|
151
|
+
```js
|
|
152
|
+
next.value = {
|
|
153
|
+
prefix: URL
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Dependency subgraph**
|
|
158
|
+
|
|
159
|
+
```js
|
|
160
|
+
next.value = {
|
|
161
|
+
children: URL
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Dependency node**
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
next.value = {
|
|
169
|
+
dependency: URL
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
To drive the generator functions, a loop like the following can be used:
|
|
106
174
|
|
|
107
175
|
```js
|
|
108
176
|
const queue = [traverse.module(url, source, artifacts, visited)]
|
|
@@ -116,11 +184,13 @@ while (queue.length > 0) {
|
|
|
116
184
|
const value = next.value
|
|
117
185
|
|
|
118
186
|
if (value.module) {
|
|
119
|
-
|
|
187
|
+
// Read `value.module` if it exists, otherwise `null`
|
|
188
|
+
let source
|
|
120
189
|
|
|
121
190
|
next = generator.next(source)
|
|
122
191
|
} else if (value.prefix) {
|
|
123
|
-
|
|
192
|
+
// List the modules that have `value.prefix` as a prefix
|
|
193
|
+
let modules
|
|
124
194
|
|
|
125
195
|
next = generator.next(modules)
|
|
126
196
|
} else {
|
package/index.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
const { lookupPackageScope } = require('bare-module-resolve')
|
|
1
|
+
const { lookupPackageScope, conditionMatches } = require('bare-module-resolve')
|
|
2
2
|
const { lookupPrebuildsScope } = require('bare-addon-resolve')
|
|
3
3
|
const lex = require('bare-module-lexer')
|
|
4
4
|
const resolve = require('./lib/resolve')
|
|
5
5
|
const errors = require('./lib/errors')
|
|
6
6
|
|
|
7
|
-
module.exports = exports = function traverse
|
|
7
|
+
module.exports = exports = function traverse(
|
|
8
|
+
entry,
|
|
9
|
+
opts,
|
|
10
|
+
readModule,
|
|
11
|
+
listPrefix
|
|
12
|
+
) {
|
|
8
13
|
if (typeof opts === 'function') {
|
|
9
14
|
listPrefix = readModule
|
|
10
15
|
readModule = opts
|
|
@@ -16,7 +21,7 @@ module.exports = exports = function traverse (entry, opts, readModule, listPrefi
|
|
|
16
21
|
}
|
|
17
22
|
|
|
18
23
|
return {
|
|
19
|
-
*
|
|
24
|
+
*[Symbol.iterator]() {
|
|
20
25
|
const artifacts = { addons: [], assets: [] }
|
|
21
26
|
|
|
22
27
|
const queue = [exports.module(entry, null, artifacts, new Set(), opts)]
|
|
@@ -51,7 +56,7 @@ module.exports = exports = function traverse (entry, opts, readModule, listPrefi
|
|
|
51
56
|
return artifacts
|
|
52
57
|
},
|
|
53
58
|
|
|
54
|
-
async *
|
|
59
|
+
async *[Symbol.asyncIterator]() {
|
|
55
60
|
const artifacts = { addons: [], assets: [] }
|
|
56
61
|
|
|
57
62
|
const queue = [exports.module(entry, null, artifacts, new Set(), opts)]
|
|
@@ -88,51 +93,11 @@ module.exports = exports = function traverse (entry, opts, readModule, listPrefi
|
|
|
88
93
|
}
|
|
89
94
|
}
|
|
90
95
|
|
|
91
|
-
function
|
|
92
|
-
|
|
93
|
-
function addURL (array, url) {
|
|
94
|
-
let lo = 0
|
|
95
|
-
let hi = array.length - 1
|
|
96
|
-
|
|
97
|
-
while (lo <= hi) {
|
|
98
|
-
const mid = lo + ((hi - lo) >> 1)
|
|
99
|
-
const found = array[mid]
|
|
100
|
-
|
|
101
|
-
if (found.href === url.href) return
|
|
102
|
-
|
|
103
|
-
if (found.href < url.href) {
|
|
104
|
-
lo = mid + 1
|
|
105
|
-
} else {
|
|
106
|
-
hi = mid - 1
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
array.splice(lo, 0, url)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function removeURL (array, url) {
|
|
114
|
-
let lo = 0
|
|
115
|
-
let hi = array.length - 1
|
|
116
|
-
|
|
117
|
-
while (lo <= hi) {
|
|
118
|
-
const mid = lo + ((hi - lo) >> 1)
|
|
119
|
-
const found = array[mid]
|
|
120
|
-
|
|
121
|
-
if (found.href === url.href) break
|
|
122
|
-
|
|
123
|
-
if (found.href < url.href) {
|
|
124
|
-
lo = mid + 1
|
|
125
|
-
} else {
|
|
126
|
-
hi = mid - 1
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (array[lo].href === url.href) array.splice(lo, 1)
|
|
131
|
-
}
|
|
96
|
+
function* defaultListPrefix() {}
|
|
132
97
|
|
|
133
98
|
exports.resolve = resolve
|
|
134
99
|
|
|
135
|
-
exports.module = function
|
|
100
|
+
exports.module = function* (url, source, artifacts, visited, opts = {}) {
|
|
136
101
|
const { resolutions = null } = opts
|
|
137
102
|
|
|
138
103
|
if (visited.has(url.href)) return false
|
|
@@ -148,7 +113,16 @@ exports.module = function * (url, source, artifacts, visited, opts = {}) {
|
|
|
148
113
|
visited.add(url.href)
|
|
149
114
|
|
|
150
115
|
if (resolutions) {
|
|
151
|
-
if (
|
|
116
|
+
if (
|
|
117
|
+
yield* exports.preresolved(
|
|
118
|
+
url,
|
|
119
|
+
source,
|
|
120
|
+
resolutions,
|
|
121
|
+
artifacts,
|
|
122
|
+
visited,
|
|
123
|
+
opts
|
|
124
|
+
)
|
|
125
|
+
) {
|
|
152
126
|
return true
|
|
153
127
|
}
|
|
154
128
|
}
|
|
@@ -161,18 +135,22 @@ exports.module = function * (url, source, artifacts, visited, opts = {}) {
|
|
|
161
135
|
if (source !== null) {
|
|
162
136
|
imports['#package'] = packageURL.href
|
|
163
137
|
|
|
164
|
-
yield {
|
|
138
|
+
yield {
|
|
139
|
+
children: exports.package(packageURL, source, artifacts, visited, opts)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
break
|
|
165
143
|
}
|
|
166
144
|
}
|
|
167
145
|
|
|
168
|
-
yield
|
|
146
|
+
yield* exports.imports(url, source, imports, artifacts, visited, opts)
|
|
169
147
|
|
|
170
148
|
yield { dependency: { url, source, imports: compressImportsMap(imports) } }
|
|
171
149
|
|
|
172
150
|
return true
|
|
173
151
|
}
|
|
174
152
|
|
|
175
|
-
exports.package = function
|
|
153
|
+
exports.package = function* (url, source, artifacts, visited, opts = {}) {
|
|
176
154
|
if (visited.has(url.href)) return false
|
|
177
155
|
|
|
178
156
|
visited.add(url.href)
|
|
@@ -187,7 +165,9 @@ exports.package = function * (url, source, artifacts, visited, opts = {}) {
|
|
|
187
165
|
}
|
|
188
166
|
|
|
189
167
|
if (info.assets) {
|
|
190
|
-
yield {
|
|
168
|
+
yield {
|
|
169
|
+
children: exports.assets(info.assets, url, artifacts, visited, opts)
|
|
170
|
+
}
|
|
191
171
|
}
|
|
192
172
|
|
|
193
173
|
return true
|
|
@@ -196,7 +176,14 @@ exports.package = function * (url, source, artifacts, visited, opts = {}) {
|
|
|
196
176
|
return false
|
|
197
177
|
}
|
|
198
178
|
|
|
199
|
-
exports.preresolved = function
|
|
179
|
+
exports.preresolved = function* (
|
|
180
|
+
url,
|
|
181
|
+
source,
|
|
182
|
+
resolutions,
|
|
183
|
+
artifacts,
|
|
184
|
+
visited,
|
|
185
|
+
opts = {}
|
|
186
|
+
) {
|
|
200
187
|
const imports = resolutions[url.href]
|
|
201
188
|
|
|
202
189
|
if (typeof imports !== 'object' || imports === null) return false
|
|
@@ -211,9 +198,13 @@ exports.preresolved = function * (url, source, resolutions, artifacts, visited,
|
|
|
211
198
|
const url = new URL(entry)
|
|
212
199
|
|
|
213
200
|
if (specifier === '#package') {
|
|
214
|
-
yield {
|
|
201
|
+
yield {
|
|
202
|
+
children: exports.package(url, null, artifacts, visited, opts)
|
|
203
|
+
}
|
|
215
204
|
} else {
|
|
216
|
-
yield {
|
|
205
|
+
yield {
|
|
206
|
+
children: exports.module(url, null, artifacts, visited, opts)
|
|
207
|
+
}
|
|
217
208
|
}
|
|
218
209
|
} else {
|
|
219
210
|
stack.unshift(...Object.values(entry))
|
|
@@ -226,103 +217,145 @@ exports.preresolved = function * (url, source, resolutions, artifacts, visited,
|
|
|
226
217
|
return true
|
|
227
218
|
}
|
|
228
219
|
|
|
229
|
-
exports.imports = function
|
|
230
|
-
|
|
220
|
+
exports.imports = function* (
|
|
221
|
+
parentURL,
|
|
222
|
+
source,
|
|
223
|
+
imports,
|
|
224
|
+
artifacts,
|
|
225
|
+
visited,
|
|
226
|
+
opts = {}
|
|
227
|
+
) {
|
|
228
|
+
const {
|
|
229
|
+
resolve = exports.resolve.default,
|
|
230
|
+
builtinProtocol = 'builtin:',
|
|
231
|
+
linkedProtocol = 'linked:',
|
|
232
|
+
matchedConditions = []
|
|
233
|
+
} = opts
|
|
231
234
|
|
|
232
235
|
let yielded = false
|
|
233
236
|
|
|
234
237
|
for (const entry of lex(source).imports) {
|
|
235
|
-
const resolver = resolve(entry, parentURL, opts)
|
|
236
|
-
|
|
237
|
-
let next = resolver.next()
|
|
238
|
-
let resolved = false
|
|
239
238
|
let specifier = entry.specifier
|
|
240
|
-
let
|
|
239
|
+
let condition = 'default'
|
|
241
240
|
|
|
242
241
|
if (entry.type & lex.constants.ADDON) {
|
|
243
242
|
specifier = specifier || '.'
|
|
244
|
-
|
|
243
|
+
condition = 'addon'
|
|
245
244
|
} else if (entry.type & lex.constants.ASSET) {
|
|
246
|
-
|
|
245
|
+
condition = 'asset'
|
|
247
246
|
}
|
|
248
247
|
|
|
248
|
+
matchedConditions.push(condition)
|
|
249
|
+
|
|
250
|
+
const resolver = resolve(entry, parentURL, { ...opts, matchedConditions })
|
|
251
|
+
|
|
252
|
+
let next = resolver.next()
|
|
253
|
+
let resolutions = 0
|
|
254
|
+
|
|
249
255
|
while (next.done !== true) {
|
|
250
256
|
const value = next.value
|
|
251
257
|
|
|
252
258
|
if (value.package) {
|
|
253
259
|
next = resolver.next(JSON.parse(yield { module: value.package }))
|
|
260
|
+
} else if (hasResolution(imports, specifier, matchedConditions)) {
|
|
261
|
+
next = resolver.next(false)
|
|
254
262
|
} else {
|
|
255
263
|
const url = value.resolution
|
|
256
264
|
|
|
257
|
-
|
|
258
|
-
if (key === 'addon') addURL(artifacts.addons, url)
|
|
259
|
-
else if (key === 'asset') addURL(artifacts.assets, url)
|
|
265
|
+
let resolved = false
|
|
260
266
|
|
|
261
|
-
|
|
267
|
+
if (
|
|
268
|
+
url.protocol === builtinProtocol ||
|
|
269
|
+
url.protocol === linkedProtocol
|
|
270
|
+
) {
|
|
271
|
+
if (addResolution(imports, specifier, matchedConditions, url)) {
|
|
272
|
+
resolved = yielded = true
|
|
273
|
+
}
|
|
274
|
+
} else {
|
|
275
|
+
const source = yield { module: url }
|
|
262
276
|
|
|
263
|
-
|
|
277
|
+
if (source !== null) {
|
|
278
|
+
if (addResolution(imports, specifier, matchedConditions, url)) {
|
|
279
|
+
yield {
|
|
280
|
+
children: exports.module(url, source, artifacts, visited, opts)
|
|
281
|
+
}
|
|
264
282
|
|
|
265
|
-
|
|
283
|
+
resolved = yielded = true
|
|
284
|
+
}
|
|
285
|
+
}
|
|
266
286
|
}
|
|
267
287
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (key === 'addon') addURL(artifacts.addons, url)
|
|
272
|
-
else if (key === 'asset') addURL(artifacts.assets, url)
|
|
288
|
+
if (resolved) {
|
|
289
|
+
if (condition === 'addon') addURL(artifacts.addons, url)
|
|
290
|
+
else if (condition === 'asset') addURL(artifacts.assets, url)
|
|
273
291
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
yield { children: exports.module(url, source, artifacts, visited, opts) }
|
|
277
|
-
|
|
278
|
-
resolved = yielded = true
|
|
279
|
-
|
|
280
|
-
break
|
|
292
|
+
resolutions++
|
|
281
293
|
}
|
|
282
294
|
|
|
283
|
-
next = resolver.next()
|
|
295
|
+
next = resolver.next(resolved)
|
|
284
296
|
}
|
|
285
297
|
}
|
|
286
298
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
default:
|
|
294
|
-
throw errors.MODULE_NOT_FOUND(`Cannot find module '${specifier}' imported from '${parentURL.href}'`)
|
|
295
|
-
}
|
|
299
|
+
matchedConditions.pop()
|
|
300
|
+
|
|
301
|
+
if (resolutions === 0) {
|
|
302
|
+
throw errors.ADDON_NOT_FOUND(
|
|
303
|
+
`Cannot find ${condition === 'default' ? 'module' : condition} '${specifier}' imported from '${parentURL.href}'`
|
|
304
|
+
)
|
|
296
305
|
}
|
|
297
306
|
}
|
|
298
307
|
|
|
299
308
|
return yielded
|
|
300
309
|
}
|
|
301
310
|
|
|
302
|
-
exports.prebuilds = function
|
|
303
|
-
const
|
|
311
|
+
exports.prebuilds = function* (packageURL, artifacts, visited, opts = {}) {
|
|
312
|
+
const {
|
|
313
|
+
host = null, // Shorthand for single host resolution
|
|
314
|
+
hosts = host !== null ? [host] : [],
|
|
315
|
+
matchedConditions = []
|
|
316
|
+
} = opts
|
|
304
317
|
|
|
305
|
-
|
|
318
|
+
const [prebuildsURL = null] = lookupPrebuildsScope(packageURL, opts)
|
|
319
|
+
|
|
320
|
+
if (prebuildsURL === null) return false
|
|
306
321
|
|
|
307
322
|
let yielded = false
|
|
308
323
|
|
|
309
|
-
for (const
|
|
310
|
-
const
|
|
324
|
+
for (const host of hosts) {
|
|
325
|
+
const prefix = new URL(host + '/', prebuildsURL)
|
|
311
326
|
|
|
312
|
-
|
|
313
|
-
addURL(artifacts.addons, url)
|
|
327
|
+
const conditions = host.split('-')
|
|
314
328
|
|
|
315
|
-
|
|
329
|
+
matchedConditions.push(...conditions)
|
|
316
330
|
|
|
317
|
-
|
|
331
|
+
for (const url of yield { prefix }) {
|
|
332
|
+
const source = yield { module: url }
|
|
333
|
+
|
|
334
|
+
if (source !== null) {
|
|
335
|
+
addURL(artifacts.addons, url)
|
|
336
|
+
|
|
337
|
+
yield {
|
|
338
|
+
children: exports.module(url, source, artifacts, visited, opts)
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
yielded = true
|
|
342
|
+
}
|
|
318
343
|
}
|
|
344
|
+
|
|
345
|
+
for (const _ of conditions) matchedConditions.pop()
|
|
319
346
|
}
|
|
320
347
|
|
|
321
348
|
return yielded
|
|
322
349
|
}
|
|
323
350
|
|
|
324
|
-
exports.assets = function
|
|
325
|
-
|
|
351
|
+
exports.assets = function* (
|
|
352
|
+
patterns,
|
|
353
|
+
parentURL,
|
|
354
|
+
artifacts,
|
|
355
|
+
visited,
|
|
356
|
+
opts = {}
|
|
357
|
+
) {
|
|
358
|
+
const matches = yield* exports.patternMatches(patterns, parentURL, [], opts)
|
|
326
359
|
|
|
327
360
|
let yielded = false
|
|
328
361
|
|
|
@@ -341,8 +374,13 @@ exports.assets = function * (patterns, parentURL, artifacts, visited, opts = {})
|
|
|
341
374
|
return yielded
|
|
342
375
|
}
|
|
343
376
|
|
|
344
|
-
exports.patternMatches = function
|
|
345
|
-
|
|
377
|
+
exports.patternMatches = function* patternMatches(
|
|
378
|
+
pattern,
|
|
379
|
+
parentURL,
|
|
380
|
+
matches,
|
|
381
|
+
opts = {}
|
|
382
|
+
) {
|
|
383
|
+
const { conditions = [], matchedConditions = [] } = opts
|
|
346
384
|
|
|
347
385
|
if (typeof pattern === 'string') {
|
|
348
386
|
let patternNegate = false
|
|
@@ -378,24 +416,127 @@ exports.patternMatches = function * (pattern, parentURL, matches, opts = {}) {
|
|
|
378
416
|
}
|
|
379
417
|
} else if (Array.isArray(pattern)) {
|
|
380
418
|
for (const patternValue of pattern) {
|
|
381
|
-
yield
|
|
419
|
+
yield* patternMatches(patternValue, parentURL, matches, opts)
|
|
382
420
|
}
|
|
383
421
|
} else if (typeof pattern === 'object' && pattern !== null) {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
for (const
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
422
|
+
let yielded = false
|
|
423
|
+
|
|
424
|
+
for (const [condition, patternValue, subset] of conditionMatches(
|
|
425
|
+
pattern,
|
|
426
|
+
conditions,
|
|
427
|
+
opts
|
|
428
|
+
)) {
|
|
429
|
+
matchedConditions.push(condition)
|
|
430
|
+
|
|
431
|
+
if (
|
|
432
|
+
yield* patternMatches(patternValue, parentURL, matches, {
|
|
433
|
+
...opts,
|
|
434
|
+
conditions: subset
|
|
435
|
+
})
|
|
436
|
+
) {
|
|
437
|
+
yielded = true
|
|
391
438
|
}
|
|
439
|
+
|
|
440
|
+
matchedConditions.pop()
|
|
392
441
|
}
|
|
442
|
+
|
|
443
|
+
if (yielded) return true
|
|
393
444
|
}
|
|
394
445
|
|
|
395
446
|
return matches
|
|
396
447
|
}
|
|
397
448
|
|
|
398
|
-
function
|
|
449
|
+
function addURL(array, url) {
|
|
450
|
+
let lo = 0
|
|
451
|
+
let hi = array.length - 1
|
|
452
|
+
|
|
453
|
+
while (lo <= hi) {
|
|
454
|
+
const mid = lo + ((hi - lo) >> 1)
|
|
455
|
+
const found = array[mid]
|
|
456
|
+
|
|
457
|
+
if (found.href === url.href) return
|
|
458
|
+
|
|
459
|
+
if (found.href < url.href) {
|
|
460
|
+
lo = mid + 1
|
|
461
|
+
} else {
|
|
462
|
+
hi = mid - 1
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
array.splice(lo, 0, url)
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
function removeURL(array, url) {
|
|
470
|
+
let lo = 0
|
|
471
|
+
let hi = array.length - 1
|
|
472
|
+
|
|
473
|
+
while (lo <= hi) {
|
|
474
|
+
const mid = lo + ((hi - lo) >> 1)
|
|
475
|
+
const found = array[mid]
|
|
476
|
+
|
|
477
|
+
if (found.href === url.href) break
|
|
478
|
+
|
|
479
|
+
if (found.href < url.href) {
|
|
480
|
+
lo = mid + 1
|
|
481
|
+
} else {
|
|
482
|
+
hi = mid - 1
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (array[lo].href === url.href) array.splice(lo, 1)
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function hasResolution(imports, specifier, conditions) {
|
|
490
|
+
if (specifier in imports === false) return false
|
|
491
|
+
|
|
492
|
+
let current = imports[specifier]
|
|
493
|
+
|
|
494
|
+
for (const key of conditions) {
|
|
495
|
+
if (key in current === false || typeof current[key] !== 'object') {
|
|
496
|
+
return false
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
current = current[key]
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return true
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
function addResolution(imports, specifier, conditions, url) {
|
|
506
|
+
imports[specifier] = imports[specifier] || {}
|
|
507
|
+
|
|
508
|
+
let current = imports[specifier]
|
|
509
|
+
|
|
510
|
+
for (let i = 0, n = conditions.length - 1; i < n; i++) {
|
|
511
|
+
const key = conditions[i]
|
|
512
|
+
|
|
513
|
+
if (key in current === false) {
|
|
514
|
+
current[key] = {}
|
|
515
|
+
} else if (typeof current[key] !== 'object') {
|
|
516
|
+
current[key] = { default: current[key] }
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
current = current[key]
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
const last = conditions[conditions.length - 1]
|
|
523
|
+
|
|
524
|
+
if (last in current) return false
|
|
525
|
+
|
|
526
|
+
current[last] = url.href
|
|
527
|
+
|
|
528
|
+
if ('default' in current) {
|
|
529
|
+
const value = current.default
|
|
530
|
+
|
|
531
|
+
delete current.default
|
|
532
|
+
|
|
533
|
+
current.default = value
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
return true
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
function compressImportsMap(imports) {
|
|
399
540
|
const entries = []
|
|
400
541
|
|
|
401
542
|
for (const entry of Object.entries(imports)) {
|
|
@@ -407,7 +548,7 @@ function compressImportsMap (imports) {
|
|
|
407
548
|
return Object.fromEntries(entries)
|
|
408
549
|
}
|
|
409
550
|
|
|
410
|
-
function compressImportsMapEntry
|
|
551
|
+
function compressImportsMapEntry(resolved) {
|
|
411
552
|
if (typeof resolved === 'string') return resolved
|
|
412
553
|
|
|
413
554
|
let entries = []
|
|
@@ -421,13 +562,11 @@ function compressImportsMapEntry (resolved) {
|
|
|
421
562
|
if (entry[0] === 'default') primary = entry[1]
|
|
422
563
|
}
|
|
423
564
|
|
|
424
|
-
entries = entries.filter(
|
|
565
|
+
entries = entries.filter(
|
|
566
|
+
([condition, resolved]) => condition === 'default' || resolved !== primary
|
|
567
|
+
)
|
|
425
568
|
|
|
426
|
-
if (entries.length === 1)
|
|
427
|
-
const [condition, resolved] = entries[0]
|
|
428
|
-
|
|
429
|
-
if (condition === 'default') return resolved
|
|
430
|
-
}
|
|
569
|
+
if (entries.length === 1) return entries[0][1]
|
|
431
570
|
|
|
432
571
|
return Object.fromEntries(entries)
|
|
433
572
|
}
|
package/lib/errors.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module.exports = class ModuleTraverseError extends Error {
|
|
2
|
-
constructor
|
|
2
|
+
constructor(msg, code, fn = ModuleTraverseError) {
|
|
3
3
|
super(`${code}: ${msg}`)
|
|
4
4
|
this.code = code
|
|
5
5
|
|
|
@@ -8,19 +8,31 @@ module.exports = class ModuleTraverseError extends Error {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
get name
|
|
11
|
+
get name() {
|
|
12
12
|
return 'ModuleTraverseError'
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
static MODULE_NOT_FOUND
|
|
16
|
-
return new ModuleTraverseError(
|
|
15
|
+
static MODULE_NOT_FOUND(msg) {
|
|
16
|
+
return new ModuleTraverseError(
|
|
17
|
+
msg,
|
|
18
|
+
'MODULE_NOT_FOUND',
|
|
19
|
+
ModuleTraverseError.MODULE_NOT_FOUND
|
|
20
|
+
)
|
|
17
21
|
}
|
|
18
22
|
|
|
19
|
-
static ADDON_NOT_FOUND
|
|
20
|
-
return new ModuleTraverseError(
|
|
23
|
+
static ADDON_NOT_FOUND(msg) {
|
|
24
|
+
return new ModuleTraverseError(
|
|
25
|
+
msg,
|
|
26
|
+
'ADDON_NOT_FOUND',
|
|
27
|
+
ModuleTraverseError.ADDON_NOT_FOUND
|
|
28
|
+
)
|
|
21
29
|
}
|
|
22
30
|
|
|
23
|
-
static ASSET_NOT_FOUND
|
|
24
|
-
return new ModuleTraverseError(
|
|
31
|
+
static ASSET_NOT_FOUND(msg) {
|
|
32
|
+
return new ModuleTraverseError(
|
|
33
|
+
msg,
|
|
34
|
+
'ASSET_NOT_FOUND',
|
|
35
|
+
ModuleTraverseError.ASSET_NOT_FOUND
|
|
36
|
+
)
|
|
25
37
|
}
|
|
26
38
|
}
|
package/lib/resolve/bare.js
CHANGED
|
@@ -9,32 +9,41 @@ module.exports = function (entry, parentURL, opts = {}) {
|
|
|
9
9
|
platform = runtime.platform,
|
|
10
10
|
arch = runtime.arch,
|
|
11
11
|
simulator = false,
|
|
12
|
-
host = `${platform}-${arch}${simulator ? '-simulator' : ''}
|
|
12
|
+
host = `${platform}-${arch}${simulator ? '-simulator' : ''}`,
|
|
13
|
+
target = [host]
|
|
13
14
|
} = opts
|
|
14
15
|
|
|
15
16
|
let extensions
|
|
16
|
-
let conditions = ['bare', 'node',
|
|
17
|
-
|
|
18
|
-
if (simulator) conditions = [...conditions, 'simulator']
|
|
17
|
+
let conditions = target.map((host) => ['bare', 'node', ...host.split('-')])
|
|
19
18
|
|
|
20
19
|
if (entry.type & lex.constants.ADDON) {
|
|
21
20
|
extensions = linked ? [] : ['.bare', '.node']
|
|
22
|
-
conditions = ['addon', ...conditions]
|
|
23
|
-
|
|
24
|
-
return resolve.addon(entry.specifier || '.', parentURL, {
|
|
21
|
+
conditions = conditions.map((conditions) => ['addon', ...conditions])
|
|
22
|
+
|
|
23
|
+
return resolve.addon(entry.specifier || '.', parentURL, {
|
|
24
|
+
extensions,
|
|
25
|
+
conditions,
|
|
26
|
+
hosts: target,
|
|
27
|
+
linked,
|
|
28
|
+
...opts
|
|
29
|
+
})
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
if (entry.type & lex.constants.ASSET) {
|
|
28
|
-
conditions = ['asset', ...conditions]
|
|
33
|
+
conditions = conditions.map((conditions) => ['asset', ...conditions])
|
|
29
34
|
} else {
|
|
30
35
|
extensions = ['.js', '.cjs', '.mjs', '.json', '.bare', '.node']
|
|
31
36
|
|
|
32
37
|
if (entry.type & lex.constants.REQUIRE) {
|
|
33
|
-
conditions = ['require', ...conditions]
|
|
38
|
+
conditions = conditions.map((conditions) => ['require', ...conditions])
|
|
34
39
|
} else if (entry.type & lex.constants.IMPORT) {
|
|
35
|
-
conditions = ['import', ...conditions]
|
|
40
|
+
conditions = conditions.map((conditions) => ['import', ...conditions])
|
|
36
41
|
}
|
|
37
42
|
}
|
|
38
43
|
|
|
39
|
-
return resolve.module(entry.specifier, parentURL, {
|
|
44
|
+
return resolve.module(entry.specifier, parentURL, {
|
|
45
|
+
extensions,
|
|
46
|
+
conditions,
|
|
47
|
+
...opts
|
|
48
|
+
})
|
|
40
49
|
}
|
package/lib/resolve/node.js
CHANGED
|
@@ -8,27 +8,39 @@ module.exports = function (entry, parentURL, opts = {}) {
|
|
|
8
8
|
platform = runtime.platform,
|
|
9
9
|
arch = runtime.arch,
|
|
10
10
|
simulator = false,
|
|
11
|
-
host = `${platform}-${arch}${simulator ? '-simulator' : ''}
|
|
11
|
+
host = `${platform}-${arch}${simulator ? '-simulator' : ''}`,
|
|
12
|
+
target = [host]
|
|
12
13
|
} = opts
|
|
13
14
|
|
|
14
15
|
let extensions
|
|
15
|
-
let conditions
|
|
16
|
-
|
|
17
|
-
if (simulator) conditions = [...conditions, 'simulator']
|
|
16
|
+
let conditions
|
|
18
17
|
|
|
19
18
|
if (entry.type & lex.constants.ADDON) {
|
|
20
19
|
extensions = ['.node']
|
|
21
|
-
conditions = ['addon', ...
|
|
22
|
-
|
|
23
|
-
return resolve.addon(entry.specifier || '.', parentURL, {
|
|
20
|
+
conditions = target.map((host) => ['node', 'addon', ...host.split('-')])
|
|
21
|
+
|
|
22
|
+
return resolve.addon(entry.specifier || '.', parentURL, {
|
|
23
|
+
extensions,
|
|
24
|
+
conditions,
|
|
25
|
+
host,
|
|
26
|
+
...opts
|
|
27
|
+
})
|
|
24
28
|
}
|
|
25
29
|
|
|
26
|
-
if (entry.type & lex.constants.
|
|
30
|
+
if (entry.type & lex.constants.ASSET) {
|
|
31
|
+
conditions = ['node', 'asset']
|
|
32
|
+
} else if (entry.type & lex.constants.REQUIRE) {
|
|
27
33
|
extensions = ['.js', '.json', '.node']
|
|
28
34
|
conditions = ['node', 'require']
|
|
29
35
|
} else if (entry.type & lex.constants.IMPORT) {
|
|
30
36
|
conditions = ['node', 'import']
|
|
37
|
+
} else {
|
|
38
|
+
conditions = ['node']
|
|
31
39
|
}
|
|
32
40
|
|
|
33
|
-
return resolve.module(entry.specifier, parentURL, {
|
|
41
|
+
return resolve.module(entry.specifier, parentURL, {
|
|
42
|
+
extensions,
|
|
43
|
+
conditions,
|
|
44
|
+
...opts
|
|
45
|
+
})
|
|
34
46
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bare-module-traverse",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Low-level module graph traversal for Bare",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./index.js",
|
|
@@ -21,7 +21,10 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
|
-
"test": "
|
|
24
|
+
"test": "npm run lint && npm run test:bare && npm run test:node",
|
|
25
|
+
"test:bare": "bare test.js",
|
|
26
|
+
"test:node": "node test.js",
|
|
27
|
+
"lint": "prettier . --check"
|
|
25
28
|
},
|
|
26
29
|
"repository": {
|
|
27
30
|
"type": "git",
|
|
@@ -40,6 +43,7 @@
|
|
|
40
43
|
},
|
|
41
44
|
"devDependencies": {
|
|
42
45
|
"brittle": "^3.2.1",
|
|
43
|
-
"
|
|
46
|
+
"prettier": "^3.4.2",
|
|
47
|
+
"prettier-config-standard": "^7.0.0"
|
|
44
48
|
}
|
|
45
49
|
}
|