bare-module 2.8.2 → 3.0.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.
Files changed (3) hide show
  1. package/README.md +5 -3
  2. package/index.js +97 -200
  3. package/package.json +3 -4
package/README.md CHANGED
@@ -22,7 +22,7 @@ const Module = require('bare-module')
22
22
 
23
23
  #### `Module.cache`
24
24
 
25
- #### `const resolved = Module.resolve(specifier[, dirname][, options])`
25
+ #### `const url = Module.resolve(specifier, parentURL[, options])`
26
26
 
27
27
  Options include:
28
28
 
@@ -31,7 +31,7 @@ Options include:
31
31
  }
32
32
  ```
33
33
 
34
- #### `const module = Module.load(specifier[, source][, options])`
34
+ #### `const module = Module.load(url[, source][, options])`
35
35
 
36
36
  Options include:
37
37
 
@@ -40,6 +40,8 @@ Options include:
40
40
  }
41
41
  ```
42
42
 
43
+ #### `module.url`
44
+
43
45
  #### `module.filename`
44
46
 
45
47
  #### `module.dirname`
@@ -64,7 +66,7 @@ Options include:
64
66
 
65
67
  ### Custom `require()`
66
68
 
67
- #### `const require = Module.createRequire(filename[, options])`
69
+ #### `const require = Module.createRequire(url[, options])`
68
70
 
69
71
  ### Protocols
70
72
 
package/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  /* global Bare */
2
2
  const path = require('bare-path')
3
- const os = require('bare-os')
4
3
  const url = require('bare-url')
5
4
  const resolve = require('bare-module-resolve')
6
5
  const Bundle = require('bare-bundle')
@@ -10,8 +9,8 @@ const errors = require('./lib/errors')
10
9
  const binding = require('./binding')
11
10
 
