bare-module-traverse 1.2.6 → 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 +257 -120
- package/lib/errors.js +20 -8
- package/lib/resolve/bare.js +20 -11
- package/lib/resolve/node.js +21 -9
- package/package.json +4 -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,20 +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
|
+
}
|
|
165
141
|
|
|
166
142
|
break
|
|
167
143
|
}
|
|
168
144
|
}
|
|
169
145
|
|
|
170
|
-
yield
|
|
146
|
+
yield* exports.imports(url, source, imports, artifacts, visited, opts)
|
|
171
147
|
|
|
172
148
|
yield { dependency: { url, source, imports: compressImportsMap(imports) } }
|
|
173
149
|
|
|
174
150
|
return true
|
|
175
151
|
}
|
|
176
152
|
|
|
177
|
-
exports.package = function
|
|
153
|
+
exports.package = function* (url, source, artifacts, visited, opts = {}) {
|
|
178
154
|
if (visited.has(url.href)) return false
|
|
179
155
|
|
|
180
156
|
visited.add(url.href)
|
|
@@ -189,7 +165,9 @@ exports.package = function * (url, source, artifacts, visited, opts = {}) {
|
|
|
189
165
|
}
|
|
190
166
|
|
|
191
167
|
if (info.assets) {
|
|
192
|
-
yield {
|
|
168
|
+
yield {
|
|
169
|
+
children: exports.assets(info.assets, url, artifacts, visited, opts)
|
|
170
|
+
}
|
|
193
171
|
}
|
|
194
172
|
|
|
195
173
|
return true
|
|
@@ -198,7 +176,14 @@ exports.package = function * (url, source, artifacts, visited, opts = {}) {
|
|
|
198
176
|
return false
|
|
199
177
|
}
|
|
200
178
|
|
|
201
|
-
exports.preresolved = function
|
|
179
|
+
exports.preresolved = function* (
|
|
180
|
+
url,
|
|
181
|
+
source,
|
|
182
|
+
resolutions,
|
|
183
|
+
artifacts,
|
|
184
|
+
visited,
|
|
185
|
+
opts = {}
|
|
186
|
+
) {
|
|
202
187
|
const imports = resolutions[url.href]
|
|
203
188
|
|
|
204
189
|
if (typeof imports !== 'object' || imports === null) return false
|
|
@@ -213,9 +198,13 @@ exports.preresolved = function * (url, source, resolutions, artifacts, visited,
|
|
|
213
198
|
const url = new URL(entry)
|
|
214
199
|
|
|
215
200
|
if (specifier === '#package') {
|
|
216
|
-
yield {
|
|
201
|
+
yield {
|
|
202
|
+
children: exports.package(url, null, artifacts, visited, opts)
|
|
203
|
+
}
|
|
217
204
|
} else {
|
|
218
|
-
yield {
|
|
205
|
+
yield {
|
|
206
|
+
children: exports.module(url, null, artifacts, visited, opts)
|
|
207
|
+
}
|
|
219
208
|
}
|
|
220
209
|
} else {
|
|
221
210
|
stack.unshift(...Object.values(entry))
|
|
@@ -228,103 +217,145 @@ exports.preresolved = function * (url, source, resolutions, artifacts, visited,
|
|
|
228
217
|
return true
|
|
229
218
|
}
|
|
230
219
|
|
|
231
|
-
exports.imports = function
|
|
232
|
-
|
|
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
|
|
233
234
|
|
|
234
235
|
let yielded = false
|
|
235
236
|
|
|
236
237
|
for (const entry of lex(source).imports) {
|
|
237
|
-
const resolver = resolve(entry, parentURL, opts)
|
|
238
|
-
|
|
239
|
-
let next = resolver.next()
|
|
240
|
-
let resolved = false
|
|
241
238
|
let specifier = entry.specifier
|
|
242
|
-
let
|
|
239
|
+
let condition = 'default'
|
|
243
240
|
|
|
244
241
|
if (entry.type & lex.constants.ADDON) {
|
|
245
242
|
specifier = specifier || '.'
|
|
246
|
-
|
|
243
|
+
condition = 'addon'
|
|
247
244
|
} else if (entry.type & lex.constants.ASSET) {
|
|
248
|
-
|
|
245
|
+
condition = 'asset'
|
|
249
246
|
}
|
|
250
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
|
+
|
|
251
255
|
while (next.done !== true) {
|
|
252
256
|
const value = next.value
|
|
253
257
|
|
|
254
258
|
if (value.package) {
|
|
255
259
|
next = resolver.next(JSON.parse(yield { module: value.package }))
|
|
260
|
+
} else if (hasResolution(imports, specifier, matchedConditions)) {
|
|
261
|
+
next = resolver.next(false)
|
|
256
262
|
} else {
|
|
257
263
|
const url = value.resolution
|
|
258
264
|
|
|
259
|
-
|
|
260
|
-
if (key === 'addon') addURL(artifacts.addons, url)
|
|
261
|
-
else if (key === 'asset') addURL(artifacts.assets, url)
|
|
265
|
+
let resolved = false
|
|
262
266
|
|
|
263
|
-
|
|
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 }
|
|
264
276
|
|
|
265
|
-
|
|
277
|
+
if (source !== null) {
|
|
278
|
+
if (addResolution(imports, specifier, matchedConditions, url)) {
|
|
279
|
+
yield {
|
|
280
|
+
children: exports.module(url, source, artifacts, visited, opts)
|
|
281
|
+
}
|
|
266
282
|
|
|
267
|
-
|
|
283
|
+
resolved = yielded = true
|
|
284
|
+
}
|
|
285
|
+
}
|
|
268
286
|
}
|
|
269
287
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
if (key === 'addon') addURL(artifacts.addons, url)
|
|
274
|
-
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)
|
|
275
291
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
yield { children: exports.module(url, source, artifacts, visited, opts) }
|
|
279
|
-
|
|
280
|
-
resolved = yielded = true
|
|
281
|
-
|
|
282
|
-
break
|
|
292
|
+
resolutions++
|
|
283
293
|
}
|
|
284
294
|
|
|
285
|
-
next = resolver.next()
|
|
295
|
+
next = resolver.next(resolved)
|
|
286
296
|
}
|
|
287
297
|
}
|
|
288
298
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
default:
|
|
296
|
-
throw errors.MODULE_NOT_FOUND(`Cannot find module '${specifier}' imported from '${parentURL.href}'`)
|
|
297
|
-
}
|
|
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
|
+
)
|
|
298
305
|
}
|
|
299
306
|
}
|
|
300
307
|
|
|
301
308
|
return yielded
|
|
302
309
|
}
|
|
303
310
|
|
|
304
|
-
exports.prebuilds = function
|
|
305
|
-
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
|
|
306
317
|
|
|
307
|
-
|
|
318
|
+
const [prebuildsURL = null] = lookupPrebuildsScope(packageURL, opts)
|
|
319
|
+
|
|
320
|
+
if (prebuildsURL === null) return false
|
|
308
321
|
|
|
309
322
|
let yielded = false
|
|
310
323
|
|
|
311
|
-
for (const
|
|
312
|
-
const
|
|
324
|
+
for (const host of hosts) {
|
|
325
|
+
const prefix = new URL(host + '/', prebuildsURL)
|
|
313
326
|
|
|
314
|
-
|
|
315
|
-
addURL(artifacts.addons, url)
|
|
327
|
+
const conditions = host.split('-')
|
|
316
328
|
|
|
317
|
-
|
|
329
|
+
matchedConditions.push(...conditions)
|
|
318
330
|
|
|
319
|
-
|
|
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
|
+
}
|
|
320
343
|
}
|
|
344
|
+
|
|
345
|
+
for (const _ of conditions) matchedConditions.pop()
|
|
321
346
|
}
|
|
322
347
|
|
|
323
348
|
return yielded
|
|
324
349
|
}
|
|
325
350
|
|
|
326
|
-
exports.assets = function
|
|
327
|
-
|
|
351
|
+
exports.assets = function* (
|
|
352
|
+
patterns,
|
|
353
|
+
parentURL,
|
|
354
|
+
artifacts,
|
|
355
|
+
visited,
|
|
356
|
+
opts = {}
|
|
357
|
+
) {
|
|
358
|
+
const matches = yield* exports.patternMatches(patterns, parentURL, [], opts)
|
|
328
359
|
|
|
329
360
|
let yielded = false
|
|
330
361
|
|
|
@@ -343,8 +374,13 @@ exports.assets = function * (patterns, parentURL, artifacts, visited, opts = {})
|
|
|
343
374
|
return yielded
|
|
344
375
|
}
|
|
345
376
|
|
|
346
|
-
exports.patternMatches = function
|
|
347
|
-
|
|
377
|
+
exports.patternMatches = function* patternMatches(
|
|
378
|
+
pattern,
|
|
379
|
+
parentURL,
|
|
380
|
+
matches,
|
|
381
|
+
opts = {}
|
|
382
|
+
) {
|
|
383
|
+
const { conditions = [], matchedConditions = [] } = opts
|
|
348
384
|
|
|
349
385
|
if (typeof pattern === 'string') {
|
|
350
386
|
let patternNegate = false
|
|
@@ -380,24 +416,127 @@ exports.patternMatches = function * (pattern, parentURL, matches, opts = {}) {
|
|
|
380
416
|
}
|
|
381
417
|
} else if (Array.isArray(pattern)) {
|
|
382
418
|
for (const patternValue of pattern) {
|
|
383
|
-
yield
|
|
419
|
+
yield* patternMatches(patternValue, parentURL, matches, opts)
|
|
384
420
|
}
|
|
385
421
|
} else if (typeof pattern === 'object' && pattern !== null) {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
for (const
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
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
|
|
393
438
|
}
|
|
439
|
+
|
|
440
|
+
matchedConditions.pop()
|
|
394
441
|
}
|
|
442
|
+
|
|
443
|
+
if (yielded) return true
|
|
395
444
|
}
|
|
396
445
|
|
|
397
446
|
return matches
|
|
398
447
|
}
|
|
399
448
|
|
|
400
|
-
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) {
|
|
401
540
|
const entries = []
|
|
402
541
|
|
|
403
542
|
for (const entry of Object.entries(imports)) {
|
|
@@ -409,7 +548,7 @@ function compressImportsMap (imports) {
|
|
|
409
548
|
return Object.fromEntries(entries)
|
|
410
549
|
}
|
|
411
550
|
|
|
412
|
-
function compressImportsMapEntry
|
|
551
|
+
function compressImportsMapEntry(resolved) {
|
|
413
552
|
if (typeof resolved === 'string') return resolved
|
|
414
553
|
|
|
415
554
|
let entries = []
|
|
@@ -423,13 +562,11 @@ function compressImportsMapEntry (resolved) {
|
|
|
423
562
|
if (entry[0] === 'default') primary = entry[1]
|
|
424
563
|
}
|
|
425
564
|
|
|
426
|
-
entries = entries.filter(
|
|
565
|
+
entries = entries.filter(
|
|
566
|
+
([condition, resolved]) => condition === 'default' || resolved !== primary
|
|
567
|
+
)
|
|
427
568
|
|
|
428
|
-
if (entries.length === 1)
|
|
429
|
-
const [condition, resolved] = entries[0]
|
|
430
|
-
|
|
431
|
-
if (condition === 'default') return resolved
|
|
432
|
-
}
|
|
569
|
+
if (entries.length === 1) return entries[0][1]
|
|
433
570
|
|
|
434
571
|
return Object.fromEntries(entries)
|
|
435
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",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"test": "npm run lint && npm run test:bare && npm run test:node",
|
|
25
25
|
"test:bare": "bare test.js",
|
|
26
26
|
"test:node": "node test.js",
|
|
27
|
-
"lint": "
|
|
27
|
+
"lint": "prettier . --check"
|
|
28
28
|
},
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"brittle": "^3.2.1",
|
|
46
|
-
"
|
|
46
|
+
"prettier": "^3.4.2",
|
|
47
|
+
"prettier-config-standard": "^7.0.0"
|
|
47
48
|
}
|
|
48
49
|
}
|