bare-module-traverse 2.4.1 → 2.4.2

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 CHANGED
@@ -72,6 +72,8 @@ options = {
72
72
  }
73
73
  ```
74
74
 
75
+ When a module URL uses the `data:` protocol, its source is decoded directly from the specifier rather than read via `readModule()`, so no source module effect is emitted for it. base64 encoded data is decoded to a `Buffer`, other data is percent-decoded to a string, and the module type is derived from the media type (`text/javascript` and `application/javascript` map to a script or module, `application/json` to JSON, and anything else to `defaultType`). A JavaScript `data:` URL inherits the type of the module that imports it, so it is a script when imported from a script and a module when imported from a module, falling back to `defaultType` when it has no referrer, such as a `data:` entry. Only the UTF-8 charset is supported; a `data:` URL specifying any other charset throws.
76
+
75
77
  `visited` is a `Set` of already visited module hrefs. If provided, modules whose href is already in the set are skipped and the set is updated in place as traversal proceeds. This allows a single set to be shared across several traversals so that a later traversal, such as one rooted at a dynamically imported module, does not revisit modules already seen by an earlier one.
76
78
 
77
79
  Options supported by <https://github.com/holepunchto/bare-module-resolve> and <https://github.com/holepunchto/bare-addon-resolve> may also be specified.
package/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const { lookupPackageScope, conditionMatches } = require('bare-module-resolve')
2
2
  const lex = require('bare-module-lexer')
3
+ const MIME = require('bare-mime')
3
4
  const resolve = require('./lib/resolve')
4
5
  const errors = require('./lib/errors')
5
6
 
@@ -196,16 +197,20 @@ exports.module = function* (url, source, attributes, artifacts, visited, opts =
196
197
  const artifact = asset === true || moduleType(url, attributes, null, opts) === constants.ADDON
197
198
 
198
199
  if (source === null) {
199
- const exists = probed !== undefined ? probed : artifact ? yield { probe: url } : undefined
200
+ if (url.protocol === 'data:') {
201
+ source = decodeDataURL(url)
202
+ } else {
203
+ const exists = probed !== undefined ? probed : artifact ? yield { probe: url } : undefined
200
204
 
201
- if (exists === false) {
202
- throw errors.MODULE_NOT_FOUND(`Cannot find module '${url.href}'`, url.href)
203
- }
205
+ if (exists === false) {
206
+ throw errors.MODULE_NOT_FOUND(`Cannot find module '${url.href}'`, url.href)
207
+ }
204
208
 
205
- source = yield { module: url, artifact }
209
+ source = yield { module: url, artifact }
206
210
 
207
- if (exists !== true && source === null) {
208
- throw errors.MODULE_NOT_FOUND(`Cannot find module '${url.href}'`, url.href)
211
+ if (exists !== true && source === null) {
212
+ throw errors.MODULE_NOT_FOUND(`Cannot find module '${url.href}'`, url.href)
213
+ }
209
214
  }
210
215
  }
211
216
 
@@ -219,20 +224,22 @@ exports.module = function* (url, source, attributes, artifacts, visited, opts =
219
224
 
220
225
  let info = null
221
226
 
222
- for (const packageURL of lookupPackageScope(url, opts)) {
223
- const source = yield { module: packageURL, artifact: false }
227
+ if (url.protocol !== 'data:') {
228
+ for (const packageURL of lookupPackageScope(url, opts)) {
229
+ const source = yield { module: packageURL, artifact: false }
224
230
 
225
- if (source !== null) {
226
- info = JSON.parse(source)
231
+ if (source !== null) {
232
+ info = JSON.parse(source)
227
233
 
228
- imports['#package'] = packageURL.href
234
+ imports['#package'] = packageURL.href
229
235
 
230
- yield {
231
- children: exports.package(packageURL, source, artifacts, visited, opts),
232
- deferred: false
233
- }
236
+ yield {
237
+ children: exports.package(packageURL, source, artifacts, visited, opts),
238
+ deferred: false
239
+ }
234
240
 
235
- break
241
+ break
242
+ }
236
243
  }
237
244
  }
238
245
 
@@ -255,7 +262,10 @@ exports.module = function* (url, source, attributes, artifacts, visited, opts =
255
262
 
256
263
  if (asset === false) {
257
264
  if (type === constants.SCRIPT || type === constants.MODULE) {
258
- yield* exports.imports(url, source, imports, artifacts, lexer, visited, opts)
265
+ yield* exports.imports(url, source, imports, artifacts, lexer, visited, {
266
+ ...opts,
267
+ referrerType: type
268
+ })
259
269
  } else if (type === constants.ADDON) {
260
270
  yield* exports.addons(url, artifacts, visited, opts)
261
271
  }
@@ -534,7 +544,13 @@ function* resolveImport(entry, specifier, condition, parentURL, imports, artifac
534
544
  resolved = true
535
545
  }
536
546
  } else {
537
- const source = yield { module: url, artifact: false }
547
+ let source
548
+
549
+ if (url.protocol === 'data:') {
550
+ source = decodeDataURL(url)
551
+ } else {
552
+ source = yield { module: url, artifact: false }
553
+ }
538
554
 
539
555
  if (source !== null) {
540
556
  resolution = yield* postresolve(url)
@@ -706,7 +722,7 @@ function* postresolve(url) {
706
722
  }
707
723
 
708
724
  function moduleType(url, attributes, info, opts = {}) {
709
- const { defaultType = constants.SCRIPT, aliases = null } = opts
725
+ const { defaultType = constants.SCRIPT, referrerType, aliases = null } = opts
710
726
 
711
727
  if (typeof attributes.type === 'string') {
712
728
  switch (attributes.type) {
@@ -729,6 +745,20 @@ function moduleType(url, attributes, info, opts = {}) {
729
745
  return 0
730
746
  }
731
747
 
748
+ if (url.protocol === 'data:') {
749
+ const { mime } = parseDataURL(url)
750
+
751
+ if (mime === null || mime.subtype === 'javascript') {
752
+ if (referrerType) return referrerType
753
+
754
+ return defaultType === constants.MODULE ? constants.MODULE : constants.SCRIPT
755
+ }
756
+
757
+ if (mime.subtype === 'json') return constants.JSON
758
+
759
+ return defaultType
760
+ }
761
+
732
762
  const match = url.pathname.match(/\.[a-z]+$/)
733
763
 
734
764
  if (match === null) return defaultType
@@ -765,6 +795,36 @@ function moduleType(url, attributes, info, opts = {}) {
765
795
  return defaultType
766
796
  }
767
797
 
798
+ function parseDataURL(url) {
799
+ const { pathname } = url
800
+
801
+ const comma = pathname.indexOf(',')
802
+
803
+ const meta = comma === -1 ? pathname : pathname.slice(0, comma)
804
+ const data = comma === -1 ? '' : pathname.slice(comma + 1)
805
+
806
+ const base64 = /;base64$/i.test(meta)
807
+
808
+ return { mime: MIME.parse(meta), base64, data }
809
+ }
810
+
811
+ function decodeDataURL(url) {
812
+ const { mime, base64, data } = parseDataURL(url)
813
+
814
+ const charset = mime === null ? undefined : mime.parameters.get('charset')
815
+
816
+ if (charset !== undefined && !/^utf-?8$/i.test(charset)) {
817
+ throw errors.UNKNOWN_DATA_URL_CHARSET(
818
+ `Unsupported charset '${charset}' in data URL '${url.href}'`,
819
+ charset
820
+ )
821
+ }
822
+
823
+ if (base64) return Buffer.from(data, 'base64')
824
+
825
+ return decodeURIComponent(data)
826
+ }
827
+
768
828
  function addURL(collection, url) {
769
829
  if (Array.isArray(collection)) {
770
830
  let lo = 0
package/lib/errors.js CHANGED
@@ -45,4 +45,12 @@ module.exports = class ModuleTraverseError extends Error {
45
45
  static INVALID_IMPORTS_MAP(msg) {
46
46
  return new ModuleTraverseError(msg, ModuleTraverseError.INVALID_IMPORTS_MAP)
47
47
  }
48
+
49
+ static UNKNOWN_DATA_URL_CHARSET(msg, charset) {
50
+ const err = new ModuleTraverseError(msg, ModuleTraverseError.UNKNOWN_DATA_URL_CHARSET)
51
+
52
+ err.charset = charset
53
+
54
+ return err
55
+ }
48
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-module-traverse",
3
- "version": "2.4.1",
3
+ "version": "2.4.2",
4
4
  "description": "Low-level module graph traversal for Bare",
5
5
  "exports": {
6
6
  ".": {
@@ -55,6 +55,7 @@
55
55
  "homepage": "https://github.com/holepunchto/bare-module-traverse#readme",
56
56
  "dependencies": {
57
57
  "bare-addon-resolve": "^1.5.0",
58
+ "bare-mime": "^1.0.0",
58
59
  "bare-module-lexer": "^1.6.0",
59
60
  "bare-module-resolve": "^1.7.0"
60
61
  },