esm: use import attributes instead of import assertions
The old import assertions proposal has been
renamed to "import attributes" with the follwing major changes:
1. The keyword is now `with` instead of `assert`.
2. Unknown assertions cause an error rather than being ignored,
This commit updates the documentation to encourage folks to use the new
syntax, and add aliases for module customization hooks.
PR-URL: https://github.com/nodejs/node/pull/50140
Fixes: https://github.com/nodejs/node/issues/50134
Refs: 159c82c5e6
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
This commit is contained in:
parent
f447a4611a
commit
d1ef6aa2db
@ -9,5 +9,7 @@ tools/github_reporter
|
|||||||
benchmark/tmp
|
benchmark/tmp
|
||||||
benchmark/fixtures
|
benchmark/fixtures
|
||||||
doc/**/*.js
|
doc/**/*.js
|
||||||
|
doc/changelogs/CHANGELOG_v1*.md
|
||||||
|
!doc/changelogs/CHANGELOG_v18.md
|
||||||
!doc/api_assets/*.js
|
!doc/api_assets/*.js
|
||||||
!.eslintrc.js
|
!.eslintrc.js
|
||||||
|
@ -18,7 +18,7 @@ const hacks = [
|
|||||||
'eslint-plugin-jsdoc',
|
'eslint-plugin-jsdoc',
|
||||||
'eslint-plugin-markdown',
|
'eslint-plugin-markdown',
|
||||||
'@babel/eslint-parser',
|
'@babel/eslint-parser',
|
||||||
'@babel/plugin-syntax-import-assertions',
|
'@babel/plugin-syntax-import-attributes',
|
||||||
];
|
];
|
||||||
Module._findPath = (request, paths, isMain) => {
|
Module._findPath = (request, paths, isMain) => {
|
||||||
const r = ModuleFindPath(request, paths, isMain);
|
const r = ModuleFindPath(request, paths, isMain);
|
||||||
@ -44,7 +44,7 @@ module.exports = {
|
|||||||
parserOptions: {
|
parserOptions: {
|
||||||
babelOptions: {
|
babelOptions: {
|
||||||
plugins: [
|
plugins: [
|
||||||
Module._findPath('@babel/plugin-syntax-import-assertions'),
|
Module._findPath('@babel/plugin-syntax-import-attributes'),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
requireConfigFile: false,
|
requireConfigFile: false,
|
||||||
|
@ -1759,7 +1759,8 @@ added:
|
|||||||
- v16.14.0
|
- v16.14.0
|
||||||
-->
|
-->
|
||||||
|
|
||||||
An import assertion has failed, preventing the specified module to be imported.
|
An import `type` attribute was provided, but the specified module is of a
|
||||||
|
different type.
|
||||||
|
|
||||||
<a id="ERR_IMPORT_ASSERTION_TYPE_MISSING"></a>
|
<a id="ERR_IMPORT_ASSERTION_TYPE_MISSING"></a>
|
||||||
|
|
||||||
@ -1771,7 +1772,7 @@ added:
|
|||||||
- v16.14.0
|
- v16.14.0
|
||||||
-->
|
-->
|
||||||
|
|
||||||
An import assertion is missing, preventing the specified module to be imported.
|
An import attribute is missing, preventing the specified module to be imported.
|
||||||
|
|
||||||
<a id="ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED"></a>
|
<a id="ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED"></a>
|
||||||
|
|
||||||
@ -1783,7 +1784,17 @@ added:
|
|||||||
- v16.14.0
|
- v16.14.0
|
||||||
-->
|
-->
|
||||||
|
|
||||||
An import assertion is not supported by this version of Node.js.
|
An import attribute is not supported by this version of Node.js.
|
||||||
|
|
||||||
|
<a id="ERR_IMPORT_ATTRIBUTE_UNSUPPORTED"></a>
|
||||||
|
|
||||||
|
### `ERR_IMPORT_ATTRIBUTE_UNSUPPORTED`
|
||||||
|
|
||||||
|
<!-- YAML
|
||||||
|
added: REPLACEME
|
||||||
|
-->
|
||||||
|
|
||||||
|
An import attribute is not supported by this version of Node.js.
|
||||||
|
|
||||||
<a id="ERR_INCOMPATIBLE_OPTION_PAIR"></a>
|
<a id="ERR_INCOMPATIBLE_OPTION_PAIR"></a>
|
||||||
|
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v8.5.0
|
added: v8.5.0
|
||||||
changes:
|
changes:
|
||||||
|
- version: REPLACEME
|
||||||
|
pr-url: https://github.com/nodejs/node/pull/50140
|
||||||
|
description: Add experimental support for import attributes.
|
||||||
- version: v20.0.0
|
- version: v20.0.0
|
||||||
pr-url: https://github.com/nodejs/node/pull/44710
|
pr-url: https://github.com/nodejs/node/pull/44710
|
||||||
description: Module customization hooks are executed off the main thread.
|
description: Module customization hooks are executed off the main thread.
|
||||||
@ -19,7 +22,7 @@ changes:
|
|||||||
- v17.1.0
|
- v17.1.0
|
||||||
- v16.14.0
|
- v16.14.0
|
||||||
pr-url: https://github.com/nodejs/node/pull/40250
|
pr-url: https://github.com/nodejs/node/pull/40250
|
||||||
description: Add support for import assertions.
|
description: Add experimental support for import assertions.
|
||||||
- version:
|
- version:
|
||||||
- v17.0.0
|
- v17.0.0
|
||||||
- v16.12.0
|
- v16.12.0
|
||||||
@ -203,7 +206,7 @@ added: v12.10.0
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
import 'data:text/javascript,console.log("hello!");';
|
import 'data:text/javascript,console.log("hello!");';
|
||||||
import _ from 'data:application/json,"world!"' assert { type: 'json' };
|
import _ from 'data:application/json,"world!"' with { type: 'json' };
|
||||||
```
|
```
|
||||||
|
|
||||||
`data:` URLs only resolve [bare specifiers][Terminology] for builtin modules
|
`data:` URLs only resolve [bare specifiers][Terminology] for builtin modules
|
||||||
@ -235,30 +238,40 @@ absolute URL strings.
|
|||||||
import fs from 'node:fs/promises';
|
import fs from 'node:fs/promises';
|
||||||
```
|
```
|
||||||
|
|
||||||
## Import assertions
|
<a id="import-assertions"></a>
|
||||||
|
|
||||||
|
## Import attributes
|
||||||
|
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added:
|
added:
|
||||||
- v17.1.0
|
- v17.1.0
|
||||||
- v16.14.0
|
- v16.14.0
|
||||||
|
changes:
|
||||||
|
- version: REPLACEME
|
||||||
|
pr-url: https://github.com/nodejs/node/pull/50140
|
||||||
|
description: Switch from Import Assertions to Import Attributes.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
> Stability: 1 - Experimental
|
> Stability: 1.1 - Active development
|
||||||
|
|
||||||
The [Import Assertions proposal][] adds an inline syntax for module import
|
> This feature was previously named "Import assertions", and using the `assert`
|
||||||
|
> keyword instead of `with`. Any uses in code of the prior `assert` keyword
|
||||||
|
> should be updated to use `with` instead.
|
||||||
|
|
||||||
|
The [Import Attributes proposal][] adds an inline syntax for module import
|
||||||
statements to pass on more information alongside the module specifier.
|
statements to pass on more information alongside the module specifier.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import fooData from './foo.json' assert { type: 'json' };
|
import fooData from './foo.json' with { type: 'json' };
|
||||||
|
|
||||||
const { default: barData } =
|
const { default: barData } =
|
||||||
await import('./bar.json', { assert: { type: 'json' } });
|
await import('./bar.json', { with: { type: 'json' } });
|
||||||
```
|
```
|
||||||
|
|
||||||
Node.js supports the following `type` values, for which the assertion is
|
Node.js supports the following `type` values, for which the attribute is
|
||||||
mandatory:
|
mandatory:
|
||||||
|
|
||||||
| Assertion `type` | Needed for |
|
| Attribute `type` | Needed for |
|
||||||
| ---------------- | ---------------- |
|
| ---------------- | ---------------- |
|
||||||
| `'json'` | [JSON modules][] |
|
| `'json'` | [JSON modules][] |
|
||||||
|
|
||||||
@ -545,10 +558,10 @@ separate cache.
|
|||||||
JSON files can be referenced by `import`:
|
JSON files can be referenced by `import`:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import packageConfig from './package.json' assert { type: 'json' };
|
import packageConfig from './package.json' with { type: 'json' };
|
||||||
```
|
```
|
||||||
|
|
||||||
The `assert { type: 'json' }` syntax is mandatory; see [Import Assertions][].
|
The `with { type: 'json' }` syntax is mandatory; see [Import Attributes][].
|
||||||
|
|
||||||
The imported JSON only exposes a `default` export. There is no support for named
|
The imported JSON only exposes a `default` export. There is no support for named
|
||||||
exports. A cache entry is created in the CommonJS cache to avoid duplication.
|
exports. A cache entry is created in the CommonJS cache to avoid duplication.
|
||||||
@ -1055,8 +1068,8 @@ resolution for ESM specifiers is [commonjs-extension-resolution-loader][].
|
|||||||
[Determining module system]: packages.md#determining-module-system
|
[Determining module system]: packages.md#determining-module-system
|
||||||
[Dynamic `import()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import
|
[Dynamic `import()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import
|
||||||
[ES Module Integration Proposal for WebAssembly]: https://github.com/webassembly/esm-integration
|
[ES Module Integration Proposal for WebAssembly]: https://github.com/webassembly/esm-integration
|
||||||
[Import Assertions]: #import-assertions
|
[Import Attributes]: #import-attributes
|
||||||
[Import Assertions proposal]: https://github.com/tc39/proposal-import-assertions
|
[Import Attributes proposal]: https://github.com/tc39/proposal-import-attributes
|
||||||
[JSON modules]: #json-modules
|
[JSON modules]: #json-modules
|
||||||
[Module customization hooks]: module.md#customization-hooks
|
[Module customization hooks]: module.md#customization-hooks
|
||||||
[Node.js Module Resolution And Loading Algorithm]: #resolution-algorithm-specification
|
[Node.js Module Resolution And Loading Algorithm]: #resolution-algorithm-specification
|
||||||
|
@ -458,6 +458,11 @@ register('./path-to-my-hooks.js', {
|
|||||||
|
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
changes:
|
changes:
|
||||||
|
- version: REPLACEME
|
||||||
|
pr-url: https://github.com/nodejs/node/pull/50140
|
||||||
|
description: The property `context.importAssertions` is replaced with
|
||||||
|
`context.importAttributes`. Using the old name is still
|
||||||
|
supported and will emit an experimental warning.
|
||||||
- version:
|
- version:
|
||||||
- v18.6.0
|
- v18.6.0
|
||||||
- v16.17.0
|
- v16.17.0
|
||||||
@ -477,8 +482,8 @@ changes:
|
|||||||
* `specifier` {string}
|
* `specifier` {string}
|
||||||
* `context` {Object}
|
* `context` {Object}
|
||||||
* `conditions` {string\[]} Export conditions of the relevant `package.json`
|
* `conditions` {string\[]} Export conditions of the relevant `package.json`
|
||||||
* `importAssertions` {Object} An object whose key-value pairs represent the
|
* `importAttributes` {Object} An object whose key-value pairs represent the
|
||||||
assertions for the module to import
|
attributes for the module to import
|
||||||
* `parentURL` {string|undefined} The module importing this one, or undefined
|
* `parentURL` {string|undefined} The module importing this one, or undefined
|
||||||
if this is the Node.js entry point
|
if this is the Node.js entry point
|
||||||
* `nextResolve` {Function} The subsequent `resolve` hook in the chain, or the
|
* `nextResolve` {Function} The subsequent `resolve` hook in the chain, or the
|
||||||
@ -489,7 +494,7 @@ changes:
|
|||||||
* `format` {string|null|undefined} A hint to the load hook (it might be
|
* `format` {string|null|undefined} A hint to the load hook (it might be
|
||||||
ignored)
|
ignored)
|
||||||
`'builtin' | 'commonjs' | 'json' | 'module' | 'wasm'`
|
`'builtin' | 'commonjs' | 'json' | 'module' | 'wasm'`
|
||||||
* `importAssertions` {Object|undefined} The import assertions to use when
|
* `importAttributes` {Object|undefined} The import attributes to use when
|
||||||
caching the module (optional; if excluded the input will be used)
|
caching the module (optional; if excluded the input will be used)
|
||||||
* `shortCircuit` {undefined|boolean} A signal that this hook intends to
|
* `shortCircuit` {undefined|boolean} A signal that this hook intends to
|
||||||
terminate the chain of `resolve` hooks. **Default:** `false`
|
terminate the chain of `resolve` hooks. **Default:** `false`
|
||||||
@ -506,10 +511,10 @@ the final `format` value (and it is free to ignore the hint provided by
|
|||||||
`resolve`); if `resolve` provides a `format`, a custom `load` hook is required
|
`resolve`); if `resolve` provides a `format`, a custom `load` hook is required
|
||||||
even if only to pass the value to the Node.js default `load` hook.
|
even if only to pass the value to the Node.js default `load` hook.
|
||||||
|
|
||||||
Import type assertions are part of the cache key for saving loaded modules into
|
Import type attributes are part of the cache key for saving loaded modules into
|
||||||
the internal module cache. The `resolve` hook is responsible for returning an
|
the internal module cache. The `resolve` hook is responsible for returning an
|
||||||
`importAssertions` object if the module should be cached with different
|
`importAttributes` object if the module should be cached with different
|
||||||
assertions than were present in the source code.
|
attributes than were present in the source code.
|
||||||
|
|
||||||
The `conditions` property in `context` is an array of conditions for
|
The `conditions` property in `context` is an array of conditions for
|
||||||
[package exports conditions][Conditional exports] that apply to this resolution
|
[package exports conditions][Conditional exports] that apply to this resolution
|
||||||
@ -575,7 +580,7 @@ changes:
|
|||||||
* `conditions` {string\[]} Export conditions of the relevant `package.json`
|
* `conditions` {string\[]} Export conditions of the relevant `package.json`
|
||||||
* `format` {string|null|undefined} The format optionally supplied by the
|
* `format` {string|null|undefined} The format optionally supplied by the
|
||||||
`resolve` hook chain
|
`resolve` hook chain
|
||||||
* `importAssertions` {Object}
|
* `importAttributes` {Object}
|
||||||
* `nextLoad` {Function} The subsequent `load` hook in the chain, or the
|
* `nextLoad` {Function} The subsequent `load` hook in the chain, or the
|
||||||
Node.js default `load` hook after the last user-supplied `load` hook
|
Node.js default `load` hook after the last user-supplied `load` hook
|
||||||
* `specifier` {string}
|
* `specifier` {string}
|
||||||
|
@ -1280,12 +1280,17 @@ E('ERR_HTTP_SOCKET_ENCODING',
|
|||||||
E('ERR_HTTP_TRAILER_INVALID',
|
E('ERR_HTTP_TRAILER_INVALID',
|
||||||
'Trailers are invalid with this transfer encoding', Error);
|
'Trailers are invalid with this transfer encoding', Error);
|
||||||
E('ERR_ILLEGAL_CONSTRUCTOR', 'Illegal constructor', TypeError);
|
E('ERR_ILLEGAL_CONSTRUCTOR', 'Illegal constructor', TypeError);
|
||||||
|
// TODO(aduh95): change the error to mention import attributes instead of import assertions.
|
||||||
E('ERR_IMPORT_ASSERTION_TYPE_FAILED',
|
E('ERR_IMPORT_ASSERTION_TYPE_FAILED',
|
||||||
'Module "%s" is not of type "%s"', TypeError);
|
'Module "%s" is not of type "%s"', TypeError);
|
||||||
|
// TODO(aduh95): change the error to mention import attributes instead of import assertions.
|
||||||
E('ERR_IMPORT_ASSERTION_TYPE_MISSING',
|
E('ERR_IMPORT_ASSERTION_TYPE_MISSING',
|
||||||
'Module "%s" needs an import assertion of type "%s"', TypeError);
|
'Module "%s" needs an import attribute of type "%s"', TypeError);
|
||||||
|
// TODO(aduh95): change the error to mention import attributes instead of import assertions.
|
||||||
E('ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED',
|
E('ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED',
|
||||||
'Import assertion type "%s" is unsupported', TypeError);
|
'Import attribute type "%s" is unsupported', TypeError);
|
||||||
|
E('ERR_IMPORT_ATTRIBUTE_UNSUPPORTED',
|
||||||
|
'Import attribute "%s" with value "%s" is not supported', TypeError);
|
||||||
E('ERR_INCOMPATIBLE_OPTION_PAIR',
|
E('ERR_INCOMPATIBLE_OPTION_PAIR',
|
||||||
'Option "%s" cannot be used in combination with option "%s"', TypeError);
|
'Option "%s" cannot be used in combination with option "%s"', TypeError);
|
||||||
E('ERR_INPUT_TYPE_NOT_ALLOWED', '--input-type can only be used with string ' +
|
E('ERR_INPUT_TYPE_NOT_ALLOWED', '--input-type can only be used with string ' +
|
||||||
|
@ -1258,10 +1258,10 @@ function wrapSafe(filename, content, cjsModuleInstance, codeCache) {
|
|||||||
const script = new Script(wrapper, {
|
const script = new Script(wrapper, {
|
||||||
filename,
|
filename,
|
||||||
lineOffset: 0,
|
lineOffset: 0,
|
||||||
importModuleDynamically: async (specifier, _, importAssertions) => {
|
importModuleDynamically: async (specifier, _, importAttributes) => {
|
||||||
const cascadedLoader = getCascadedLoader();
|
const cascadedLoader = getCascadedLoader();
|
||||||
return cascadedLoader.import(specifier, normalizeReferrerURL(filename),
|
return cascadedLoader.import(specifier, normalizeReferrerURL(filename),
|
||||||
importAssertions);
|
importAttributes);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1285,10 +1285,10 @@ function wrapSafe(filename, content, cjsModuleInstance, codeCache) {
|
|||||||
], {
|
], {
|
||||||
filename,
|
filename,
|
||||||
cachedData: codeCache,
|
cachedData: codeCache,
|
||||||
importModuleDynamically(specifier, _, importAssertions) {
|
importModuleDynamically(specifier, _, importAttributes) {
|
||||||
const cascadedLoader = getCascadedLoader();
|
const cascadedLoader = getCascadedLoader();
|
||||||
return cascadedLoader.import(specifier, normalizeReferrerURL(filename),
|
return cascadedLoader.import(specifier, normalizeReferrerURL(filename),
|
||||||
importAssertions);
|
importAttributes);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -13,16 +13,15 @@ const {
|
|||||||
ERR_IMPORT_ASSERTION_TYPE_FAILED,
|
ERR_IMPORT_ASSERTION_TYPE_FAILED,
|
||||||
ERR_IMPORT_ASSERTION_TYPE_MISSING,
|
ERR_IMPORT_ASSERTION_TYPE_MISSING,
|
||||||
ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED,
|
ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED,
|
||||||
|
ERR_IMPORT_ATTRIBUTE_UNSUPPORTED,
|
||||||
} = require('internal/errors').codes;
|
} = require('internal/errors').codes;
|
||||||
|
|
||||||
// The HTML spec has an implied default type of `'javascript'`.
|
// The HTML spec has an implied default type of `'javascript'`.
|
||||||
const kImplicitAssertType = 'javascript';
|
const kImplicitAssertType = 'javascript';
|
||||||
|
|
||||||
let alreadyWarned = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define a map of module formats to import assertion types (the value of
|
* Define a map of module formats to import attributes types (the value of
|
||||||
* `type` in `assert { type: 'json' }`).
|
* `type` in `with { type: 'json' }`).
|
||||||
* @type {Map<string, string>}
|
* @type {Map<string, string>}
|
||||||
*/
|
*/
|
||||||
const formatTypeMap = {
|
const formatTypeMap = {
|
||||||
@ -31,13 +30,13 @@ const formatTypeMap = {
|
|||||||
'commonjs': kImplicitAssertType,
|
'commonjs': kImplicitAssertType,
|
||||||
'json': 'json',
|
'json': 'json',
|
||||||
'module': kImplicitAssertType,
|
'module': kImplicitAssertType,
|
||||||
'wasm': kImplicitAssertType, // It's unclear whether the HTML spec will require an assertion type or not for Wasm; see https://github.com/WebAssembly/esm-integration/issues/42
|
'wasm': kImplicitAssertType, // It's unclear whether the HTML spec will require an attribute type or not for Wasm; see https://github.com/WebAssembly/esm-integration/issues/42
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The HTML spec disallows the default type to be explicitly specified
|
* The HTML spec disallows the default type to be explicitly specified
|
||||||
* (for now); so `import './file.js'` is okay but
|
* (for now); so `import './file.js'` is okay but
|
||||||
* `import './file.js' assert { type: 'javascript' }` throws.
|
* `import './file.js' with { type: 'javascript' }` throws.
|
||||||
* @type {Array<string, string>}
|
* @type {Array<string, string>}
|
||||||
*/
|
*/
|
||||||
const supportedAssertionTypes = ArrayPrototypeFilter(
|
const supportedAssertionTypes = ArrayPrototypeFilter(
|
||||||
@ -46,54 +45,50 @@ const supportedAssertionTypes = ArrayPrototypeFilter(
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test a module's import assertions.
|
* Test a module's import attributes.
|
||||||
* @param {string} url The URL of the imported module, for error reporting.
|
* @param {string} url The URL of the imported module, for error reporting.
|
||||||
* @param {string} format One of Node's supported translators
|
* @param {string} format One of Node's supported translators
|
||||||
* @param {Record<string, string>} importAssertions Validations for the
|
* @param {Record<string, string>} importAttributes Validations for the
|
||||||
* module import.
|
* module import.
|
||||||
* @returns {true}
|
* @returns {true}
|
||||||
* @throws {TypeError} If the format and assertion type are incompatible.
|
* @throws {TypeError} If the format and assertion type are incompatible.
|
||||||
*/
|
*/
|
||||||
function validateAssertions(url, format,
|
function validateAttributes(url, format,
|
||||||
importAssertions = { __proto__: null }) {
|
importAttributes = { __proto__: null }) {
|
||||||
const validType = formatTypeMap[format];
|
const keys = ObjectKeys(importAttributes);
|
||||||
|
for (let i = 0; i < keys.length; i++) {
|
||||||
if (!alreadyWarned && ObjectKeys(importAssertions).length !== 0) {
|
if (keys[i] !== 'type') {
|
||||||
alreadyWarned = true;
|
throw new ERR_IMPORT_ATTRIBUTE_UNSUPPORTED(keys[i], importAttributes[keys[i]]);
|
||||||
process.emitWarning(
|
}
|
||||||
'Import assertions are not a stable feature of the JavaScript language. ' +
|
|
||||||
'Avoid relying on their current behavior and syntax as those might change ' +
|
|
||||||
'in a future version of Node.js.',
|
|
||||||
'ExperimentalWarning',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
const validType = formatTypeMap[format];
|
||||||
|
|
||||||
switch (validType) {
|
switch (validType) {
|
||||||
case undefined:
|
case undefined:
|
||||||
// Ignore assertions for module formats we don't recognize, to allow new
|
// Ignore attributes for module formats we don't recognize, to allow new
|
||||||
// formats in the future.
|
// formats in the future.
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case kImplicitAssertType:
|
case kImplicitAssertType:
|
||||||
// This format doesn't allow an import assertion type, so the property
|
// This format doesn't allow an import assertion type, so the property
|
||||||
// must not be set on the import assertions object.
|
// must not be set on the import attributes object.
|
||||||
if (!ObjectPrototypeHasOwnProperty(importAssertions, 'type')) {
|
if (!ObjectPrototypeHasOwnProperty(importAttributes, 'type')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return handleInvalidType(url, importAssertions.type);
|
return handleInvalidType(url, importAttributes.type);
|
||||||
|
|
||||||
case importAssertions.type:
|
case importAttributes.type:
|
||||||
// The asserted type is the valid type for this format.
|
// The asserted type is the valid type for this format.
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// There is an expected type for this format, but the value of
|
// There is an expected type for this format, but the value of
|
||||||
// `importAssertions.type` might not have been it.
|
// `importAttributes.type` might not have been it.
|
||||||
if (!ObjectPrototypeHasOwnProperty(importAssertions, 'type')) {
|
if (!ObjectPrototypeHasOwnProperty(importAttributes, 'type')) {
|
||||||
// `type` wasn't specified at all.
|
// `type` wasn't specified at all.
|
||||||
throw new ERR_IMPORT_ASSERTION_TYPE_MISSING(url, validType);
|
throw new ERR_IMPORT_ASSERTION_TYPE_MISSING(url, validType);
|
||||||
}
|
}
|
||||||
return handleInvalidType(url, importAssertions.type);
|
return handleInvalidType(url, importAttributes.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,5 +113,5 @@ function handleInvalidType(url, type) {
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
kImplicitAssertType,
|
kImplicitAssertType,
|
||||||
validateAssertions,
|
validateAttributes,
|
||||||
};
|
};
|
||||||
|
@ -11,6 +11,7 @@ const {
|
|||||||
ObjectDefineProperty,
|
ObjectDefineProperty,
|
||||||
ObjectSetPrototypeOf,
|
ObjectSetPrototypeOf,
|
||||||
Promise,
|
Promise,
|
||||||
|
ReflectSet,
|
||||||
SafeSet,
|
SafeSet,
|
||||||
StringPrototypeSlice,
|
StringPrototypeSlice,
|
||||||
StringPrototypeToUpperCase,
|
StringPrototypeToUpperCase,
|
||||||
@ -65,6 +66,30 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
|
|||||||
});
|
});
|
||||||
let importMetaInitializer;
|
let importMetaInitializer;
|
||||||
|
|
||||||
|
let importAssertionAlreadyWarned = false;
|
||||||
|
|
||||||
|
function emitImportAssertionWarning() {
|
||||||
|
if (!importAssertionAlreadyWarned) {
|
||||||
|
importAssertionAlreadyWarned = true;
|
||||||
|
process.emitWarning('Use `importAttributes` instead of `importAssertions`', 'ExperimentalWarning');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function defineImportAssertionAlias(context) {
|
||||||
|
return ObjectDefineProperty(context, 'importAssertions', {
|
||||||
|
__proto__: null,
|
||||||
|
configurable: true,
|
||||||
|
get() {
|
||||||
|
emitImportAssertionWarning();
|
||||||
|
return this.importAttributes;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
emitImportAssertionWarning();
|
||||||
|
return ReflectSet(this, 'importAttributes', value);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {object} ExportedHooks
|
* @typedef {object} ExportedHooks
|
||||||
* @property {Function} resolve Resolve hook.
|
* @property {Function} resolve Resolve hook.
|
||||||
@ -164,21 +189,21 @@ class Hooks {
|
|||||||
* @param {string} originalSpecifier The specified URL path of the module to
|
* @param {string} originalSpecifier The specified URL path of the module to
|
||||||
* be resolved.
|
* be resolved.
|
||||||
* @param {string} [parentURL] The URL path of the module's parent.
|
* @param {string} [parentURL] The URL path of the module's parent.
|
||||||
* @param {ImportAssertions} [importAssertions] Assertions from the import
|
* @param {ImportAttributes} [importAttributes] Attributes from the import
|
||||||
* statement or expression.
|
* statement or expression.
|
||||||
* @returns {Promise<{ format: string, url: URL['href'] }>}
|
* @returns {Promise<{ format: string, url: URL['href'] }>}
|
||||||
*/
|
*/
|
||||||
async resolve(
|
async resolve(
|
||||||
originalSpecifier,
|
originalSpecifier,
|
||||||
parentURL,
|
parentURL,
|
||||||
importAssertions = { __proto__: null },
|
importAttributes = { __proto__: null },
|
||||||
) {
|
) {
|
||||||
throwIfInvalidParentURL(parentURL);
|
throwIfInvalidParentURL(parentURL);
|
||||||
|
|
||||||
const chain = this.#chains.resolve;
|
const chain = this.#chains.resolve;
|
||||||
const context = {
|
const context = {
|
||||||
conditions: getDefaultConditions(),
|
conditions: getDefaultConditions(),
|
||||||
importAssertions,
|
importAttributes,
|
||||||
parentURL,
|
parentURL,
|
||||||
};
|
};
|
||||||
const meta = {
|
const meta = {
|
||||||
@ -220,9 +245,9 @@ class Hooks {
|
|||||||
throw new ERR_LOADER_CHAIN_INCOMPLETE(hookErrIdentifier);
|
throw new ERR_LOADER_CHAIN_INCOMPLETE(hookErrIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let resolvedImportAttributes;
|
||||||
const {
|
const {
|
||||||
format,
|
format,
|
||||||
importAssertions: resolvedImportAssertions,
|
|
||||||
url,
|
url,
|
||||||
} = resolution;
|
} = resolution;
|
||||||
|
|
||||||
@ -252,15 +277,22 @@ class Hooks {
|
|||||||
this.#validatedUrls.add(url);
|
this.#validatedUrls.add(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!('importAttributes' in resolution) && ('importAssertions' in resolution)) {
|
||||||
|
emitImportAssertionWarning();
|
||||||
|
resolvedImportAttributes = resolution.importAssertions;
|
||||||
|
} else {
|
||||||
|
resolvedImportAttributes = resolution.importAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
resolvedImportAssertions != null &&
|
resolvedImportAttributes != null &&
|
||||||
typeof resolvedImportAssertions !== 'object'
|
typeof resolvedImportAttributes !== 'object'
|
||||||
) {
|
) {
|
||||||
throw new ERR_INVALID_RETURN_PROPERTY_VALUE(
|
throw new ERR_INVALID_RETURN_PROPERTY_VALUE(
|
||||||
'an object',
|
'an object',
|
||||||
hookErrIdentifier,
|
hookErrIdentifier,
|
||||||
'importAssertions',
|
'importAttributes',
|
||||||
resolvedImportAssertions,
|
resolvedImportAttributes,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,12 +311,12 @@ class Hooks {
|
|||||||
return {
|
return {
|
||||||
__proto__: null,
|
__proto__: null,
|
||||||
format,
|
format,
|
||||||
importAssertions: resolvedImportAssertions,
|
importAttributes: resolvedImportAttributes,
|
||||||
url,
|
url,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveSync(_originalSpecifier, _parentURL, _importAssertions) {
|
resolveSync(_originalSpecifier, _parentURL, _importAttributes) {
|
||||||
throw new ERR_METHOD_NOT_IMPLEMENTED('resolveSync()');
|
throw new ERR_METHOD_NOT_IMPLEMENTED('resolveSync()');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,7 +379,7 @@ class Hooks {
|
|||||||
|
|
||||||
const nextLoad = nextHookFactory(chain[chain.length - 1], meta, { validateArgs, validateOutput });
|
const nextLoad = nextHookFactory(chain[chain.length - 1], meta, { validateArgs, validateOutput });
|
||||||
|
|
||||||
const loaded = await nextLoad(url, context);
|
const loaded = await nextLoad(url, defineImportAssertionAlias(context));
|
||||||
const { hookErrIdentifier } = meta; // Retrieve the value after all settled
|
const { hookErrIdentifier } = meta; // Retrieve the value after all settled
|
||||||
|
|
||||||
validateOutput(hookErrIdentifier, loaded);
|
validateOutput(hookErrIdentifier, loaded);
|
||||||
|
@ -8,7 +8,7 @@ const {
|
|||||||
const { kEmptyObject } = require('internal/util');
|
const { kEmptyObject } = require('internal/util');
|
||||||
|
|
||||||
const { defaultGetFormat } = require('internal/modules/esm/get_format');
|
const { defaultGetFormat } = require('internal/modules/esm/get_format');
|
||||||
const { validateAssertions } = require('internal/modules/esm/assert');
|
const { validateAttributes, emitImportAssertionWarning } = require('internal/modules/esm/assert');
|
||||||
const { getOptionValue } = require('internal/options');
|
const { getOptionValue } = require('internal/options');
|
||||||
const { readFileSync } = require('fs');
|
const { readFileSync } = require('fs');
|
||||||
|
|
||||||
@ -107,19 +107,29 @@ function getSourceSync(url, context) {
|
|||||||
*/
|
*/
|
||||||
async function defaultLoad(url, context = kEmptyObject) {
|
async function defaultLoad(url, context = kEmptyObject) {
|
||||||
let responseURL = url;
|
let responseURL = url;
|
||||||
const { importAssertions } = context;
|
|
||||||
let {
|
let {
|
||||||
|
importAttributes,
|
||||||
format,
|
format,
|
||||||
source,
|
source,
|
||||||
} = context;
|
} = context;
|
||||||
|
|
||||||
|
if (importAttributes == null && !('importAttributes' in context) && 'importAssertions' in context) {
|
||||||
|
emitImportAssertionWarning();
|
||||||
|
importAttributes = context.importAssertions;
|
||||||
|
// Alias `importAssertions` to `importAttributes`
|
||||||
|
context = {
|
||||||
|
...context,
|
||||||
|
importAttributes,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const urlInstance = new URL(url);
|
const urlInstance = new URL(url);
|
||||||
|
|
||||||
throwIfUnsupportedURLScheme(urlInstance, experimentalNetworkImports);
|
throwIfUnsupportedURLScheme(urlInstance, experimentalNetworkImports);
|
||||||
|
|
||||||
format ??= await defaultGetFormat(urlInstance, context);
|
format ??= await defaultGetFormat(urlInstance, context);
|
||||||
|
|
||||||
validateAssertions(url, format, importAssertions);
|
validateAttributes(url, format, importAttributes);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
format === 'builtin' ||
|
format === 'builtin' ||
|
||||||
@ -141,7 +151,7 @@ async function defaultLoad(url, context = kEmptyObject) {
|
|||||||
* @typedef LoadContext
|
* @typedef LoadContext
|
||||||
* @property {string} [format] A hint (possibly returned from `resolve`)
|
* @property {string} [format] A hint (possibly returned from `resolve`)
|
||||||
* @property {string | Buffer | ArrayBuffer} [source] source
|
* @property {string | Buffer | ArrayBuffer} [source] source
|
||||||
* @property {Record<string, string>} [importAssertions] import attributes
|
* @property {Record<string, string>} [importAttributes] import attributes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -158,7 +168,7 @@ async function defaultLoad(url, context = kEmptyObject) {
|
|||||||
*/
|
*/
|
||||||
function defaultLoadSync(url, context = kEmptyObject) {
|
function defaultLoadSync(url, context = kEmptyObject) {
|
||||||
let responseURL = url;
|
let responseURL = url;
|
||||||
const { importAssertions } = context;
|
const { importAttributes } = context;
|
||||||
let {
|
let {
|
||||||
format,
|
format,
|
||||||
source,
|
source,
|
||||||
@ -170,7 +180,7 @@ function defaultLoadSync(url, context = kEmptyObject) {
|
|||||||
|
|
||||||
format ??= defaultGetFormat(urlInstance, context);
|
format ??= defaultGetFormat(urlInstance, context);
|
||||||
|
|
||||||
validateAssertions(url, format, importAssertions);
|
validateAttributes(url, format, importAttributes);
|
||||||
|
|
||||||
if (format === 'builtin') {
|
if (format === 'builtin') {
|
||||||
source = null;
|
source = null;
|
||||||
|
@ -165,12 +165,12 @@ class ModuleLoader {
|
|||||||
* resolve(
|
* resolve(
|
||||||
* originalSpecifier:
|
* originalSpecifier:
|
||||||
* string, parentURL: string,
|
* string, parentURL: string,
|
||||||
* importAssertions: Record<string, string>
|
* importAttributes: Record<string, string>
|
||||||
* ): Promise<ResolveResult>
|
* ): Promise<ResolveResult>
|
||||||
* resolveSync(
|
* resolveSync(
|
||||||
* originalSpecifier:
|
* originalSpecifier:
|
||||||
* string, parentURL: string,
|
* string, parentURL: string,
|
||||||
* importAssertions: Record<string, string>
|
* importAttributes: Record<string, string>
|
||||||
* ) ResolveResult;
|
* ) ResolveResult;
|
||||||
* register(specifier: string, parentURL: string): any;
|
* register(specifier: string, parentURL: string): any;
|
||||||
* forceLoadHooks(): void;
|
* forceLoadHooks(): void;
|
||||||
@ -204,8 +204,8 @@ class ModuleLoader {
|
|||||||
registerModule(module, {
|
registerModule(module, {
|
||||||
__proto__: null,
|
__proto__: null,
|
||||||
initializeImportMeta: (meta, wrap) => this.importMetaInitialize(meta, { url }),
|
initializeImportMeta: (meta, wrap) => this.importMetaInitialize(meta, { url }),
|
||||||
importModuleDynamically: (specifier, { url }, importAssertions) => {
|
importModuleDynamically: (specifier, { url }, importAttributes) => {
|
||||||
return this.import(specifier, url, importAssertions);
|
return this.import(specifier, url, importAttributes);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -232,24 +232,24 @@ class ModuleLoader {
|
|||||||
* @param {string | undefined} parentURL The URL of the module importing this
|
* @param {string | undefined} parentURL The URL of the module importing this
|
||||||
* one, unless this is the Node.js entry
|
* one, unless this is the Node.js entry
|
||||||
* point.
|
* point.
|
||||||
* @param {Record<string, string>} importAssertions Validations for the
|
* @param {Record<string, string>} importAttributes Validations for the
|
||||||
* module import.
|
* module import.
|
||||||
* @returns {Promise<ModuleJob>} The (possibly pending) module job
|
* @returns {Promise<ModuleJob>} The (possibly pending) module job
|
||||||
*/
|
*/
|
||||||
async getModuleJob(specifier, parentURL, importAssertions) {
|
async getModuleJob(specifier, parentURL, importAttributes) {
|
||||||
const resolveResult = await this.resolve(specifier, parentURL, importAssertions);
|
const resolveResult = await this.resolve(specifier, parentURL, importAttributes);
|
||||||
return this.getJobFromResolveResult(resolveResult, parentURL, importAssertions);
|
return this.getJobFromResolveResult(resolveResult, parentURL, importAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
getModuleJobSync(specifier, parentURL, importAssertions) {
|
getModuleJobSync(specifier, parentURL, importAttributes) {
|
||||||
const resolveResult = this.resolveSync(specifier, parentURL, importAssertions);
|
const resolveResult = this.resolveSync(specifier, parentURL, importAttributes);
|
||||||
return this.getJobFromResolveResult(resolveResult, parentURL, importAssertions, true);
|
return this.getJobFromResolveResult(resolveResult, parentURL, importAttributes, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
getJobFromResolveResult(resolveResult, parentURL, importAssertions, sync) {
|
getJobFromResolveResult(resolveResult, parentURL, importAttributes, sync) {
|
||||||
const { url, format } = resolveResult;
|
const { url, format } = resolveResult;
|
||||||
const resolvedImportAssertions = resolveResult.importAssertions ?? importAssertions;
|
const resolvedImportAttributes = resolveResult.importAttributes ?? importAttributes;
|
||||||
let job = this.loadCache.get(url, resolvedImportAssertions.type);
|
let job = this.loadCache.get(url, resolvedImportAttributes.type);
|
||||||
|
|
||||||
// CommonJS will set functions for lazy job evaluation.
|
// CommonJS will set functions for lazy job evaluation.
|
||||||
if (typeof job === 'function') {
|
if (typeof job === 'function') {
|
||||||
@ -257,7 +257,7 @@ class ModuleLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (job === undefined) {
|
if (job === undefined) {
|
||||||
job = this.#createModuleJob(url, resolvedImportAssertions, parentURL, format, sync);
|
job = this.#createModuleJob(url, resolvedImportAttributes, parentURL, format, sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
return job;
|
return job;
|
||||||
@ -266,7 +266,7 @@ class ModuleLoader {
|
|||||||
/**
|
/**
|
||||||
* Create and cache an object representing a loaded module.
|
* Create and cache an object representing a loaded module.
|
||||||
* @param {string} url The absolute URL that was resolved for this module
|
* @param {string} url The absolute URL that was resolved for this module
|
||||||
* @param {Record<string, string>} importAssertions Validations for the
|
* @param {Record<string, string>} importAttributes Validations for the
|
||||||
* module import.
|
* module import.
|
||||||
* @param {string} [parentURL] The absolute URL of the module importing this
|
* @param {string} [parentURL] The absolute URL of the module importing this
|
||||||
* one, unless this is the Node.js entry point
|
* one, unless this is the Node.js entry point
|
||||||
@ -274,7 +274,7 @@ class ModuleLoader {
|
|||||||
* `resolve` hook
|
* `resolve` hook
|
||||||
* @returns {Promise<ModuleJob>} The (possibly pending) module job
|
* @returns {Promise<ModuleJob>} The (possibly pending) module job
|
||||||
*/
|
*/
|
||||||
#createModuleJob(url, importAssertions, parentURL, format, sync) {
|
#createModuleJob(url, importAttributes, parentURL, format, sync) {
|
||||||
const callTranslator = ({ format: finalFormat, responseURL, source }, isMain) => {
|
const callTranslator = ({ format: finalFormat, responseURL, source }, isMain) => {
|
||||||
const translator = getTranslators().get(finalFormat);
|
const translator = getTranslators().get(finalFormat);
|
||||||
|
|
||||||
@ -284,7 +284,8 @@ class ModuleLoader {
|
|||||||
|
|
||||||
return FunctionPrototypeCall(translator, this, responseURL, source, isMain);
|
return FunctionPrototypeCall(translator, this, responseURL, source, isMain);
|
||||||
};
|
};
|
||||||
const context = { format, importAssertions };
|
const context = { format, importAttributes };
|
||||||
|
|
||||||
const moduleProvider = sync ?
|
const moduleProvider = sync ?
|
||||||
(url, isMain) => callTranslator(this.loadSync(url, context), isMain) :
|
(url, isMain) => callTranslator(this.loadSync(url, context), isMain) :
|
||||||
async (url, isMain) => callTranslator(await this.load(url, context), isMain);
|
async (url, isMain) => callTranslator(await this.load(url, context), isMain);
|
||||||
@ -302,14 +303,14 @@ class ModuleLoader {
|
|||||||
const job = new ModuleJob(
|
const job = new ModuleJob(
|
||||||
this,
|
this,
|
||||||
url,
|
url,
|
||||||
importAssertions,
|
importAttributes,
|
||||||
moduleProvider,
|
moduleProvider,
|
||||||
parentURL === undefined,
|
parentURL === undefined,
|
||||||
inspectBrk,
|
inspectBrk,
|
||||||
sync,
|
sync,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.loadCache.set(url, importAssertions.type, job);
|
this.loadCache.set(url, importAttributes.type, job);
|
||||||
|
|
||||||
return job;
|
return job;
|
||||||
}
|
}
|
||||||
@ -319,12 +320,12 @@ class ModuleLoader {
|
|||||||
* Use directly with caution.
|
* Use directly with caution.
|
||||||
* @param {string} specifier The first parameter of an `import()` expression.
|
* @param {string} specifier The first parameter of an `import()` expression.
|
||||||
* @param {string} parentURL Path of the parent importing the module.
|
* @param {string} parentURL Path of the parent importing the module.
|
||||||
* @param {Record<string, string>} importAssertions Validations for the
|
* @param {Record<string, string>} importAttributes Validations for the
|
||||||
* module import.
|
* module import.
|
||||||
* @returns {Promise<ModuleExports>}
|
* @returns {Promise<ModuleExports>}
|
||||||
*/
|
*/
|
||||||
async import(specifier, parentURL, importAssertions) {
|
async import(specifier, parentURL, importAttributes) {
|
||||||
const moduleJob = await this.getModuleJob(specifier, parentURL, importAssertions);
|
const moduleJob = await this.getModuleJob(specifier, parentURL, importAttributes);
|
||||||
const { module } = await moduleJob.run();
|
const { module } = await moduleJob.run();
|
||||||
return module.getNamespace();
|
return module.getNamespace();
|
||||||
}
|
}
|
||||||
@ -348,20 +349,20 @@ class ModuleLoader {
|
|||||||
* @param {string} originalSpecifier The specified URL path of the module to
|
* @param {string} originalSpecifier The specified URL path of the module to
|
||||||
* be resolved.
|
* be resolved.
|
||||||
* @param {string} [parentURL] The URL path of the module's parent.
|
* @param {string} [parentURL] The URL path of the module's parent.
|
||||||
* @param {ImportAssertions} importAssertions Assertions from the import
|
* @param {ImportAttributes} importAttributes Attributes from the import
|
||||||
* statement or expression.
|
* statement or expression.
|
||||||
* @returns {{ format: string, url: URL['href'] }}
|
* @returns {{ format: string, url: URL['href'] }}
|
||||||
*/
|
*/
|
||||||
resolve(originalSpecifier, parentURL, importAssertions) {
|
resolve(originalSpecifier, parentURL, importAttributes) {
|
||||||
if (this.#customizations) {
|
if (this.#customizations) {
|
||||||
return this.#customizations.resolve(originalSpecifier, parentURL, importAssertions);
|
return this.#customizations.resolve(originalSpecifier, parentURL, importAttributes);
|
||||||
}
|
}
|
||||||
const requestKey = this.#resolveCache.serializeKey(originalSpecifier, importAssertions);
|
const requestKey = this.#resolveCache.serializeKey(originalSpecifier, importAttributes);
|
||||||
const cachedResult = this.#resolveCache.get(requestKey, parentURL);
|
const cachedResult = this.#resolveCache.get(requestKey, parentURL);
|
||||||
if (cachedResult != null) {
|
if (cachedResult != null) {
|
||||||
return cachedResult;
|
return cachedResult;
|
||||||
}
|
}
|
||||||
const result = this.defaultResolve(originalSpecifier, parentURL, importAssertions);
|
const result = this.defaultResolve(originalSpecifier, parentURL, importAttributes);
|
||||||
this.#resolveCache.set(requestKey, parentURL, result);
|
this.#resolveCache.set(requestKey, parentURL, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -370,11 +371,11 @@ class ModuleLoader {
|
|||||||
* Just like `resolve` except synchronous. This is here specifically to support
|
* Just like `resolve` except synchronous. This is here specifically to support
|
||||||
* `import.meta.resolve` which must happen synchronously.
|
* `import.meta.resolve` which must happen synchronously.
|
||||||
*/
|
*/
|
||||||
resolveSync(originalSpecifier, parentURL, importAssertions) {
|
resolveSync(originalSpecifier, parentURL, importAttributes) {
|
||||||
if (this.#customizations) {
|
if (this.#customizations) {
|
||||||
return this.#customizations.resolveSync(originalSpecifier, parentURL, importAssertions);
|
return this.#customizations.resolveSync(originalSpecifier, parentURL, importAttributes);
|
||||||
}
|
}
|
||||||
return this.defaultResolve(originalSpecifier, parentURL, importAssertions);
|
return this.defaultResolve(originalSpecifier, parentURL, importAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -382,13 +383,13 @@ class ModuleLoader {
|
|||||||
* `resolve` and `resolveSync`. This function is here just to avoid
|
* `resolve` and `resolveSync`. This function is here just to avoid
|
||||||
* repeating the same code block twice in those functions.
|
* repeating the same code block twice in those functions.
|
||||||
*/
|
*/
|
||||||
defaultResolve(originalSpecifier, parentURL, importAssertions) {
|
defaultResolve(originalSpecifier, parentURL, importAttributes) {
|
||||||
defaultResolve ??= require('internal/modules/esm/resolve').defaultResolve;
|
defaultResolve ??= require('internal/modules/esm/resolve').defaultResolve;
|
||||||
|
|
||||||
const context = {
|
const context = {
|
||||||
__proto__: null,
|
__proto__: null,
|
||||||
conditions: this.#defaultConditions,
|
conditions: this.#defaultConditions,
|
||||||
importAssertions,
|
importAttributes,
|
||||||
parentURL,
|
parentURL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -483,17 +484,17 @@ class CustomizedModuleLoader {
|
|||||||
* @param {string} originalSpecifier The specified URL path of the module to
|
* @param {string} originalSpecifier The specified URL path of the module to
|
||||||
* be resolved.
|
* be resolved.
|
||||||
* @param {string} [parentURL] The URL path of the module's parent.
|
* @param {string} [parentURL] The URL path of the module's parent.
|
||||||
* @param {ImportAssertions} importAssertions Assertions from the import
|
* @param {ImportAttributes} importAttributes Attributes from the import
|
||||||
* statement or expression.
|
* statement or expression.
|
||||||
* @returns {{ format: string, url: URL['href'] }}
|
* @returns {{ format: string, url: URL['href'] }}
|
||||||
*/
|
*/
|
||||||
resolve(originalSpecifier, parentURL, importAssertions) {
|
resolve(originalSpecifier, parentURL, importAttributes) {
|
||||||
return hooksProxy.makeAsyncRequest('resolve', undefined, originalSpecifier, parentURL, importAssertions);
|
return hooksProxy.makeAsyncRequest('resolve', undefined, originalSpecifier, parentURL, importAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveSync(originalSpecifier, parentURL, importAssertions) {
|
resolveSync(originalSpecifier, parentURL, importAttributes) {
|
||||||
// This happens only as a result of `import.meta.resolve` calls, which must be sync per spec.
|
// This happens only as a result of `import.meta.resolve` calls, which must be sync per spec.
|
||||||
return hooksProxy.makeSyncRequest('resolve', undefined, originalSpecifier, parentURL, importAssertions);
|
return hooksProxy.makeSyncRequest('resolve', undefined, originalSpecifier, parentURL, importAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,10 +50,10 @@ const isCommonJSGlobalLikeNotDefinedError = (errorMessage) =>
|
|||||||
class ModuleJob {
|
class ModuleJob {
|
||||||
// `loader` is the Loader instance used for loading dependencies.
|
// `loader` is the Loader instance used for loading dependencies.
|
||||||
// `moduleProvider` is a function
|
// `moduleProvider` is a function
|
||||||
constructor(loader, url, importAssertions = { __proto__: null },
|
constructor(loader, url, importAttributes = { __proto__: null },
|
||||||
moduleProvider, isMain, inspectBrk, sync = false) {
|
moduleProvider, isMain, inspectBrk, sync = false) {
|
||||||
this.loader = loader;
|
this.loader = loader;
|
||||||
this.importAssertions = importAssertions;
|
this.importAttributes = importAttributes;
|
||||||
this.isMain = isMain;
|
this.isMain = isMain;
|
||||||
this.inspectBrk = inspectBrk;
|
this.inspectBrk = inspectBrk;
|
||||||
|
|
||||||
@ -81,8 +81,8 @@ class ModuleJob {
|
|||||||
// so that circular dependencies can't cause a deadlock by two of
|
// so that circular dependencies can't cause a deadlock by two of
|
||||||
// these `link` callbacks depending on each other.
|
// these `link` callbacks depending on each other.
|
||||||
const dependencyJobs = [];
|
const dependencyJobs = [];
|
||||||
const promises = this.module.link(async (specifier, assertions) => {
|
const promises = this.module.link(async (specifier, attributes) => {
|
||||||
const job = await this.loader.getModuleJob(specifier, url, assertions);
|
const job = await this.loader.getModuleJob(specifier, url, attributes);
|
||||||
ArrayPrototypePush(dependencyJobs, job);
|
ArrayPrototypePush(dependencyJobs, job);
|
||||||
return job.modulePromise;
|
return job.modulePromise;
|
||||||
});
|
});
|
||||||
@ -157,7 +157,7 @@ class ModuleJob {
|
|||||||
let format;
|
let format;
|
||||||
try {
|
try {
|
||||||
// This might throw for non-CommonJS modules because we aren't passing
|
// This might throw for non-CommonJS modules because we aren't passing
|
||||||
// in the import assertions and some formats require them; but we only
|
// in the import attributes and some formats require them; but we only
|
||||||
// care about CommonJS for the purposes of this error message.
|
// care about CommonJS for the purposes of this error message.
|
||||||
({ format } =
|
({ format } =
|
||||||
await this.loader.load(childFileURL));
|
await this.loader.load(childFileURL));
|
||||||
|
@ -17,7 +17,7 @@ const { validateString } = require('internal/validators');
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache the results of the `resolve` step of the module resolution and loading process.
|
* Cache the results of the `resolve` step of the module resolution and loading process.
|
||||||
* Future resolutions of the same input (specifier, parent URL and import assertions)
|
* Future resolutions of the same input (specifier, parent URL and import attributes)
|
||||||
* must return the same result if the first attempt was successful, per
|
* must return the same result if the first attempt was successful, per
|
||||||
* https://tc39.es/ecma262/#sec-HostLoadImportedModule.
|
* https://tc39.es/ecma262/#sec-HostLoadImportedModule.
|
||||||
* This cache is *not* used when custom loaders are registered.
|
* This cache is *not* used when custom loaders are registered.
|
||||||
@ -30,15 +30,15 @@ class ResolveCache extends SafeMap {
|
|||||||
*
|
*
|
||||||
* It is exposed to allow more efficient read and overwrite a cache entry.
|
* It is exposed to allow more efficient read and overwrite a cache entry.
|
||||||
* @param {string} specifier
|
* @param {string} specifier
|
||||||
* @param {Record<string,string>} importAssertions
|
* @param {Record<string,string>} importAttributes
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
serializeKey(specifier, importAssertions) {
|
serializeKey(specifier, importAttributes) {
|
||||||
// To serialize the ModuleRequest (specifier + list of import assertions),
|
// To serialize the ModuleRequest (specifier + list of import attributes),
|
||||||
// we need to sort the assertions by key, then stringifying,
|
// we need to sort the attributes by key, then stringifying,
|
||||||
// so that different import statements with the same assertions are always treated
|
// so that different import statements with the same attributes are always treated
|
||||||
// as identical.
|
// as identical.
|
||||||
const keys = ObjectKeys(importAssertions);
|
const keys = ObjectKeys(importAttributes);
|
||||||
|
|
||||||
if (keys.length === 0) {
|
if (keys.length === 0) {
|
||||||
return specifier + '::';
|
return specifier + '::';
|
||||||
@ -47,7 +47,7 @@ class ResolveCache extends SafeMap {
|
|||||||
return specifier + '::' + ArrayPrototypeJoin(
|
return specifier + '::' + ArrayPrototypeJoin(
|
||||||
ArrayPrototypeMap(
|
ArrayPrototypeMap(
|
||||||
ArrayPrototypeSort(keys),
|
ArrayPrototypeSort(keys),
|
||||||
(key) => JSONStringify(key) + JSONStringify(importAssertions[key])),
|
(key) => JSONStringify(key) + JSONStringify(importAttributes[key])),
|
||||||
',');
|
',');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,11 +138,11 @@ function errPath(url) {
|
|||||||
* @param {string} specifier - The module specifier to import.
|
* @param {string} specifier - The module specifier to import.
|
||||||
* @param {object} options - An object containing options for the import.
|
* @param {object} options - An object containing options for the import.
|
||||||
* @param {string} options.url - The URL of the module requesting the import.
|
* @param {string} options.url - The URL of the module requesting the import.
|
||||||
* @param {Record<string, string>} [assertions] - An object containing assertions for the import.
|
* @param {Record<string, string>} [attributes] - An object containing attributes for the import.
|
||||||
* @returns {Promise<import('internal/modules/esm/loader.js').ModuleExports>} The imported module.
|
* @returns {Promise<import('internal/modules/esm/loader.js').ModuleExports>} The imported module.
|
||||||
*/
|
*/
|
||||||
async function importModuleDynamically(specifier, { url }, assertions) {
|
async function importModuleDynamically(specifier, { url }, attributes) {
|
||||||
return asyncESM.esmLoader.import(specifier, url, assertions);
|
return asyncESM.esmLoader.import(specifier, url, attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strategy for loading a standard JavaScript module.
|
// Strategy for loading a standard JavaScript module.
|
||||||
@ -201,8 +201,8 @@ function loadCJSModule(module, source, url, filename) {
|
|||||||
'__dirname',
|
'__dirname',
|
||||||
], {
|
], {
|
||||||
filename,
|
filename,
|
||||||
importModuleDynamically(specifier, _, importAssertions) {
|
importModuleDynamically(specifier, _, importAttributes) {
|
||||||
return asyncESM.esmLoader.import(specifier, url, importAssertions);
|
return asyncESM.esmLoader.import(specifier, url, importAttributes);
|
||||||
},
|
},
|
||||||
}).function;
|
}).function;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -213,14 +213,14 @@ function loadCJSModule(module, source, url, filename) {
|
|||||||
const __dirname = dirname(filename);
|
const __dirname = dirname(filename);
|
||||||
// eslint-disable-next-line func-name-matching,func-style
|
// eslint-disable-next-line func-name-matching,func-style
|
||||||
const requireFn = function require(specifier) {
|
const requireFn = function require(specifier) {
|
||||||
let importAssertions = kEmptyObject;
|
let importAttributes = kEmptyObject;
|
||||||
if (!StringPrototypeStartsWith(specifier, 'node:')) {
|
if (!StringPrototypeStartsWith(specifier, 'node:')) {
|
||||||
// TODO: do not depend on the monkey-patchable CJS loader here.
|
// TODO: do not depend on the monkey-patchable CJS loader here.
|
||||||
const path = CJSModule._resolveFilename(specifier, module);
|
const path = CJSModule._resolveFilename(specifier, module);
|
||||||
if (specifier !== path) {
|
if (specifier !== path) {
|
||||||
switch (extname(path)) {
|
switch (extname(path)) {
|
||||||
case '.json':
|
case '.json':
|
||||||
importAssertions = { __proto__: null, type: 'json' };
|
importAttributes = { __proto__: null, type: 'json' };
|
||||||
break;
|
break;
|
||||||
case '.node':
|
case '.node':
|
||||||
return CJSModule._load(specifier, module);
|
return CJSModule._load(specifier, module);
|
||||||
@ -230,7 +230,7 @@ function loadCJSModule(module, source, url, filename) {
|
|||||||
specifier = `${pathToFileURL(path)}`;
|
specifier = `${pathToFileURL(path)}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const job = asyncESM.esmLoader.getModuleJobSync(specifier, url, importAssertions);
|
const job = asyncESM.esmLoader.getModuleJobSync(specifier, url, importAttributes);
|
||||||
job.runSync();
|
job.runSync();
|
||||||
return cjsCache.get(job.url).exports;
|
return cjsCache.get(job.url).exports;
|
||||||
};
|
};
|
||||||
|
@ -88,7 +88,7 @@ function getConditionsSet(conditions) {
|
|||||||
* @callback ImportModuleDynamicallyCallback
|
* @callback ImportModuleDynamicallyCallback
|
||||||
* @param {string} specifier
|
* @param {string} specifier
|
||||||
* @param {ModuleWrap|ContextifyScript|Function|vm.Module} callbackReferrer
|
* @param {ModuleWrap|ContextifyScript|Function|vm.Module} callbackReferrer
|
||||||
* @param {object} assertions
|
* @param {Record<string, string>} attributes
|
||||||
* @returns { Promise<void> }
|
* @returns { Promise<void> }
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -162,15 +162,15 @@ function initializeImportMetaObject(symbol, meta) {
|
|||||||
* Asynchronously imports a module dynamically using a callback function. The native callback.
|
* Asynchronously imports a module dynamically using a callback function. The native callback.
|
||||||
* @param {symbol} symbol - Reference to the module.
|
* @param {symbol} symbol - Reference to the module.
|
||||||
* @param {string} specifier - The module specifier string.
|
* @param {string} specifier - The module specifier string.
|
||||||
* @param {Record<string, string>} assertions - The import assertions object.
|
* @param {Record<string, string>} attributes - The import attributes object.
|
||||||
* @returns {Promise<import('internal/modules/esm/loader.js').ModuleExports>} - The imported module object.
|
* @returns {Promise<import('internal/modules/esm/loader.js').ModuleExports>} - The imported module object.
|
||||||
* @throws {ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING} - If the callback function is missing.
|
* @throws {ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING} - If the callback function is missing.
|
||||||
*/
|
*/
|
||||||
async function importModuleDynamicallyCallback(symbol, specifier, assertions) {
|
async function importModuleDynamicallyCallback(symbol, specifier, attributes) {
|
||||||
if (moduleRegistries.has(symbol)) {
|
if (moduleRegistries.has(symbol)) {
|
||||||
const { importModuleDynamically, callbackReferrer } = moduleRegistries.get(symbol);
|
const { importModuleDynamically, callbackReferrer } = moduleRegistries.get(symbol);
|
||||||
if (importModuleDynamically !== undefined) {
|
if (importModuleDynamically !== undefined) {
|
||||||
return importModuleDynamically(specifier, callbackReferrer, assertions);
|
return importModuleDynamically(specifier, callbackReferrer, attributes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING();
|
throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING();
|
||||||
|
@ -84,9 +84,9 @@ function evalScript(name, body, breakFirstLine, print, shouldLoadESM = false) {
|
|||||||
filename: name,
|
filename: name,
|
||||||
displayErrors: true,
|
displayErrors: true,
|
||||||
[kVmBreakFirstLineSymbol]: !!breakFirstLine,
|
[kVmBreakFirstLineSymbol]: !!breakFirstLine,
|
||||||
importModuleDynamically(specifier, _, importAssertions) {
|
importModuleDynamically(specifier, _, importAttributes) {
|
||||||
const loader = asyncESM.esmLoader;
|
const loader = asyncESM.esmLoader;
|
||||||
return loader.import(specifier, baseUrl, importAssertions);
|
return loader.import(specifier, baseUrl, importAttributes);
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
if (print) {
|
if (print) {
|
||||||
|
@ -483,9 +483,9 @@ function REPLServer(prompt,
|
|||||||
vm.createScript(fallbackCode, {
|
vm.createScript(fallbackCode, {
|
||||||
filename: file,
|
filename: file,
|
||||||
displayErrors: true,
|
displayErrors: true,
|
||||||
importModuleDynamically: (specifier, _, importAssertions) => {
|
importModuleDynamically: (specifier, _, importAttributes) => {
|
||||||
return asyncESM.esmLoader.import(specifier, parentURL,
|
return asyncESM.esmLoader.import(specifier, parentURL,
|
||||||
importAssertions);
|
importAttributes);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (fallbackError) {
|
} catch (fallbackError) {
|
||||||
@ -527,9 +527,9 @@ function REPLServer(prompt,
|
|||||||
script = vm.createScript(code, {
|
script = vm.createScript(code, {
|
||||||
filename: file,
|
filename: file,
|
||||||
displayErrors: true,
|
displayErrors: true,
|
||||||
importModuleDynamically: (specifier, _, importAssertions) => {
|
importModuleDynamically: (specifier, _, importAttributes) => {
|
||||||
return asyncESM.esmLoader.import(specifier, parentURL,
|
return asyncESM.esmLoader.import(specifier, parentURL,
|
||||||
importAssertions);
|
importAttributes);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -249,19 +249,19 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
|
|||||||
args.GetReturnValue().Set(that);
|
args.GetReturnValue().Set(that);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Local<Object> createImportAssertionContainer(Environment* env,
|
static Local<Object> createImportAttributesContainer(
|
||||||
Isolate* isolate, Local<FixedArray> raw_assertions) {
|
Environment* env, Isolate* isolate, Local<FixedArray> raw_attributes) {
|
||||||
Local<Object> assertions =
|
Local<Object> attributes =
|
||||||
Object::New(isolate, v8::Null(env->isolate()), nullptr, nullptr, 0);
|
Object::New(isolate, v8::Null(env->isolate()), nullptr, nullptr, 0);
|
||||||
for (int i = 0; i < raw_assertions->Length(); i += 3) {
|
for (int i = 0; i < raw_attributes->Length(); i += 3) {
|
||||||
assertions
|
attributes
|
||||||
->Set(env->context(),
|
->Set(env->context(),
|
||||||
raw_assertions->Get(env->context(), i).As<String>(),
|
raw_attributes->Get(env->context(), i).As<String>(),
|
||||||
raw_assertions->Get(env->context(), i + 1).As<Value>())
|
raw_attributes->Get(env->context(), i + 1).As<Value>())
|
||||||
.ToChecked();
|
.ToChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
return assertions;
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
|
void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
|
||||||
@ -297,13 +297,13 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
|
|||||||
Utf8Value specifier_utf8(env->isolate(), specifier);
|
Utf8Value specifier_utf8(env->isolate(), specifier);
|
||||||
std::string specifier_std(*specifier_utf8, specifier_utf8.length());
|
std::string specifier_std(*specifier_utf8, specifier_utf8.length());
|
||||||
|
|
||||||
Local<FixedArray> raw_assertions = module_request->GetImportAssertions();
|
Local<FixedArray> raw_attributes = module_request->GetImportAssertions();
|
||||||
Local<Object> assertions =
|
Local<Object> attributes =
|
||||||
createImportAssertionContainer(env, isolate, raw_assertions);
|
createImportAttributesContainer(env, isolate, raw_attributes);
|
||||||
|
|
||||||
Local<Value> argv[] = {
|
Local<Value> argv[] = {
|
||||||
specifier,
|
specifier,
|
||||||
assertions,
|
attributes,
|
||||||
};
|
};
|
||||||
|
|
||||||
MaybeLocal<Value> maybe_resolve_return_value =
|
MaybeLocal<Value> maybe_resolve_return_value =
|
||||||
@ -499,7 +499,7 @@ void ModuleWrap::GetError(const FunctionCallbackInfo<Value>& args) {
|
|||||||
MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
|
MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
|
||||||
Local<Context> context,
|
Local<Context> context,
|
||||||
Local<String> specifier,
|
Local<String> specifier,
|
||||||
Local<FixedArray> import_assertions,
|
Local<FixedArray> import_attributes,
|
||||||
Local<Module> referrer) {
|
Local<Module> referrer) {
|
||||||
Environment* env = Environment::GetCurrent(context);
|
Environment* env = Environment::GetCurrent(context);
|
||||||
if (env == nullptr) {
|
if (env == nullptr) {
|
||||||
@ -552,7 +552,7 @@ static MaybeLocal<Promise> ImportModuleDynamically(
|
|||||||
Local<v8::Data> host_defined_options,
|
Local<v8::Data> host_defined_options,
|
||||||
Local<Value> resource_name,
|
Local<Value> resource_name,
|
||||||
Local<String> specifier,
|
Local<String> specifier,
|
||||||
Local<FixedArray> import_assertions) {
|
Local<FixedArray> import_attributes) {
|
||||||
Isolate* isolate = context->GetIsolate();
|
Isolate* isolate = context->GetIsolate();
|
||||||
Environment* env = Environment::GetCurrent(context);
|
Environment* env = Environment::GetCurrent(context);
|
||||||
if (env == nullptr) {
|
if (env == nullptr) {
|
||||||
@ -580,13 +580,13 @@ static MaybeLocal<Promise> ImportModuleDynamically(
|
|||||||
Local<Symbol> id =
|
Local<Symbol> id =
|
||||||
options->Get(context, HostDefinedOptions::kID).As<Symbol>();
|
options->Get(context, HostDefinedOptions::kID).As<Symbol>();
|
||||||
|
|
||||||
Local<Object> assertions =
|
Local<Object> attributes =
|
||||||
createImportAssertionContainer(env, isolate, import_assertions);
|
createImportAttributesContainer(env, isolate, import_attributes);
|
||||||
|
|
||||||
Local<Value> import_args[] = {
|
Local<Value> import_args[] = {
|
||||||
id,
|
id,
|
||||||
Local<Value>(specifier),
|
Local<Value>(specifier),
|
||||||
assertions,
|
attributes,
|
||||||
};
|
};
|
||||||
|
|
||||||
Local<Value> result;
|
Local<Value> result;
|
||||||
|
@ -97,7 +97,7 @@ class ModuleWrap : public BaseObject {
|
|||||||
static v8::MaybeLocal<v8::Module> ResolveModuleCallback(
|
static v8::MaybeLocal<v8::Module> ResolveModuleCallback(
|
||||||
v8::Local<v8::Context> context,
|
v8::Local<v8::Context> context,
|
||||||
v8::Local<v8::String> specifier,
|
v8::Local<v8::String> specifier,
|
||||||
v8::Local<v8::FixedArray> import_assertions,
|
v8::Local<v8::FixedArray> import_attributes,
|
||||||
v8::Local<v8::Module> referrer);
|
v8::Local<v8::Module> referrer);
|
||||||
static ModuleWrap* GetFromModule(node::Environment*, v8::Local<v8::Module>);
|
static ModuleWrap* GetFromModule(node::Environment*, v8::Local<v8::Module>);
|
||||||
|
|
||||||
|
@ -753,6 +753,13 @@ static ExitCode ProcessGlobalArgsInternal(std::vector<std::string>* args,
|
|||||||
"--no-harmony-import-assertions") == v8_args.end()) {
|
"--no-harmony-import-assertions") == v8_args.end()) {
|
||||||
v8_args.emplace_back("--harmony-import-assertions");
|
v8_args.emplace_back("--harmony-import-assertions");
|
||||||
}
|
}
|
||||||
|
// TODO(aduh95): remove this when the harmony-import-attributes flag
|
||||||
|
// is removed in V8.
|
||||||
|
if (std::find(v8_args.begin(),
|
||||||
|
v8_args.end(),
|
||||||
|
"--no-harmony-import-attributes") == v8_args.end()) {
|
||||||
|
v8_args.emplace_back("--harmony-import-attributes");
|
||||||
|
}
|
||||||
|
|
||||||
auto env_opts = per_process::cli_options->per_isolate->per_env;
|
auto env_opts = per_process::cli_options->per_isolate->per_env;
|
||||||
if (std::find(v8_args.begin(), v8_args.end(),
|
if (std::find(v8_args.begin(), v8_args.end(),
|
||||||
|
@ -9,7 +9,7 @@ async function test() {
|
|||||||
import('../fixtures/experimental.json'),
|
import('../fixtures/experimental.json'),
|
||||||
import(
|
import(
|
||||||
'../fixtures/experimental.json',
|
'../fixtures/experimental.json',
|
||||||
{ assert: { type: 'json' } }
|
{ with: { type: 'json' } }
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ async function test() {
|
|||||||
import('../fixtures/experimental.json?test'),
|
import('../fixtures/experimental.json?test'),
|
||||||
import(
|
import(
|
||||||
'../fixtures/experimental.json?test',
|
'../fixtures/experimental.json?test',
|
||||||
{ assert: { type: 'json' } }
|
{ with: { type: 'json' } }
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ async function test() {
|
|||||||
import('../fixtures/experimental.json#test'),
|
import('../fixtures/experimental.json#test'),
|
||||||
import(
|
import(
|
||||||
'../fixtures/experimental.json#test',
|
'../fixtures/experimental.json#test',
|
||||||
{ assert: { type: 'json' } }
|
{ with: { type: 'json' } }
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ async function test() {
|
|||||||
import('../fixtures/experimental.json?test2#test'),
|
import('../fixtures/experimental.json?test2#test'),
|
||||||
import(
|
import(
|
||||||
'../fixtures/experimental.json?test2#test',
|
'../fixtures/experimental.json?test2#test',
|
||||||
{ assert: { type: 'json' } }
|
{ with: { type: 'json' } }
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ async function test() {
|
|||||||
import('data:application/json,{"ofLife":42}'),
|
import('data:application/json,{"ofLife":42}'),
|
||||||
import(
|
import(
|
||||||
'data:application/json,{"ofLife":42}',
|
'data:application/json,{"ofLife":42}',
|
||||||
{ assert: { type: 'json' } }
|
{ with: { type: 'json' } }
|
||||||
),
|
),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
@ -60,21 +60,21 @@ function createBase64URL(mime, body) {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
const ns = await import('data:application/json;foo="test,"this"',
|
const ns = await import('data:application/json;foo="test,"this"',
|
||||||
{ assert: { type: 'json' } });
|
{ with: { type: 'json' } });
|
||||||
assert.deepStrictEqual(Object.keys(ns), ['default']);
|
assert.deepStrictEqual(Object.keys(ns), ['default']);
|
||||||
assert.strictEqual(ns.default, 'this');
|
assert.strictEqual(ns.default, 'this');
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const ns = await import(`data:application/json;foo=${
|
const ns = await import(`data:application/json;foo=${
|
||||||
encodeURIComponent('test,')
|
encodeURIComponent('test,')
|
||||||
},0`, { assert: { type: 'json' } });
|
},0`, { with: { type: 'json' } });
|
||||||
assert.deepStrictEqual(Object.keys(ns), ['default']);
|
assert.deepStrictEqual(Object.keys(ns), ['default']);
|
||||||
assert.strictEqual(ns.default, 0);
|
assert.strictEqual(ns.default, 0);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
await assert.rejects(async () =>
|
await assert.rejects(async () =>
|
||||||
import('data:application/json;foo="test,",0',
|
import('data:application/json;foo="test,",0',
|
||||||
{ assert: { type: 'json' } }), {
|
{ with: { type: 'json' } }), {
|
||||||
name: 'SyntaxError',
|
name: 'SyntaxError',
|
||||||
message: /Unterminated string in JSON at position 3/
|
message: /Unterminated string in JSON at position 3/
|
||||||
});
|
});
|
||||||
@ -82,14 +82,14 @@ function createBase64URL(mime, body) {
|
|||||||
{
|
{
|
||||||
const body = '{"x": 1}';
|
const body = '{"x": 1}';
|
||||||
const plainESMURL = createURL('application/json', body);
|
const plainESMURL = createURL('application/json', body);
|
||||||
const ns = await import(plainESMURL, { assert: { type: 'json' } });
|
const ns = await import(plainESMURL, { with: { type: 'json' } });
|
||||||
assert.deepStrictEqual(Object.keys(ns), ['default']);
|
assert.deepStrictEqual(Object.keys(ns), ['default']);
|
||||||
assert.strictEqual(ns.default.x, 1);
|
assert.strictEqual(ns.default.x, 1);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
const body = '{"default": 2}';
|
const body = '{"default": 2}';
|
||||||
const plainESMURL = createURL('application/json', body);
|
const plainESMURL = createURL('application/json', body);
|
||||||
const ns = await import(plainESMURL, { assert: { type: 'json' } });
|
const ns = await import(plainESMURL, { with: { type: 'json' } });
|
||||||
assert.deepStrictEqual(Object.keys(ns), ['default']);
|
assert.deepStrictEqual(Object.keys(ns), ['default']);
|
||||||
assert.strictEqual(ns.default.default, 2);
|
assert.strictEqual(ns.default.default, 2);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ const { strictEqual } = require('assert');
|
|||||||
async function test() {
|
async function test() {
|
||||||
{
|
{
|
||||||
const results = await Promise.allSettled([
|
const results = await Promise.allSettled([
|
||||||
import('../fixtures/empty.js', { assert: { type: 'json' } }),
|
import('../fixtures/empty.js', { with: { type: 'json' } }),
|
||||||
import('../fixtures/empty.js'),
|
import('../fixtures/empty.js'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -16,7 +16,7 @@ async function test() {
|
|||||||
{
|
{
|
||||||
const results = await Promise.allSettled([
|
const results = await Promise.allSettled([
|
||||||
import('../fixtures/empty.js'),
|
import('../fixtures/empty.js'),
|
||||||
import('../fixtures/empty.js', { assert: { type: 'json' } }),
|
import('../fixtures/empty.js', { with: { type: 'json' } }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
strictEqual(results[0].status, 'fulfilled');
|
strictEqual(results[0].status, 'fulfilled');
|
||||||
@ -25,7 +25,7 @@ async function test() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
const results = await Promise.allSettled([
|
const results = await Promise.allSettled([
|
||||||
import('../fixtures/empty.json', { assert: { type: 'json' } }),
|
import('../fixtures/empty.json', { with: { type: 'json' } }),
|
||||||
import('../fixtures/empty.json'),
|
import('../fixtures/empty.json'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ async function test() {
|
|||||||
{
|
{
|
||||||
const results = await Promise.allSettled([
|
const results = await Promise.allSettled([
|
||||||
import('../fixtures/empty.json'),
|
import('../fixtures/empty.json'),
|
||||||
import('../fixtures/empty.json', { assert: { type: 'json' } }),
|
import('../fixtures/empty.json', { with: { type: 'json' } }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
strictEqual(results[0].status, 'rejected');
|
strictEqual(results[0].status, 'rejected');
|
@ -3,7 +3,7 @@ import { strictEqual } from 'assert';
|
|||||||
|
|
||||||
{
|
{
|
||||||
const results = await Promise.allSettled([
|
const results = await Promise.allSettled([
|
||||||
import('../fixtures/empty.js', { assert: { type: 'json' } }),
|
import('../fixtures/empty.js', { with: { type: 'json' } }),
|
||||||
import('../fixtures/empty.js'),
|
import('../fixtures/empty.js'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ import { strictEqual } from 'assert';
|
|||||||
{
|
{
|
||||||
const results = await Promise.allSettled([
|
const results = await Promise.allSettled([
|
||||||
import('../fixtures/empty.js'),
|
import('../fixtures/empty.js'),
|
||||||
import('../fixtures/empty.js', { assert: { type: 'json' } }),
|
import('../fixtures/empty.js', { with: { type: 'json' } }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
strictEqual(results[0].status, 'fulfilled');
|
strictEqual(results[0].status, 'fulfilled');
|
||||||
@ -23,7 +23,7 @@ import { strictEqual } from 'assert';
|
|||||||
|
|
||||||
{
|
{
|
||||||
const results = await Promise.allSettled([
|
const results = await Promise.allSettled([
|
||||||
import('../fixtures/empty.json', { assert: { type: 'json' } }),
|
import('../fixtures/empty.json', { with: { type: 'json' } }),
|
||||||
import('../fixtures/empty.json'),
|
import('../fixtures/empty.json'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ import { strictEqual } from 'assert';
|
|||||||
{
|
{
|
||||||
const results = await Promise.allSettled([
|
const results = await Promise.allSettled([
|
||||||
import('../fixtures/empty.json'),
|
import('../fixtures/empty.json'),
|
||||||
import('../fixtures/empty.json', { assert: { type: 'json' } }),
|
import('../fixtures/empty.json', { with: { type: 'json' } }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
strictEqual(results[0].status, 'rejected');
|
strictEqual(results[0].status, 'rejected');
|
@ -1,6 +0,0 @@
|
|||||||
import '../common/index.mjs';
|
|
||||||
import { strictEqual } from 'assert';
|
|
||||||
|
|
||||||
import secret from '../fixtures/experimental.json' assert { type: 'json', unsupportedAssertion: 'should ignore' };
|
|
||||||
|
|
||||||
strictEqual(secret.ofLife, 42);
|
|
@ -1,45 +0,0 @@
|
|||||||
// Flags: --expose-internals
|
|
||||||
'use strict';
|
|
||||||
const common = require('../common');
|
|
||||||
|
|
||||||
const assert = require('assert');
|
|
||||||
|
|
||||||
const { validateAssertions } = require('internal/modules/esm/assert');
|
|
||||||
|
|
||||||
common.expectWarning(
|
|
||||||
'ExperimentalWarning',
|
|
||||||
'Import assertions are not a stable feature of the JavaScript language. ' +
|
|
||||||
'Avoid relying on their current behavior and syntax as those might change ' +
|
|
||||||
'in a future version of Node.js.'
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
const url = 'test://';
|
|
||||||
|
|
||||||
assert.ok(validateAssertions(url, 'builtin', {}));
|
|
||||||
assert.ok(validateAssertions(url, 'commonjs', {}));
|
|
||||||
assert.ok(validateAssertions(url, 'json', { type: 'json' }));
|
|
||||||
assert.ok(validateAssertions(url, 'module', {}));
|
|
||||||
assert.ok(validateAssertions(url, 'wasm', {}));
|
|
||||||
|
|
||||||
assert.throws(() => validateAssertions(url, 'json', {}), {
|
|
||||||
code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING',
|
|
||||||
});
|
|
||||||
|
|
||||||
assert.throws(() => validateAssertions(url, 'module', { type: 'json' }), {
|
|
||||||
code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED',
|
|
||||||
});
|
|
||||||
|
|
||||||
// The HTML spec specifically disallows this for now, while Wasm module import
|
|
||||||
// and whether it will require a type assertion is still an open question.
|
|
||||||
assert.throws(() => validateAssertions(url, 'module', { type: 'javascript' }), {
|
|
||||||
code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED',
|
|
||||||
});
|
|
||||||
|
|
||||||
assert.throws(() => validateAssertions(url, 'module', { type: 'css' }), {
|
|
||||||
code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED',
|
|
||||||
});
|
|
||||||
|
|
||||||
assert.throws(() => validateAssertions(url, 'module', { type: false }), {
|
|
||||||
code: 'ERR_INVALID_ARG_TYPE',
|
|
||||||
});
|
|
@ -1,10 +1,37 @@
|
|||||||
import { expectWarning } from '../common/index.mjs';
|
import { spawnPromisified } from '../common/index.mjs';
|
||||||
|
import assert from 'node:assert';
|
||||||
|
import { execPath } from 'node:process';
|
||||||
|
|
||||||
expectWarning(
|
await Promise.all([
|
||||||
'ExperimentalWarning',
|
// Using importAssertions in the resolve hook should warn but still work.
|
||||||
'Import assertions are not a stable feature of the JavaScript language. ' +
|
`data:text/javascript,export ${encodeURIComponent(function resolve() {
|
||||||
'Avoid relying on their current behavior and syntax as those might change ' +
|
return { shortCircuit: true, url: 'data:application/json,1', importAssertions: { type: 'json' } };
|
||||||
'in a future version of Node.js.'
|
})}`,
|
||||||
);
|
// Setting importAssertions on the context object of the load hook should warn but still work.
|
||||||
|
`data:text/javascript,export ${encodeURIComponent(function load(u, c, n) {
|
||||||
|
c.importAssertions = { type: 'json' };
|
||||||
|
return n('data:application/json,1', c);
|
||||||
|
})}`,
|
||||||
|
// Creating a new context object with importAssertions in the load hook should warn but still work.
|
||||||
|
`data:text/javascript,export ${encodeURIComponent(function load(u, c, n) {
|
||||||
|
return n('data:application/json,1', { importAssertions: { type: 'json' } });
|
||||||
|
})}`,
|
||||||
|
].map(async (loaderURL) => {
|
||||||
|
const { stdout, stderr, code } = await spawnPromisified(execPath, [
|
||||||
|
'--input-type=module',
|
||||||
|
'--eval', `
|
||||||
|
import assert from 'node:assert';
|
||||||
|
import { register } from 'node:module';
|
||||||
|
|
||||||
|
register(${JSON.stringify(loaderURL)});
|
||||||
|
|
||||||
|
assert.deepStrictEqual(
|
||||||
|
{ ...await import('data:') },
|
||||||
|
{ default: 1 }
|
||||||
|
);`,
|
||||||
|
]);
|
||||||
|
|
||||||
await import('data:text/javascript,', { assert: { someUnsupportedKey: 'value' } });
|
assert.match(stderr, /Use `importAttributes` instead of `importAssertions`/);
|
||||||
|
assert.strictEqual(stdout, '');
|
||||||
|
assert.strictEqual(code, 0);
|
||||||
|
}));
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import '../common/index.mjs';
|
import '../common/index.mjs';
|
||||||
import { strictEqual } from 'assert';
|
import { strictEqual } from 'assert';
|
||||||
|
|
||||||
import secret from '../fixtures/experimental.json' assert { type: 'json' };
|
import secret from '../fixtures/experimental.json' with { type: 'json' };
|
||||||
|
|
||||||
strictEqual(secret.ofLife, 42);
|
strictEqual(secret.ofLife, 42);
|
@ -1,9 +1,9 @@
|
|||||||
import '../common/index.mjs';
|
import '../common/index.mjs';
|
||||||
import { strictEqual } from 'assert';
|
import { strictEqual } from 'assert';
|
||||||
|
|
||||||
import secret0 from '../fixtures/experimental.json' assert { type: 'json' };
|
import secret0 from '../fixtures/experimental.json' with { type: 'json' };
|
||||||
const secret1 = await import('../fixtures/experimental.json', {
|
const secret1 = await import('../fixtures/experimental.json', {
|
||||||
assert: { type: 'json' },
|
with: { type: 'json' },
|
||||||
});
|
});
|
||||||
|
|
||||||
strictEqual(secret0.ofLife, 42);
|
strictEqual(secret0.ofLife, 42);
|
@ -1,9 +1,9 @@
|
|||||||
import '../common/index.mjs';
|
import '../common/index.mjs';
|
||||||
import { strictEqual } from 'assert';
|
import { strictEqual } from 'assert';
|
||||||
|
|
||||||
import secret0 from '../fixtures/experimental.json' assert { type: 'json' };
|
import secret0 from '../fixtures/experimental.json' with { type: 'json' };
|
||||||
const secret1 = await import('../fixtures/experimental.json',
|
const secret1 = await import('../fixtures/experimental.json',
|
||||||
{ assert: { type: 'json' } });
|
{ with: { type: 'json' } });
|
||||||
|
|
||||||
strictEqual(secret0.ofLife, 42);
|
strictEqual(secret0.ofLife, 42);
|
||||||
strictEqual(secret1.default.ofLife, 42);
|
strictEqual(secret1.default.ofLife, 42);
|
@ -5,31 +5,29 @@ const { rejects } = require('assert');
|
|||||||
const jsModuleDataUrl = 'data:text/javascript,export{}';
|
const jsModuleDataUrl = 'data:text/javascript,export{}';
|
||||||
const jsonModuleDataUrl = 'data:application/json,""';
|
const jsonModuleDataUrl = 'data:application/json,""';
|
||||||
|
|
||||||
common.expectWarning(
|
|
||||||
'ExperimentalWarning',
|
|
||||||
'Import assertions are not a stable feature of the JavaScript language. ' +
|
|
||||||
'Avoid relying on their current behavior and syntax as those might change ' +
|
|
||||||
'in a future version of Node.js.'
|
|
||||||
);
|
|
||||||
|
|
||||||
async function test() {
|
async function test() {
|
||||||
await rejects(
|
await rejects(
|
||||||
import('data:text/css,', { assert: { type: 'css' } }),
|
import('data:text/css,', { with: { type: 'css' } }),
|
||||||
{ code: 'ERR_UNKNOWN_MODULE_FORMAT' }
|
{ code: 'ERR_UNKNOWN_MODULE_FORMAT' }
|
||||||
);
|
);
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
import(`data:text/javascript,import${JSON.stringify(jsModuleDataUrl)}assert{type:"json"}`),
|
import('data:text/css,', { with: { unsupportedAttribute: 'value' } }),
|
||||||
|
{ code: 'ERR_IMPORT_ATTRIBUTE_UNSUPPORTED' }
|
||||||
|
);
|
||||||
|
|
||||||
|
await rejects(
|
||||||
|
import(`data:text/javascript,import${JSON.stringify(jsModuleDataUrl)}with{type:"json"}`),
|
||||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED' }
|
{ code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED' }
|
||||||
);
|
);
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
import(jsModuleDataUrl, { assert: { type: 'json' } }),
|
import(jsModuleDataUrl, { with: { type: 'json' } }),
|
||||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED' }
|
{ code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED' }
|
||||||
);
|
);
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
import(jsModuleDataUrl, { assert: { type: 'unsupported' } }),
|
import(jsModuleDataUrl, { with: { type: 'unsupported' } }),
|
||||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED' }
|
{ code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED' }
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -39,17 +37,17 @@ async function test() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
import(jsonModuleDataUrl, { assert: {} }),
|
import(jsonModuleDataUrl, { with: {} }),
|
||||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING' }
|
{ code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING' }
|
||||||
);
|
);
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
import(jsonModuleDataUrl, { assert: { foo: 'bar' } }),
|
import(jsonModuleDataUrl, { with: { foo: 'bar' } }),
|
||||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING' }
|
{ code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING' }
|
||||||
);
|
);
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
import(jsonModuleDataUrl, { assert: { type: 'unsupported' } }),
|
import(jsonModuleDataUrl, { with: { type: 'unsupported' } }),
|
||||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED' }
|
{ code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED' }
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -1,36 +1,28 @@
|
|||||||
import { expectWarning } from '../common/index.mjs';
|
import '../common/index.mjs';
|
||||||
import { rejects } from 'assert';
|
import { rejects } from 'assert';
|
||||||
|
|
||||||
const jsModuleDataUrl = 'data:text/javascript,export{}';
|
const jsModuleDataUrl = 'data:text/javascript,export{}';
|
||||||
const jsonModuleDataUrl = 'data:application/json,""';
|
const jsonModuleDataUrl = 'data:application/json,""';
|
||||||
|
|
||||||
expectWarning(
|
|
||||||
'ExperimentalWarning',
|
|
||||||
'Import assertions are not a stable feature of the JavaScript language. ' +
|
|
||||||
'Avoid relying on their current behavior and syntax as those might change ' +
|
|
||||||
'in a future version of Node.js.'
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
// This rejects because of the unsupported MIME type, not because of the
|
// This rejects because of the unsupported MIME type, not because of the
|
||||||
// unsupported assertion.
|
// unsupported assertion.
|
||||||
import('data:text/css,', { assert: { type: 'css' } }),
|
import('data:text/css,', { with: { type: 'css' } }),
|
||||||
{ code: 'ERR_UNKNOWN_MODULE_FORMAT' }
|
{ code: 'ERR_UNKNOWN_MODULE_FORMAT' }
|
||||||
);
|
);
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
import(`data:text/javascript,import${JSON.stringify(jsModuleDataUrl)}assert{type:"json"}`),
|
import(`data:text/javascript,import${JSON.stringify(jsModuleDataUrl)}with{type:"json"}`),
|
||||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED' }
|
{ code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED' }
|
||||||
);
|
);
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
import(jsModuleDataUrl, { assert: { type: 'json' } }),
|
import(jsModuleDataUrl, { with: { type: 'json' } }),
|
||||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED' }
|
{ code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED' }
|
||||||
);
|
);
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
import(import.meta.url, { assert: { type: 'unsupported' } }),
|
import(import.meta.url, { with: { type: 'unsupported' } }),
|
||||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED' }
|
{ code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED' }
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -40,16 +32,16 @@ await rejects(
|
|||||||
);
|
);
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
import(jsonModuleDataUrl, { assert: {} }),
|
import(jsonModuleDataUrl, { with: {} }),
|
||||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING' }
|
{ code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING' }
|
||||||
);
|
);
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
import(jsonModuleDataUrl, { assert: { foo: 'bar' } }),
|
import(jsonModuleDataUrl, { with: { foo: 'bar' } }),
|
||||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING' }
|
{ code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING' }
|
||||||
);
|
);
|
||||||
|
|
||||||
await rejects(
|
await rejects(
|
||||||
import(jsonModuleDataUrl, { assert: { type: 'unsupported' } }),
|
import(jsonModuleDataUrl, { with: { type: 'unsupported' } }),
|
||||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED' }
|
{ code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED' }
|
||||||
);
|
);
|
45
test/es-module/test-esm-import-attributes-validation.js
Normal file
45
test/es-module/test-esm-import-attributes-validation.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Flags: --expose-internals
|
||||||
|
'use strict';
|
||||||
|
require('../common');
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
|
||||||
|
const { validateAttributes } = require('internal/modules/esm/assert');
|
||||||
|
|
||||||
|
const url = 'test://';
|
||||||
|
|
||||||
|
assert.ok(validateAttributes(url, 'builtin', {}));
|
||||||
|
assert.ok(validateAttributes(url, 'commonjs', {}));
|
||||||
|
assert.ok(validateAttributes(url, 'json', { type: 'json' }));
|
||||||
|
assert.ok(validateAttributes(url, 'module', {}));
|
||||||
|
assert.ok(validateAttributes(url, 'wasm', {}));
|
||||||
|
|
||||||
|
assert.throws(() => validateAttributes(url, 'json', {}), {
|
||||||
|
code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING',
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(() => validateAttributes(url, 'json', { type: 'json', unsupportedAttribute: 'value' }), {
|
||||||
|
code: 'ERR_IMPORT_ATTRIBUTE_UNSUPPORTED',
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(() => validateAttributes(url, 'module', { unsupportedAttribute: 'value' }), {
|
||||||
|
code: 'ERR_IMPORT_ATTRIBUTE_UNSUPPORTED',
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(() => validateAttributes(url, 'module', { type: 'json' }), {
|
||||||
|
code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED',
|
||||||
|
});
|
||||||
|
|
||||||
|
// The HTML spec specifically disallows this for now, while Wasm module import
|
||||||
|
// and whether it will require a type assertion is still an open question.
|
||||||
|
assert.throws(() => validateAttributes(url, 'module', { type: 'javascript' }), {
|
||||||
|
code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED',
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(() => validateAttributes(url, 'module', { type: 'css' }), {
|
||||||
|
code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED',
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.throws(() => validateAttributes(url, 'module', { type: false }), {
|
||||||
|
code: 'ERR_INVALID_ARG_TYPE',
|
||||||
|
});
|
@ -6,7 +6,7 @@ import { createRequire } from 'module';
|
|||||||
|
|
||||||
import mod from '../fixtures/es-modules/json-cache/mod.cjs';
|
import mod from '../fixtures/es-modules/json-cache/mod.cjs';
|
||||||
import another from '../fixtures/es-modules/json-cache/another.cjs';
|
import another from '../fixtures/es-modules/json-cache/another.cjs';
|
||||||
import test from '../fixtures/es-modules/json-cache/test.json' assert
|
import test from '../fixtures/es-modules/json-cache/test.json' with
|
||||||
{ type: 'json' };
|
{ type: 'json' };
|
||||||
|
|
||||||
const require = createRequire(import.meta.url);
|
const require = createRequire(import.meta.url);
|
||||||
|
@ -7,7 +7,7 @@ import { describe, it, test } from 'node:test';
|
|||||||
import { mkdir, rm, writeFile } from 'node:fs/promises';
|
import { mkdir, rm, writeFile } from 'node:fs/promises';
|
||||||
import * as tmpdir from '../common/tmpdir.js';
|
import * as tmpdir from '../common/tmpdir.js';
|
||||||
|
|
||||||
import secret from '../fixtures/experimental.json' assert { type: 'json' };
|
import secret from '../fixtures/experimental.json' with { type: 'json' };
|
||||||
|
|
||||||
describe('ESM: importing JSON', () => {
|
describe('ESM: importing JSON', () => {
|
||||||
it('should load JSON', () => {
|
it('should load JSON', () => {
|
||||||
@ -20,7 +20,6 @@ describe('ESM: importing JSON', () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
assert.match(stderr, /ExperimentalWarning: Importing JSON modules/);
|
assert.match(stderr, /ExperimentalWarning: Importing JSON modules/);
|
||||||
assert.match(stderr, /ExperimentalWarning: Import assertions/);
|
|
||||||
assert.strictEqual(code, 0);
|
assert.strictEqual(code, 0);
|
||||||
assert.strictEqual(signal, null);
|
assert.strictEqual(signal, null);
|
||||||
});
|
});
|
||||||
@ -35,19 +34,19 @@ describe('ESM: importing JSON', () => {
|
|||||||
const url = new URL('./foo.json', root);
|
const url = new URL('./foo.json', root);
|
||||||
await writeFile(url, JSON.stringify({ id: i++ }));
|
await writeFile(url, JSON.stringify({ id: i++ }));
|
||||||
const absoluteURL = await import(`${url}`, {
|
const absoluteURL = await import(`${url}`, {
|
||||||
assert: { type: 'json' },
|
with: { type: 'json' },
|
||||||
});
|
});
|
||||||
await writeFile(url, JSON.stringify({ id: i++ }));
|
await writeFile(url, JSON.stringify({ id: i++ }));
|
||||||
const queryString = await import(`${url}?a=2`, {
|
const queryString = await import(`${url}?a=2`, {
|
||||||
assert: { type: 'json' },
|
with: { type: 'json' },
|
||||||
});
|
});
|
||||||
await writeFile(url, JSON.stringify({ id: i++ }));
|
await writeFile(url, JSON.stringify({ id: i++ }));
|
||||||
const hash = await import(`${url}#a=2`, {
|
const hash = await import(`${url}#a=2`, {
|
||||||
assert: { type: 'json' },
|
with: { type: 'json' },
|
||||||
});
|
});
|
||||||
await writeFile(url, JSON.stringify({ id: i++ }));
|
await writeFile(url, JSON.stringify({ id: i++ }));
|
||||||
const queryStringAndHash = await import(`${url}?a=2#a=2`, {
|
const queryStringAndHash = await import(`${url}?a=2#a=2`, {
|
||||||
assert: { type: 'json' },
|
with: { type: 'json' },
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.notDeepStrictEqual(absoluteURL, queryString);
|
assert.notDeepStrictEqual(absoluteURL, queryString);
|
||||||
|
@ -12,7 +12,7 @@ async function resolve(referrer, context, next) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function load(url, context, next) {
|
function load(url, context, next) {
|
||||||
if (context.importAssertions.type === 'json') {
|
if (context.importAttributes.type === 'json') {
|
||||||
return {
|
return {
|
||||||
shortCircuit: true,
|
shortCircuit: true,
|
||||||
format: 'json',
|
format: 'json',
|
||||||
@ -25,6 +25,6 @@ function load(url, context, next) {
|
|||||||
register(`data:text/javascript,export ${encodeURIComponent(resolve)};export ${encodeURIComponent(load)}`);
|
register(`data:text/javascript,export ${encodeURIComponent(resolve)};export ${encodeURIComponent(load)}`);
|
||||||
|
|
||||||
assert.notDeepStrictEqual(
|
assert.notDeepStrictEqual(
|
||||||
await import(fixtures.fileURL('empty.json'), { assert: { type: 'json' } }),
|
await import(fixtures.fileURL('empty.json'), { with: { type: 'json' } }),
|
||||||
await import(fixtures.fileURL('empty.json'), { assert: { type: 'json' } }),
|
await import(fixtures.fileURL('empty.json'), { with: { type: 'json' } }),
|
||||||
);
|
);
|
||||||
|
@ -2,20 +2,20 @@ const DATA_URL_PATTERN = /^data:application\/json(?:[^,]*?)(;base64)?,([\s\S]*)$
|
|||||||
const JSON_URL_PATTERN = /^[^?]+\.json(\?[^#]*)?(#.*)?$/;
|
const JSON_URL_PATTERN = /^[^?]+\.json(\?[^#]*)?(#.*)?$/;
|
||||||
|
|
||||||
export async function resolve(specifier, context, next) {
|
export async function resolve(specifier, context, next) {
|
||||||
const noAssertionSpecified = context.importAssertions.type == null;
|
const noAttributesSpecified = context.importAttributes.type == null;
|
||||||
|
|
||||||
// Mutation from resolve hook should be discarded.
|
// Mutation from resolve hook should be discarded.
|
||||||
context.importAssertions.type = 'whatever';
|
context.importAttributes.type = 'whatever';
|
||||||
|
|
||||||
// This fixture assumes that no other resolve hooks in the chain will error on invalid import assertions
|
// This fixture assumes that no other resolve hooks in the chain will error on invalid import attributes
|
||||||
// (as defaultResolve doesn't).
|
// (as defaultResolve doesn't).
|
||||||
const result = await next(specifier, context);
|
const result = await next(specifier, context);
|
||||||
|
|
||||||
if (noAssertionSpecified &&
|
if (noAttributesSpecified &&
|
||||||
(DATA_URL_PATTERN.test(result.url) || JSON_URL_PATTERN.test(result.url))) {
|
(DATA_URL_PATTERN.test(result.url) || JSON_URL_PATTERN.test(result.url))) {
|
||||||
// Clean new import assertions object to ensure that this test isn't passing due to mutation.
|
// Clean new import attributes object to ensure that this test isn't passing due to mutation.
|
||||||
result.importAssertions = {
|
result.importAttributes = {
|
||||||
...(result.importAssertions ?? context.importAssertions),
|
...(result.importAttributes ?? context.importAttributes),
|
||||||
type: 'json',
|
type: 'json',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ export async function resolve(specifier, context, next) {
|
|||||||
return {
|
return {
|
||||||
shortCircuit: true,
|
shortCircuit: true,
|
||||||
url: `custom-${def.url}`,
|
url: `custom-${def.url}`,
|
||||||
importAssertions: context.importAssertions,
|
importAttributes: context.importAttributes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return def;
|
return def;
|
||||||
|
@ -6,7 +6,7 @@ import count from '../es-modules/stateful.mjs';
|
|||||||
// used to assert node-land and user-land have different contexts
|
// used to assert node-land and user-land have different contexts
|
||||||
count();
|
count();
|
||||||
|
|
||||||
export function resolve(specifier, { importAssertions }, next) {
|
export function resolve(specifier, { importAttributes }, next) {
|
||||||
let format = '';
|
let format = '';
|
||||||
|
|
||||||
if (specifier === 'esmHook/format.false') {
|
if (specifier === 'esmHook/format.false') {
|
||||||
@ -24,7 +24,7 @@ export function resolve(specifier, { importAssertions }, next) {
|
|||||||
format,
|
format,
|
||||||
shortCircuit: true,
|
shortCircuit: true,
|
||||||
url: pathToFileURL(specifier).href,
|
url: pathToFileURL(specifier).href,
|
||||||
importAssertions,
|
importAttributes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
test/fixtures/es-module-loaders/hooks-input.mjs
vendored
12
test/fixtures/es-module-loaders/hooks-input.mjs
vendored
@ -22,12 +22,12 @@ export async function resolve(specifier, context, next) {
|
|||||||
assert.strictEqual(context.parentURL, undefined);
|
assert.strictEqual(context.parentURL, undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.deepStrictEqual(context.importAssertions, {});
|
assert.deepStrictEqual(context.importAttributes, {});
|
||||||
} else if (resolveCalls === 2) {
|
} else if (resolveCalls === 2) {
|
||||||
url = new URL(specifier, context.parentURL).href;
|
url = new URL(specifier, context.parentURL).href;
|
||||||
assert.match(specifier, /experimental\.json$/);
|
assert.match(specifier, /experimental\.json$/);
|
||||||
assert.match(context.parentURL, /json-modules\.mjs$/);
|
assert.match(context.parentURL, /json-modules\.mjs$/);
|
||||||
assert.deepStrictEqual(context.importAssertions, {
|
assert.deepStrictEqual(context.importAttributes, {
|
||||||
type: 'json',
|
type: 'json',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -35,7 +35,7 @@ export async function resolve(specifier, context, next) {
|
|||||||
// Ensure `context` has all and only the properties it's supposed to
|
// Ensure `context` has all and only the properties it's supposed to
|
||||||
assert.deepStrictEqual(Reflect.ownKeys(context), [
|
assert.deepStrictEqual(Reflect.ownKeys(context), [
|
||||||
'conditions',
|
'conditions',
|
||||||
'importAssertions',
|
'importAttributes',
|
||||||
'parentURL',
|
'parentURL',
|
||||||
]);
|
]);
|
||||||
assert.ok(Array.isArray(context.conditions));
|
assert.ok(Array.isArray(context.conditions));
|
||||||
@ -59,11 +59,11 @@ export async function load(url, context, next) {
|
|||||||
|
|
||||||
if (loadCalls === 1) {
|
if (loadCalls === 1) {
|
||||||
assert.match(url, /json-modules\.mjs$/);
|
assert.match(url, /json-modules\.mjs$/);
|
||||||
assert.deepStrictEqual(context.importAssertions, {});
|
assert.deepStrictEqual(context.importAttributes, {});
|
||||||
format = 'module';
|
format = 'module';
|
||||||
} else if (loadCalls === 2) {
|
} else if (loadCalls === 2) {
|
||||||
assert.match(url, /experimental\.json$/);
|
assert.match(url, /experimental\.json$/);
|
||||||
assert.deepStrictEqual(context.importAssertions, {
|
assert.deepStrictEqual(context.importAttributes, {
|
||||||
type: 'json',
|
type: 'json',
|
||||||
});
|
});
|
||||||
format = 'json';
|
format = 'json';
|
||||||
@ -73,7 +73,7 @@ export async function load(url, context, next) {
|
|||||||
// Ensure `context` has all and only the properties it's supposed to
|
// Ensure `context` has all and only the properties it's supposed to
|
||||||
assert.deepStrictEqual(Object.keys(context), [
|
assert.deepStrictEqual(Object.keys(context), [
|
||||||
'format',
|
'format',
|
||||||
'importAssertions',
|
'importAttributes',
|
||||||
]);
|
]);
|
||||||
assert.strictEqual(context.format, 'test');
|
assert.strictEqual(context.format, 'test');
|
||||||
assert.strictEqual(typeof next, 'function');
|
assert.strictEqual(typeof next, 'function');
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export async function resolve(specifier, { parentURL, importAssertions }, next) {
|
export async function resolve(specifier, { parentURL, importAttributes }, next) {
|
||||||
if (parentURL && specifier === '../fixtures/es-modules/test-esm-ok.mjs') {
|
if (parentURL && specifier === '../fixtures/es-modules/test-esm-ok.mjs') {
|
||||||
return {
|
return {
|
||||||
shortCircuit: true,
|
shortCircuit: true,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
export async function resolve(specifier, { parentURL, importAssertions }, next) {
|
export async function resolve(specifier, { parentURL, importAttributes }, next) {
|
||||||
if (parentURL && specifier === '../fixtures/es-modules/test-esm-ok.mjs') {
|
if (parentURL && specifier === '../fixtures/es-modules/test-esm-ok.mjs') {
|
||||||
return {
|
return {
|
||||||
shortCircuit: true,
|
shortCircuit: true,
|
||||||
url: specifier,
|
url: specifier,
|
||||||
importAssertions,
|
importAttributes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return next(specifier);
|
return next(specifier);
|
||||||
|
@ -3,9 +3,9 @@ import {createRequire} from '../../common/index.mjs';
|
|||||||
const require = createRequire(import.meta.url);
|
const require = createRequire(import.meta.url);
|
||||||
const dep = require('./loader-dep.js');
|
const dep = require('./loader-dep.js');
|
||||||
|
|
||||||
export async function resolve(specifier, { parentURL, importAssertions }, defaultResolve) {
|
export async function resolve(specifier, { parentURL, importAttributes }, defaultResolve) {
|
||||||
return {
|
return {
|
||||||
url: (await defaultResolve(specifier, { parentURL, importAssertions }, defaultResolve)).url,
|
url: (await defaultResolve(specifier, { parentURL, importAttributes }, defaultResolve)).url,
|
||||||
format: dep.format
|
format: dep.format
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import assert from 'node:assert';
|
|||||||
// A loader that asserts that the defaultResolve will throw "not found"
|
// A loader that asserts that the defaultResolve will throw "not found"
|
||||||
// (skipping the top-level main of course, and the built-in ones needed for run-worker).
|
// (skipping the top-level main of course, and the built-in ones needed for run-worker).
|
||||||
let mainLoad = true;
|
let mainLoad = true;
|
||||||
export async function resolve(specifier, { importAssertions }, next) {
|
export async function resolve(specifier, { importAttributes }, next) {
|
||||||
if (mainLoad || specifier === 'path' || specifier === 'worker_threads') {
|
if (mainLoad || specifier === 'path' || specifier === 'worker_threads') {
|
||||||
mainLoad = false;
|
mainLoad = false;
|
||||||
return next(specifier);
|
return next(specifier);
|
||||||
@ -11,6 +11,6 @@ export async function resolve(specifier, { importAssertions }, next) {
|
|||||||
await assert.rejects(next(specifier), { code: 'ERR_MODULE_NOT_FOUND' });
|
await assert.rejects(next(specifier), { code: 'ERR_MODULE_NOT_FOUND' });
|
||||||
return {
|
return {
|
||||||
url: 'node:fs',
|
url: 'node:fs',
|
||||||
importAssertions,
|
importAttributes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ const SOURCES = {
|
|||||||
export function resolve(specifier, context, next) {
|
export function resolve(specifier, context, next) {
|
||||||
if (specifier.startsWith('test:')) {
|
if (specifier.startsWith('test:')) {
|
||||||
return {
|
return {
|
||||||
importAssertions: context.importAssertions,
|
importAttributes: context.importAttributes,
|
||||||
shortCircuit: true,
|
shortCircuit: true,
|
||||||
url: specifier,
|
url: specifier,
|
||||||
};
|
};
|
||||||
|
@ -1 +1 @@
|
|||||||
import { ofLife } from '../experimental.json' assert { type: 'json' };
|
import { ofLife } from '../experimental.json' with { type: 'json' };
|
||||||
|
2
test/fixtures/es-modules/json-modules.mjs
vendored
2
test/fixtures/es-modules/json-modules.mjs
vendored
@ -1 +1 @@
|
|||||||
import secret from '../experimental.json' assert { type: 'json' };
|
import secret from '../experimental.json' with { type: 'json' };
|
||||||
|
@ -58,11 +58,11 @@ async function test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const s = new Script('import("foo", { assert: { key: "value" } })', {
|
const s = new Script('import("foo", { with: { key: "value" } })', {
|
||||||
importModuleDynamically: common.mustCall((specifier, wrap, assertion) => {
|
importModuleDynamically: common.mustCall((specifier, wrap, attributes) => {
|
||||||
assert.strictEqual(specifier, 'foo');
|
assert.strictEqual(specifier, 'foo');
|
||||||
assert.strictEqual(wrap, s);
|
assert.strictEqual(wrap, s);
|
||||||
assert.deepStrictEqual(assertion, { __proto__: null, key: 'value' });
|
assert.deepStrictEqual(attributes, { __proto__: null, key: 'value' });
|
||||||
return foo;
|
return foo;
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
@ -47,7 +47,7 @@ rm -rf ../node_modules/eslint
|
|||||||
eslint-plugin-markdown \
|
eslint-plugin-markdown \
|
||||||
@babel/core \
|
@babel/core \
|
||||||
@babel/eslint-parser \
|
@babel/eslint-parser \
|
||||||
@babel/plugin-syntax-import-assertions
|
@babel/plugin-syntax-import-attributes
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
cd node_modules/eslint
|
cd node_modules/eslint
|
||||||
@ -62,7 +62,7 @@ rm -rf ../node_modules/eslint
|
|||||||
eslint-plugin-markdown \
|
eslint-plugin-markdown \
|
||||||
@babel/core \
|
@babel/core \
|
||||||
@babel/eslint-parser \
|
@babel/eslint-parser \
|
||||||
@babel/plugin-syntax-import-assertions
|
@babel/plugin-syntax-import-attributes
|
||||||
)
|
)
|
||||||
# Use dmn to remove some unneeded files.
|
# Use dmn to remove some unneeded files.
|
||||||
"$NODE" "$NPM" exec --package=dmn@2.2.2 --yes -- dmn -f clean
|
"$NODE" "$NPM" exec --package=dmn@2.2.2 --yes -- dmn -f clean
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
Object.defineProperty(exports, "__esModule", {
|
|
||||||
value: true
|
|
||||||
});
|
|
||||||
exports.default = void 0;
|
|
||||||
var _helperPluginUtils = require("@babel/helper-plugin-utils");
|
|
||||||
var _default = (0, _helperPluginUtils.declare)(api => {
|
|
||||||
api.assertVersion(7);
|
|
||||||
return {
|
|
||||||
name: "syntax-import-assertions",
|
|
||||||
manipulateOptions(opts, parserOpts) {
|
|
||||||
parserOpts.plugins.push("importAssertions");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
exports.default = _default;
|
|
||||||
|
|
||||||
//# sourceMappingURL=index.js.map
|
|
31
tools/node_modules/eslint/node_modules/@babel/plugin-syntax-import-attributes/lib/index.js
generated
vendored
Normal file
31
tools/node_modules/eslint/node_modules/@babel/plugin-syntax-import-attributes/lib/index.js
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
Object.defineProperty(exports, "__esModule", {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
exports.default = void 0;
|
||||||
|
var _helperPluginUtils = require("@babel/helper-plugin-utils");
|
||||||
|
var _default = (0, _helperPluginUtils.declare)((api, {
|
||||||
|
deprecatedAssertSyntax
|
||||||
|
}) => {
|
||||||
|
api.assertVersion("^7.22.0");
|
||||||
|
if (deprecatedAssertSyntax != null && typeof deprecatedAssertSyntax !== "boolean") {
|
||||||
|
throw new Error("'deprecatedAssertSyntax' must be a boolean, if specified.");
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
name: "syntax-import-attributes",
|
||||||
|
manipulateOptions({
|
||||||
|
parserOpts,
|
||||||
|
generatorOpts
|
||||||
|
}) {
|
||||||
|
var _generatorOpts$import;
|
||||||
|
(_generatorOpts$import = generatorOpts.importAttributesKeyword) != null ? _generatorOpts$import : generatorOpts.importAttributesKeyword = "with";
|
||||||
|
parserOpts.plugins.push(["importAttributes", {
|
||||||
|
deprecatedAssertSyntax: Boolean(deprecatedAssertSyntax)
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
exports.default = _default;
|
||||||
|
|
||||||
|
//# sourceMappingURL=index.js.map
|
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@babel/plugin-syntax-import-assertions",
|
"name": "@babel/plugin-syntax-import-attributes",
|
||||||
"version": "7.22.5",
|
"version": "7.22.5",
|
||||||
"description": "Allow parsing of the module assertion attributes in the import statement",
|
"description": "Allow parsing of the module attributes in the import statement",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/babel/babel.git",
|
"url": "https://github.com/babel/babel.git",
|
||||||
"directory": "packages/babel-plugin-syntax-import-assertions"
|
"directory": "packages/babel-plugin-syntax-import-attributes"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
@ -28,5 +28,9 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
},
|
},
|
||||||
"author": "The Babel Team (https://babel.dev/team)",
|
"author": "The Babel Team (https://babel.dev/team)",
|
||||||
|
"exports": {
|
||||||
|
".": "./lib/index.js",
|
||||||
|
"./package.json": "./package.json"
|
||||||
|
},
|
||||||
"type": "commonjs"
|
"type": "commonjs"
|
||||||
}
|
}
|
@ -1 +1 @@
|
|||||||
module.exports={A:{A:{"2":"J D E F A B NC"},B:{"2":"C K L G M N O","132":"P Q R S T U V W X","260":"0 1 2 3 Y Z a b c d e f g h i j k l m r s t u v w x y z H"},C:{"2":"4 5 6 7 8 9 OC 3B I J D E F A B C K L G M N O n o p AB BB CB DB EB FB GB HB IB JB QC RC","132":"KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB 4B gB 5B","260":"0 1 2 3 hB iB jB kB lB mB nB oB pB qB rB q sB tB uB vB wB P Q R 6B S T U V W X Y Z a b c d e f g h i j k l m r s t u v w x y z H xB 7B 8B PC"},D:{"2":"4 5 6 7 8 9 I J D E F A B C K L G M N O n o p AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB","132":"kB lB mB nB oB pB qB rB q sB tB uB vB wB P Q R S T U V W X","194":"fB 4B gB 5B hB iB jB","260":"0 1 2 3 Y Z a b c d e f g h i j k l m r s t u v w x y z H xB 7B 8B"},E:{"1":"2B KC aC","2":"4 I J D E F A B SC 9B TC UC VC WC AC","132":"C K L G yB zB BC XC YC CC DC 0B ZC","516":"EC FC GC HC IC JC","772":"1B"},F:{"2":"5 6 7 8 9 F B C G M N O n o p AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB bC cC dC eC yB LC fC zB","132":"ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB q sB tB","260":"uB vB wB P Q R 6B S T U V W X Y Z a b c d e f g h i j k l m"},G:{"1":"2B KC","2":"E 9B gC MC hC iC jC kC lC mC nC oC pC","132":"qC rC sC tC uC vC","260":"wC xC yC zC CC DC 0B 0C","516":"EC FC GC HC IC JC","772":"1B"},H:{"2":"1C"},I:{"2":"3B I 2C 3C 4C 5C MC 6C 7C","260":"H"},J:{"2":"D A"},K:{"2":"A B C yB LC zB","260":"q"},L:{"260":"H"},M:{"260":"xB"},N:{"2":"A B"},O:{"132":"0B"},P:{"2":"I 8C 9C AD BD","132":"CD AC DD ED FD GD","260":"n o p HD 1B 2B ID JD"},Q:{"132":"BC"},R:{"260":"KD"},S:{"132":"LD","260":"MD"}},B:4,C:"CSS display: contents",D:true};
|
module.exports={A:{A:{"2":"J D E F A B NC"},B:{"2":"C K L G M N O","132":"P Q R S T U V W X","260":"0 1 2 3 Y Z a b c d e f g h i j k l m r s t u v w x y z H"},C:{"2":"4 5 6 7 8 9 OC 3B I J D E F A B C K L G M N O n o p AB BB CB DB EB FB GB HB IB JB QC RC","132":"KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB 4B gB 5B","260":"0 1 2 3 hB iB jB kB lB mB nB oB pB qB rB q sB tB uB vB wB P Q R 6B S T U V W X Y Z a b c d e f g h i j k l m r s t u v w x y z H xB 7B 8B PC"},D:{"2":"4 5 6 7 8 9 I J D E F A B C K L G M N O n o p AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB","132":"kB lB mB nB oB pB qB rB q sB tB uB vB wB P Q R S T U V W X","194":"fB 4B gB 5B hB iB jB","260":"0 1 2 3 Y Z a b c d e f g h i j k l m r s t u v w x y z H xB 7B 8B"},E:{"2":"4 I J D E F A B SC 9B TC UC VC WC AC","132":"C K L G yB zB BC XC YC CC DC 0B ZC","260":"2B KC aC","772":"1B EC FC GC HC IC JC"},F:{"2":"5 6 7 8 9 F B C G M N O n o p AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB PB QB RB SB TB UB VB WB XB YB bC cC dC eC yB LC fC zB","132":"ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB q sB tB","260":"uB vB wB P Q R 6B S T U V W X Y Z a b c d e f g h i j k l m"},G:{"1":"2B KC","2":"E 9B gC MC hC iC jC kC lC mC nC oC pC","132":"qC rC sC tC uC vC","260":"wC xC yC zC CC DC 0B 0C","516":"EC FC GC HC IC JC","772":"1B"},H:{"2":"1C"},I:{"2":"3B I 2C 3C 4C 5C MC 6C 7C","260":"H"},J:{"2":"D A"},K:{"2":"A B C yB LC zB","260":"q"},L:{"260":"H"},M:{"260":"xB"},N:{"2":"A B"},O:{"132":"0B"},P:{"2":"I 8C 9C AD BD","132":"CD AC DD ED FD GD","260":"n o p HD 1B 2B ID JD"},Q:{"132":"BC"},R:{"260":"KD"},S:{"132":"LD","260":"MD"}},B:4,C:"CSS display: contents",D:true};
|
||||||
|
2
tools/node_modules/eslint/node_modules/caniuse-lite/package.json
generated
vendored
2
tools/node_modules/eslint/node_modules/caniuse-lite/package.json
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "caniuse-lite",
|
"name": "caniuse-lite",
|
||||||
"version": "1.0.30001546",
|
"version": "1.0.30001547",
|
||||||
"description": "A smaller version of caniuse-db, with only the essentials!",
|
"description": "A smaller version of caniuse-db, with only the essentials!",
|
||||||
"main": "dist/unpacker/index.js",
|
"main": "dist/unpacker/index.js",
|
||||||
"files": [
|
"files": [
|
||||||
|
13
tools/node_modules/eslint/node_modules/electron-to-chromium/full-chromium-versions.js
generated
vendored
13
tools/node_modules/eslint/node_modules/electron-to-chromium/full-chromium-versions.js
generated
vendored
@ -2306,7 +2306,8 @@ module.exports = {
|
|||||||
"22.3.23",
|
"22.3.23",
|
||||||
"22.3.24",
|
"22.3.24",
|
||||||
"22.3.25",
|
"22.3.25",
|
||||||
"22.3.26"
|
"22.3.26",
|
||||||
|
"22.3.27"
|
||||||
],
|
],
|
||||||
"110.0.5415.0": [
|
"110.0.5415.0": [
|
||||||
"23.0.0-alpha.1",
|
"23.0.0-alpha.1",
|
||||||
@ -2512,7 +2513,8 @@ module.exports = {
|
|||||||
"24.8.3",
|
"24.8.3",
|
||||||
"24.8.4",
|
"24.8.4",
|
||||||
"24.8.5",
|
"24.8.5",
|
||||||
"24.8.6"
|
"24.8.6",
|
||||||
|
"24.8.7"
|
||||||
],
|
],
|
||||||
"114.0.5694.0": [
|
"114.0.5694.0": [
|
||||||
"25.0.0-alpha.1",
|
"25.0.0-alpha.1",
|
||||||
@ -2812,6 +2814,9 @@ module.exports = {
|
|||||||
"27.0.0-nightly.20230814",
|
"27.0.0-nightly.20230814",
|
||||||
"27.0.0-nightly.20230815"
|
"27.0.0-nightly.20230815"
|
||||||
],
|
],
|
||||||
|
"118.0.5993.54": [
|
||||||
|
"27.0.0"
|
||||||
|
],
|
||||||
"118.0.5991.0": [
|
"118.0.5991.0": [
|
||||||
"28.0.0-nightly.20230906"
|
"28.0.0-nightly.20230906"
|
||||||
],
|
],
|
||||||
@ -2847,6 +2852,8 @@ module.exports = {
|
|||||||
"28.0.0-nightly.20231005"
|
"28.0.0-nightly.20231005"
|
||||||
],
|
],
|
||||||
"119.0.6045.0": [
|
"119.0.6045.0": [
|
||||||
"28.0.0-nightly.20231006"
|
"28.0.0-nightly.20231006",
|
||||||
|
"28.0.0-nightly.20231009",
|
||||||
|
"28.0.0-nightly.20231010"
|
||||||
]
|
]
|
||||||
};
|
};
|
File diff suppressed because one or more lines are too long
7
tools/node_modules/eslint/node_modules/electron-to-chromium/full-versions.js
generated
vendored
7
tools/node_modules/eslint/node_modules/electron-to-chromium/full-versions.js
generated
vendored
@ -1691,6 +1691,7 @@ module.exports = {
|
|||||||
"22.3.24": "108.0.5359.215",
|
"22.3.24": "108.0.5359.215",
|
||||||
"22.3.25": "108.0.5359.215",
|
"22.3.25": "108.0.5359.215",
|
||||||
"22.3.26": "108.0.5359.215",
|
"22.3.26": "108.0.5359.215",
|
||||||
|
"22.3.27": "108.0.5359.215",
|
||||||
"23.0.0-alpha.1": "110.0.5415.0",
|
"23.0.0-alpha.1": "110.0.5415.0",
|
||||||
"23.0.0-alpha.2": "110.0.5451.0",
|
"23.0.0-alpha.2": "110.0.5451.0",
|
||||||
"23.0.0-alpha.3": "110.0.5451.0",
|
"23.0.0-alpha.3": "110.0.5451.0",
|
||||||
@ -1844,6 +1845,7 @@ module.exports = {
|
|||||||
"24.8.4": "112.0.5615.204",
|
"24.8.4": "112.0.5615.204",
|
||||||
"24.8.5": "112.0.5615.204",
|
"24.8.5": "112.0.5615.204",
|
||||||
"24.8.6": "112.0.5615.204",
|
"24.8.6": "112.0.5615.204",
|
||||||
|
"24.8.7": "112.0.5615.204",
|
||||||
"25.0.0-alpha.1": "114.0.5694.0",
|
"25.0.0-alpha.1": "114.0.5694.0",
|
||||||
"25.0.0-alpha.2": "114.0.5694.0",
|
"25.0.0-alpha.2": "114.0.5694.0",
|
||||||
"25.0.0-alpha.3": "114.0.5710.0",
|
"25.0.0-alpha.3": "114.0.5710.0",
|
||||||
@ -2045,6 +2047,7 @@ module.exports = {
|
|||||||
"27.0.0-nightly.20230814": "117.0.5921.0",
|
"27.0.0-nightly.20230814": "117.0.5921.0",
|
||||||
"27.0.0-nightly.20230815": "117.0.5921.0",
|
"27.0.0-nightly.20230815": "117.0.5921.0",
|
||||||
"27.0.0-nightly.20230816": "118.0.5949.0",
|
"27.0.0-nightly.20230816": "118.0.5949.0",
|
||||||
|
"27.0.0": "118.0.5993.54",
|
||||||
"28.0.0-nightly.20230817": "118.0.5949.0",
|
"28.0.0-nightly.20230817": "118.0.5949.0",
|
||||||
"28.0.0-nightly.20230818": "118.0.5949.0",
|
"28.0.0-nightly.20230818": "118.0.5949.0",
|
||||||
"28.0.0-nightly.20230821": "118.0.5949.0",
|
"28.0.0-nightly.20230821": "118.0.5949.0",
|
||||||
@ -2076,5 +2079,7 @@ module.exports = {
|
|||||||
"28.0.0-nightly.20231003": "119.0.6043.0",
|
"28.0.0-nightly.20231003": "119.0.6043.0",
|
||||||
"28.0.0-nightly.20231004": "119.0.6043.0",
|
"28.0.0-nightly.20231004": "119.0.6043.0",
|
||||||
"28.0.0-nightly.20231005": "119.0.6043.0",
|
"28.0.0-nightly.20231005": "119.0.6043.0",
|
||||||
"28.0.0-nightly.20231006": "119.0.6045.0"
|
"28.0.0-nightly.20231006": "119.0.6045.0",
|
||||||
|
"28.0.0-nightly.20231009": "119.0.6045.0",
|
||||||
|
"28.0.0-nightly.20231010": "119.0.6045.0"
|
||||||
};
|
};
|
2
tools/node_modules/eslint/node_modules/electron-to-chromium/full-versions.json
generated
vendored
2
tools/node_modules/eslint/node_modules/electron-to-chromium/full-versions.json
generated
vendored
File diff suppressed because one or more lines are too long
2
tools/node_modules/eslint/node_modules/electron-to-chromium/package.json
generated
vendored
2
tools/node_modules/eslint/node_modules/electron-to-chromium/package.json
generated
vendored
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "electron-to-chromium",
|
"name": "electron-to-chromium",
|
||||||
"version": "1.4.544",
|
"version": "1.4.549",
|
||||||
"description": "Provides a list of electron-to-chromium version mappings",
|
"description": "Provides a list of electron-to-chromium version mappings",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"files": [
|
"files": [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user