12
11
  const Module = module.exports = exports = class Module {
13
- constructor (filename) {
14
- this._filename = filename
12
+ constructor (url) {
13
+ this._url = url
15
14
  this._state = 0
16
15
  this._type = 0
17
16
  this._defaultType = this._type
@@ -28,12 +27,16 @@ const Module = module.exports = exports = class Module {
28
27
  Module._modules.add(this)
29
28
  }
30
29
 
30
+ get url () {
31
+ return this._url
32
+ }
33
+
31
34
  get filename () {
32
- return this._filename
35
+ return url.fileURLToPath(this._url)
33
36
  }
34
37
 
35
38
  get dirname () {
36
- return path.dirname(this._filename)
39
+ return path.dirname(url.fileURLToPath(this._url))
37
40
  }
38
41
 
39
42
  get type () {
@@ -132,7 +135,7 @@ const Module = module.exports = exports = class Module {
132
135
  if (key !== 'default') names.push(key)
133
136
  }
134
137
 
135
- this._handle = binding.createSyntheticModule(this._filename, names, Module._handle)
138
+ this._handle = binding.createSyntheticModule(this._url.href, names, Module._handle)
136
139
  }
137
140
 
138
141
  this._state |= constants.states.SYNTHESIZED
@@ -142,8 +145,7 @@ const Module = module.exports = exports = class Module {
142
145
  return {
143
146
  __proto__: { constructor: Module },
144
147
 
145
- filename: this.filename,
146
- dirname: this.dirname,
148
+ url: this.url,
147
149
  type: this.type,
148
150
  defaultType: this.defaultType,
149
151
  main: this.main,
@@ -163,14 +165,11 @@ const Module = module.exports = exports = class Module {
163
165
 
164
166
  static _handle = binding.init(this, this._onimport, this._onevaluate, this._onmeta)
165
167
 
166
- static _onimport (specifier, assertions, referrerFilename, isDynamicImport) {
167
- const referrer = this._cache[referrerFilename]
168
+ static _onimport (specifier, assertions, referrerURL, isDynamicImport) {
169
+ const referrer = this._cache[referrerURL]
168
170
 
169
- const protocol = this._protocolFor(specifier, referrer._protocol)
170
-
171
- specifier = this.resolve(specifier, {
171
+ const url = this.resolve(specifier, referrer._url, {
172
172
  isImport: true,
173
- protocol,
174
173
  referrer
175
174
  })
176
175
 
@@ -185,10 +184,9 @@ const Module = module.exports = exports = class Module {
185
184
  break
186
185
  }
187
186
 
188
- const module = this.load(specifier, {
187
+ const module = this.load(url, {
189
188
  isImport: true,
190
189
  isDynamicImport,
191
- protocol: this._protocolFor(specifier, protocol),
192
190
  referrer,
193
191
  type
194
192
  })
@@ -215,16 +213,13 @@ const Module = module.exports = exports = class Module {
215
213
 
216
214
  addon.host = Bare.Addon.host
217
215
 
218
- meta.url = module._filename
216
+ meta.url = module._url.href
219
217
  meta.main = module._main === module
220
218
  meta.resolve = resolve
221
219
  meta.addon = addon
222
220
 
223
221
  function resolve (specifier) {
224
- return self.resolve(specifier, {
225
- protocol: self._protocolFor(specifier, module._protocol),
226
- referrer
227
- })
222
+ return self.resolve(specifier, referrer._url, { referrer }).href
228
223
  }
229
224
 
230
225
  function addon (specifier = '.') {
@@ -250,12 +245,14 @@ const Module = module.exports = exports = class Module {
250
245
  return false
251
246
  }
252
247
 
253
- static createRequire (filename, opts = {}) {
248
+ static createRequire (url, opts = {}) {
254
249
  const self = Module
255
250
 
251
+ if (typeof url === 'string') url = new URL(url, 'file:///')
252
+
256
253
  let {
257
254
  referrer = null,
258
- protocol = self._protocolFor(filename, referrer ? referrer._protocol : self._protocols['file:']),
255
+ protocol = referrer ? referrer._protocol : self._protocols['file:'],
259
256
  imports = referrer ? referrer._imports : null,
260
257
  resolutions = referrer ? referrer._resolutions : null,
261
258
  builtins = referrer ? referrer._builtins : null,
@@ -265,7 +262,7 @@ const Module = module.exports = exports = class Module {
265
262
  type = constants.types.SCRIPT
266
263
  } = opts
267
264
 
268
- const module = new Module(filename)
265
+ const module = new Module(url)
269
266
 
270
267
  module._main = main || module
271
268
  module._type = type
@@ -288,19 +285,15 @@ const Module = module.exports = exports = class Module {
288
285
  return require
289
286
 
290
287
  function require (specifier) {
291
- const module = self.load(resolve(specifier), {
292
- protocol: self._protocolFor(specifier, protocol),
293
- referrer
294
- })
288
+ const url = self.resolve(specifier, referrer._url, { referrer })
289
+
290
+ const module = self.load(url, { referrer })
295
291
 
296
292
  return module._exports
297
293
  }
298
294
 
299
295
  function resolve (specifier) {
300
- return self.resolve(specifier, {
301
- protocol: self._protocolFor(specifier, protocol),
302
- referrer
303
- })
296
+ return self.resolve(specifier, referrer._url, { referrer }).pathname
304
297
  }
305
298
 
306
299
  function addon (specifier = '.') {
@@ -308,19 +301,15 @@ const Module = module.exports = exports = class Module {
308
301
  }
309
302
  }
310
303
 
311
- static load (specifier, source = null, opts = {}) {
304
+ static load (url, source = null, opts = {}) {
312
305
  const self = Module
313
306
 
314
- if (typeof specifier !== 'string') {
315
- throw new TypeError(`Specifier must be a string. Received type ${typeof specifier} (${specifier})`)
316
- }
317
-
318
307
  if (!ArrayBuffer.isView(source) && typeof source !== 'string' && source !== null) {
319
308
  opts = source
320
309
  source = null
321
310
  }
322
311
 
323
- let {
312
+ const {
324
313
  isImport = false,
325
314
  isDynamicImport = false,
326
315
 
@@ -328,62 +317,53 @@ const Module = module.exports = exports = class Module {
328
317
  type = 0,
329
318
  defaultType = referrer ? referrer._defaultType : 0,
330
319
  main = referrer ? referrer._main : null,
331
- protocol = self._protocolFor(specifier, referrer ? referrer._protocol : self._protocols['file:']),
320
+ protocol = referrer ? referrer._protocol : self._protocols['file:'],
332
321
  imports = referrer ? referrer._imports : null,
333
322
  resolutions = referrer ? referrer._resolutions : null,
334
323
  builtins = referrer ? referrer._builtins : null,
335
324
  conditions = referrer ? referrer._conditions : self._conditions
336
325
  } = opts
337
326
 
338
- if (self._cache[specifier]) return self._cache[specifier]._transform(isImport, isDynamicImport)
327
+ if (self._cache[url.href]) return self._cache[url.href]._transform(isImport, isDynamicImport)
339
328
 
340
- const bundle = self._bundleFor(path.dirname(specifier), protocol)
329
+ const module = self._cache[url.href] = new Module(url)
341
330
 
342
- if (bundle) protocol = bundle._protocol
343
-
344
- const module = self._cache[specifier] = new Module(specifier)
331
+ switch (url.protocol) {
332
+ case 'builtin:':
333
+ module._exports = builtins[url.pathname]
334
+ break
345
335
 
346
- if (builtins && specifier in builtins) {
347
- module._exports = builtins[specifier]
348
- } else {
349
- module._main = main || module
350
- module._defaultType = defaultType
351
- module._protocol = protocol
352
- module._imports = imports
353
- module._resolutions = resolutions
354
- module._builtins = builtins
355
- module._conditions = conditions
336
+ default: {
337
+ module._main = main || module
338
+ module._defaultType = defaultType
339
+ module._protocol = protocol
340
+ module._imports = imports
341
+ module._resolutions = resolutions
342
+ module._builtins = builtins
343
+ module._conditions = conditions
356
344
 
357
- let extension = self._extensionFor(type) || path.extname(specifier)
345
+ let extension = self._extensionFor(type) || path.extname(url.pathname)
358
346
 
359
- if (extension in self._extensions === false) {
360
- if (defaultType) extension = self._extensionFor(defaultType) || '.js'
361
- else extension = '.js'
362
- }
347
+ if (extension in self._extensions === false) {
348
+ if (defaultType) extension = self._extensionFor(defaultType) || '.js'
349
+ else extension = '.js'
350
+ }
363
351
 
364
- if (extension === '.bundle' && path.extname(specifier) !== extension) {
365
- throw errors.INVALID_BUNDLE_EXTENSION(`Invalid extension for bundle '${specifier}'`)
352
+ self._extensions[extension](module, source, referrer)
366
353
  }
367
-
368
- self._extensions[extension](module, source, referrer)
369
354
  }
370
355
 
371
356
  return module._transform(isImport, isDynamicImport)
372
357
  }
373
358
 
374
- static resolve (specifier, dirname = null, opts = {}) {
359
+ static resolve (specifier, parentURL, opts = {}) {
375
360
  const self = Module
376
361
 
377
362
  if (typeof specifier !== 'string') {
378
363
  throw new TypeError(`Specifier must be a string. Received type ${typeof specifier} (${specifier})`)
379
364
  }
380
365
 
381
- if (typeof dirname !== 'string' && dirname !== null) {
382
- opts = dirname
383
- dirname = null
384
- }
385
-
386
- let {
366
+ const {
387
367
  isImport = false,
388
368
 
389
369
  referrer = null,
@@ -394,36 +374,11 @@ const Module = module.exports = exports = class Module {
394
374
  conditions = referrer ? referrer._conditions : self._conditions
395
375
  } = opts
396
376
 
397
- if (referrer) dirname = path.dirname(referrer._filename)
398
- else if (typeof dirname !== 'string') dirname = os.cwd()
399
-
400
- const bundle = self._bundleFor(path.dirname(specifier), protocol)
401
-
402
- if (bundle) protocol = bundle._protocol
403
-
404
- const resolved = protocol.preresolve(specifier, dirname)
377
+ const resolved = protocol.preresolve(specifier, parentURL)
405
378
 
406
- const [resolution] = protocol.resolve(specifier, dirname, imports)
379
+ const [resolution] = protocol.resolve(specifier, parentURL, imports)
407
380
 
408
- if (resolution) return protocol.postresolve(resolution, dirname)
409
-
410
- const parentURL = url.pathToFileURL(
411
- referrer
412
- ? referrer._filename
413
- : dirname[dirname.length - 1] === path.sep
414
- ? dirname
415
- : dirname + path.sep
416
- )
417
-
418
- if (resolutions) {
419
- const entries = Object.entries(resolutions)
420
-
421
- resolutions = Object.create(null)
422
-
423
- for (const [path, imports] of entries) {
424
- resolutions[url.pathToFileURL(path).href] = imports
425
- }
426
- }
381
+ if (resolution) return protocol.postresolve(resolution, parentURL)
427
382
 
428
383
  for (const resolution of resolve(resolved, parentURL, {
429
384
  conditions: isImport ? ['import', ...conditions] : ['require', ...conditions],
@@ -440,13 +395,11 @@ const Module = module.exports = exports = class Module {
440
395
  ]
441
396
  }, readPackage)) {
442
397
  switch (resolution.protocol) {
443
- case 'builtin:': return resolution.pathname
398
+ case 'builtin:': return resolution
444
399
 
445
400
  case 'file:': {
446
- const path = url.fileURLToPath(resolution)
447
-
448
- if (protocol.exists(path)) {
449
- return protocol.postresolve(path, dirname)
401
+ if (protocol.exists(resolution)) {
402
+ return protocol.postresolve(resolution, parentURL)
450
403
  }
451
404
  }
452
405
  }
@@ -454,15 +407,13 @@ const Module = module.exports = exports = class Module {
454
407
 
455
408
  let msg = `Cannot find module '${specifier}'`
456
409
 
457
- if (referrer) msg += ` imported from '${referrer._filename}'`
410
+ if (referrer) msg += ` imported from '${referrer._url.href}'`
458
411
 
459
412
  throw errors.MODULE_NOT_FOUND(msg)
460
413
 
461
414
  function readPackage (packageURL) {
462
- const path = url.fileURLToPath(packageURL)
463
-
464
- if (protocol.exists(path)) {
465
- return Module.load(path, { protocol })._exports
415
+ if (protocol.exists(packageURL)) {
416
+ return Module.load(packageURL, { protocol })._exports
466
417
  }
467
418
 
468
419
  return null
@@ -485,39 +436,6 @@ const Module = module.exports = exports = class Module {
485
436
  return null
486
437
  }
487
438
  }
488
-
489
- static _protocolFor (specifier, fallback = null) {
490
- let protocol = fallback
491
-
492
- const i = specifier.indexOf(':')
493
-
494
- if (i >= 2) { // Allow drive letters in Windows paths
495
- const name = specifier.slice(0, i + 1)
496
-
497
- protocol = this._protocols[name] || fallback
498
-
499
- if (protocol === null) {
500
- throw errors.UNKNOWN_PROTOCOL(`Unknown protocol '${name}' in specifier '${specifier}'`)
501
- }
502
- }
503
-
504
- return protocol
505
- }
506
-
507
- static _bundleFor (specifier, protocol) {
508
- let name = specifier
509
- do {
510
- if (path.extname(name) === '.bundle') {
511
- break
512
- }
513
-
514
- name = path.dirname(name)
515
- } while (name !== path.sep && name !== '.')
516
-
517
- if (path.extname(name) !== '.bundle') return null
518
-
519
- return Module.load(name, { protocol })
520
- }
521
439
  }
522
440
 
523
441
  Module._extensions['.js'] = function (module, source, referrer) {
@@ -526,22 +444,18 @@ Module._extensions['.js'] = function (module, source, referrer) {
526
444
  const protocol = module._protocol
527
445
 
528
446
  let pkg
529
- let dirname = path.dirname(module._filename)
530
- do {
531
- const specifier = path.join(dirname, 'package.json')
532
447
 
533
- if (self._cache[specifier]) {
534
- pkg = self._cache[specifier]
448
+ for (const packageURL of resolve.lookupPackageScope(module._url)) {
449
+ if (self._cache[packageURL.href]) {
450
+ pkg = self._cache[packageURL.href]
535
451
  break
536
452
  }
537
453
 
538
- if (protocol.exists(specifier)) {
539
- pkg = self.load(specifier, { protocol })
454
+ if (protocol.exists(packageURL)) {
455
+ pkg = self.load(packageURL, { protocol })
540
456
  break
541
457
  }
542
-
543
- dirname = path.dirname(dirname)
544
- } while (dirname !== path.sep && dirname !== '.')
458
+ }
545
459
 
546
460
  const info = (pkg && pkg._exports) || {}
547
461
 
@@ -550,10 +464,7 @@ Module._extensions['.js'] = function (module, source, referrer) {
550
464
  (constants.types.MODULE === module._defaultType) ||
551
465
 
552
466
  // The package is explicitly declared as an ES module.
553
- (info && info.type === 'module') ||
554
-
555
- // The source is a data: URI and the referrer is itself an ES module.
556
- (protocol === self._protocols['data:'] && referrer && referrer._type === constants.types.MODULE)
467
+ (info && info.type === 'module')
557
468
  )
558
469
 
559
470
  return self._extensions[isESM ? '.mjs' : '.cjs'](module, source, referrer)
@@ -567,9 +478,9 @@ Module._extensions['.cjs'] = function (module, source, referrer) {
567
478
  module._type = constants.types.SCRIPT
568
479
 
569
480
  if (protocol.load) {
570
- module._exports = protocol.load(module._filename)
481
+ module._exports = protocol.load(module._url)
571
482
  } else {
572
- if (source === null) source = protocol.read(module._filename)
483
+ if (source === null) source = protocol.read(module._url)
573
484
 
574
485
  if (typeof source !== 'string') source = Buffer.coerce(source).toString()
575
486
 
@@ -584,28 +495,26 @@ Module._extensions['.cjs'] = function (module, source, referrer) {
584
495
 
585
496
  module._exports = {}
586
497
 
587
- binding.createFunction(module._filename, ['require', 'module', 'exports', '__filename', '__dirname'], source, 0)(
498
+ const filename = url.fileURLToPath(module._url)
499
+
500
+ binding.createFunction(module._url.href, ['require', 'module', 'exports', '__filename', '__dirname'], source, 0)(
588
501
  require,
589
502
  module,
590
503
  module._exports,
591
- module._filename,
592
- path.dirname(module._filename)
504
+ filename,
505
+ path.dirname(filename)
593
506
  )
594
507
 
595
508
  function require (specifier) {
596
- const module = self.load(resolve(specifier), {
597
- protocol: self._protocolFor(specifier, protocol),
598
- referrer
599
- })
509
+ const url = self.resolve(specifier, referrer._url, { referrer })
510
+
511
+ const module = self.load(url, { referrer })
600
512
 
601
513
  return module._exports
602
514
  }
603
515
 
604
516
  function resolve (specifier) {
605
- return self.resolve(specifier, {
606
- protocol: self._protocolFor(specifier, protocol),
607
- referrer
608
- })
517
+ return self.resolve(specifier, referrer._url, { referrer }).pathname
609
518
  }
610
519
 
611
520
  function addon (specifier = '.') {
@@ -622,13 +531,13 @@ Module._extensions['.mjs'] = function (module, source, referrer) {
622
531
  module._type = constants.types.MODULE
623
532
 
624
533
  if (protocol.load) {
625
- module._exports = protocol.load(module._filename)
534
+ module._exports = protocol.load(module._url)
626
535
  } else {
627
- if (source === null) source = protocol.read(module._filename)
536
+ if (source === null) source = protocol.read(module._url)
628
537
 
629
538
  if (typeof source !== 'string') source = Buffer.coerce(source).toString()
630
539
 
631
- module._handle = binding.createModule(module._filename, source, 0, self._handle)
540
+ module._handle = binding.createModule(module._url.href, source, 0, self._handle)
632
541
  }
633
542
  }
634
543
 
@@ -638,9 +547,9 @@ Module._extensions['.json'] = function (module, source, referrer) {
638
547
  module._type = constants.types.JSON
639
548
 
640
549
  if (protocol.load) {
641
- module._exports = protocol.load(module._filename)
550
+ module._exports = protocol.load(module._url)
642
551
  } else {
643
- if (source === null) source = protocol.read(module._filename)
552
+ if (source === null) source = protocol.read(module._url)
644
553
 
645
554
  if (typeof source !== 'string') source = Buffer.coerce(source).toString()
646
555
 
@@ -651,13 +560,13 @@ Module._extensions['.json'] = function (module, source, referrer) {
651
560
  Module._extensions['.bare'] = function (module, source, referrer) {
652
561
  module._type = constants.types.ADDON
653
562
 
654
- module._exports = Bare.Addon.load(module._filename)
563
+ module._exports = Bare.Addon.load(url.fileURLToPath(module._url))
655
564
  }
656
565
 
657
566
  Module._extensions['.node'] = function (module, source, referrer) {
658
567
  module._type = constants.types.ADDON
659
568
 
660
- module._exports = Bare.Addon.load(module._filename)
569
+ module._exports = Bare.Addon.load(url.fileURLToPath(module._url))
661
570
  }
662
571
 
663
572
  Module._extensions['.bundle'] = function (module, source, referrer) {
@@ -667,55 +576,43 @@ Module._extensions['.bundle'] = function (module, source, referrer) {
667
576
 
668
577
  module._type = constants.types.BUNDLE
669
578
 
670
- if (source === null) source = protocol.read(module._filename)
579
+ if (source === null) source = protocol.read(module._url)
671
580
 
672
581
  if (typeof source === 'string') source = Buffer.from(source)
673
582
 
674
583
  referrer = module
675
584
 
676
- const bundle = module._bundle = Bundle.from(source).mount(module._filename)
585
+ const bundle = module._bundle = Bundle.from(source).mount(module._url.href + '/')
677
586
 
678
587
  module._imports = bundle.imports
679
588
  module._resolutions = bundle.resolutions
680
589
 
681
590
  module._protocol = new Protocol({
682
- exists (filename) {
683
- return bundle.exists(filename)
591
+ exists (url) {
592
+ return bundle.exists(url.href)
684
593
  },
685
594
 
686
- read (filename) {
687
- return bundle.read(filename)
595
+ read (url) {
596
+ return bundle.read(url.href)
688
597
  }
689
598
  })
690
599
 
691
600
  if (bundle.main) {
692
- module._exports = self.load(bundle.main, bundle.read(bundle.main), { referrer })._exports
601
+ module._exports = self.load(new URL(bundle.main), bundle.read(bundle.main), { referrer })._exports
693
602
  }
694
603
  }
695
604
 
696
605
  Module._protocols['file:'] = new Protocol({
697
- postresolve (specifier) {
698
- return binding.realpath(specifier)
606
+ postresolve (fileURL) {
607
+ return url.pathToFileURL(binding.realpath(url.fileURLToPath(fileURL)))
699
608
  },
700
609
 
701
- exists (filename) {
702
- return binding.exists(filename)
610
+ exists (fileURL) {
611
+ return binding.exists(url.fileURLToPath(fileURL))
703
612
  },
704
613
 
705
- read (filename) {
706
- return Buffer.from(binding.read(filename))
707
- }
708
- })
709
-
710
- Module._protocols['data:'] = new Protocol({
711
- * resolve (specifier) {
712
- yield specifier
713
- },
714
-
715
- read (specifier) {
716
- const [, , , base64, data] = specifier.match(/data:(?:([^/]+\/[^;,]+)(;[^=]+=[^;,]+)*)?(;base64)?,(.*)/)
717
-
718
- return Buffer.from(decodeURIComponent(data), base64 ? 'base64' : 'ascii')
614
+ read (fileURL) {
615
+ return Buffer.from(binding.read(url.fileURLToPath(fileURL)))
719
616
  }
720
617
  })
721
618
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-module",
3
- "version": "2.8.2",
3
+ "version": "3.0.0",
4
4
  "description": "Module support for JavaScript",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -25,9 +25,8 @@
25
25
  },
26
26
  "homepage": "https://github.com/holepunchto/bare-module#readme",
27
27
  "dependencies": {
28
- "bare-bundle": "^0.3.4",
29
- "bare-module-resolve": "^1.3.0",
30
- "bare-os": "^2.0.0",
28
+ "bare-bundle": "^0.4.0",
29
+ "bare-module-resolve": "^1.4.1",
31
30
  "bare-path": "^2.0.0",
32
31
  "bare-url": "^0.3.4"
33
32
  },