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/fixtures
|
||||
doc/**/*.js
|
||||
doc/changelogs/CHANGELOG_v1*.md
|
||||
!doc/changelogs/CHANGELOG_v18.md
|
||||
!doc/api_assets/*.js
|
||||
!.eslintrc.js
|
||||
|
@ -18,7 +18,7 @@ const hacks = [
|
||||
'eslint-plugin-jsdoc',
|
||||
'eslint-plugin-markdown',
|
||||
'@babel/eslint-parser',
|
||||
'@babel/plugin-syntax-import-assertions',
|
||||
'@babel/plugin-syntax-import-attributes',
|
||||
];
|
||||
Module._findPath = (request, paths, isMain) => {
|
||||
const r = ModuleFindPath(request, paths, isMain);
|
||||
@ -44,7 +44,7 @@ module.exports = {
|
||||
parserOptions: {
|
||||
babelOptions: {
|
||||
plugins: [
|
||||
Module._findPath('@babel/plugin-syntax-import-assertions'),
|
||||
Module._findPath('@babel/plugin-syntax-import-attributes'),
|
||||
],
|
||||
},
|
||||
requireConfigFile: false,
|
||||
|
@ -1759,7 +1759,8 @@ added:
|
||||
- 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>
|
||||
|
||||
@ -1771,7 +1772,7 @@ added:
|
||||
- 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>
|
||||
|
||||
@ -1783,7 +1784,17 @@ added:
|
||||
- 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>
|
||||
|
||||
|
@ -7,6 +7,9 @@
|
||||
<!-- YAML
|
||||
added: v8.5.0
|
||||
changes:
|
||||
- version: REPLACEME
|
||||
pr-url: https://github.com/nodejs/node/pull/50140
|
||||
description: Add experimental support for import attributes.
|
||||
- version: v20.0.0
|
||||
pr-url: https://github.com/nodejs/node/pull/44710
|
||||
description: Module customization hooks are executed off the main thread.
|
||||
@ -19,7 +22,7 @@ changes:
|
||||
- v17.1.0
|
||||
- v16.14.0
|
||||
pr-url: https://github.com/nodejs/node/pull/40250
|
||||
description: Add support for import assertions.
|
||||
description: Add experimental support for import assertions.
|
||||
- version:
|
||||
- v17.0.0
|
||||
- v16.12.0
|
||||
@ -203,7 +206,7 @@ added: v12.10.0
|
||||
|
||||
```js
|
||||
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
|
||||
@ -235,30 +238,40 @@ absolute URL strings.
|
||||
import fs from 'node:fs/promises';
|
||||
```
|
||||
|
||||
## Import assertions
|
||||
<a id="import-assertions"></a>
|
||||
|
||||
## Import attributes
|
||||
|
||||
<!-- YAML
|
||||
added:
|
||||
- v17.1.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.
|
||||
|
||||
```js
|
||||
import fooData from './foo.json' assert { type: 'json' };
|
||||
import fooData from './foo.json' with { type: 'json' };
|
||||
|
||||
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:
|
||||
|
||||
| Assertion `type` | Needed for |
|
||||
| Attribute `type` | Needed for |
|
||||
| ---------------- | ---------------- |
|
||||
| `'json'` | [JSON modules][] |
|
||||
|
||||
@ -545,10 +558,10 @@ separate cache.
|
||||
JSON files can be referenced by `import`:
|
||||
|
||||
```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
|
||||
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
|
||||
[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
|
||||
[Import Assertions]: #import-assertions
|
||||
[Import Assertions proposal]: https://github.com/tc39/proposal-import-assertions
|
||||
[Import Attributes]: #import-attributes
|
||||
[Import Attributes proposal]: https://github.com/tc39/proposal-import-attributes
|
||||
[JSON modules]: #json-modules
|
||||
[Module customization hooks]: module.md#customization-hooks
|
||||
[Node.js Module Resolution And Loading Algorithm]: #resolution-algorithm-specification
|
||||
|
@ -458,6 +458,11 @@ register('./path-to-my-hooks.js', {
|
||||
|
||||
<!-- YAML
|
||||
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:
|
||||
- v18.6.0
|
||||
- v16.17.0
|
||||
@ -477,8 +482,8 @@ changes:
|
||||
* `specifier` {string}
|
||||
* `context` {Object}
|
||||
* `conditions` {string\[]} Export conditions of the relevant `package.json`
|
||||
* `importAssertions` {Object} An object whose key-value pairs represent the
|
||||
assertions for the module to import
|
||||
* `importAttributes` {Object} An object whose key-value pairs represent the
|
||||
attributes for the module to import
|
||||
* `parentURL` {string|undefined} The module importing this one, or undefined
|
||||
if this is the Node.js entry point
|
||||
* `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
|
||||
ignored)
|
||||
`'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)
|
||||
* `shortCircuit` {undefined|boolean} A signal that this hook intends to
|
||||
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
|
||||
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
|
||||
`importAssertions` object if the module should be cached with different
|
||||
assertions than were present in the source code.
|
||||
`importAttributes` object if the module should be cached with different
|
||||
attributes than were present in the source code.
|
||||
|
||||
The `conditions` property in `context` is an array of conditions for
|
||||
[package exports conditions][Conditional exports] that apply to this resolution
|
||||
@ -575,7 +580,7 @@ changes:
|
||||
* `conditions` {string\[]} Export conditions of the relevant `package.json`
|
||||
* `format` {string|null|undefined} The format optionally supplied by the
|
||||
`resolve` hook chain
|
||||
* `importAssertions` {Object}
|
||||
* `importAttributes` {Object}
|
||||
* `nextLoad` {Function} The subsequent `load` hook in the chain, or the
|
||||
Node.js default `load` hook after the last user-supplied `load` hook
|
||||
* `specifier` {string}
|
||||
|
@ -1280,12 +1280,17 @@ E('ERR_HTTP_SOCKET_ENCODING',
|
||||
E('ERR_HTTP_TRAILER_INVALID',
|
||||
'Trailers are invalid with this transfer encoding', Error);
|
||||
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',
|
||||
'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',
|
||||
'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',
|
||||
'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',
|
||||
'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 ' +
|
||||
|
@ -1258,10 +1258,10 @@ function wrapSafe(filename, content, cjsModuleInstance, codeCache) {
|
||||
const script = new Script(wrapper, {
|
||||
filename,
|
||||
lineOffset: 0,
|
||||
importModuleDynamically: async (specifier, _, importAssertions) => {
|
||||
importModuleDynamically: async (specifier, _, importAttributes) => {
|
||||
const cascadedLoader = getCascadedLoader();
|
||||
return cascadedLoader.import(specifier, normalizeReferrerURL(filename),
|
||||
importAssertions);
|
||||
importAttributes);
|
||||
},
|
||||
});
|
||||
|
||||
@ -1285,10 +1285,10 @@ function wrapSafe(filename, content, cjsModuleInstance, codeCache) {
|
||||
], {
|
||||
filename,
|
||||
cachedData: codeCache,
|
||||
importModuleDynamically(specifier, _, importAssertions) {
|
||||
importModuleDynamically(specifier, _, importAttributes) {
|
||||
const cascadedLoader = getCascadedLoader();
|
||||
return cascadedLoader.import(specifier, normalizeReferrerURL(filename),
|
||||
importAssertions);
|
||||
importAttributes);
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -13,16 +13,15 @@ const {
|
||||
ERR_IMPORT_ASSERTION_TYPE_FAILED,
|
||||
ERR_IMPORT_ASSERTION_TYPE_MISSING,
|
||||
ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED,
|
||||
ERR_IMPORT_ATTRIBUTE_UNSUPPORTED,
|
||||
} = require('internal/errors').codes;
|
||||
|
||||
// The HTML spec has an implied default type of `'javascript'`.
|
||||
const kImplicitAssertType = 'javascript';
|
||||
|
||||
let alreadyWarned = false;
|
||||
|
||||
/**
|
||||
* Define a map of module formats to import assertion types (the value of
|
||||
* `type` in `assert { type: 'json' }`).
|
||||
* Define a map of module formats to import attributes types (the value of
|
||||
* `type` in `with { type: 'json' }`).
|
||||
* @type {Map<string, string>}
|
||||
*/
|
||||
const formatTypeMap = {
|
||||
@ -31,13 +30,13 @@ const formatTypeMap = {
|
||||
'commonjs': kImplicitAssertType,
|
||||
'json': 'json',
|
||||
'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
|
||||
* (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>}
|
||||
*/
|
||||
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} 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.
|
||||
* @returns {true}
|
||||
* @throws {TypeError} If the format and assertion type are incompatible.
|
||||
*/
|
||||
function validateAssertions(url, format,
|
||||
importAssertions = { __proto__: null }) {
|
||||
const validType = formatTypeMap[format];
|
||||
|
||||
if (!alreadyWarned && ObjectKeys(importAssertions).length !== 0) {
|
||||
alreadyWarned = true;
|
||||
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',
|
||||
);
|
||||
function validateAttributes(url, format,
|
||||
importAttributes = { __proto__: null }) {
|
||||
const keys = ObjectKeys(importAttributes);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
if (keys[i] !== 'type') {
|
||||
throw new ERR_IMPORT_ATTRIBUTE_UNSUPPORTED(keys[i], importAttributes[keys[i]]);
|
||||
}
|
||||
}
|
||||
const validType = formatTypeMap[format];
|
||||
|
||||
switch (validType) {
|
||||
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.
|
||||
return true;
|
||||
|
||||
case kImplicitAssertType:
|
||||
// This format doesn't allow an import assertion type, so the property
|
||||
// must not be set on the import assertions object.
|
||||
if (!ObjectPrototypeHasOwnProperty(importAssertions, 'type')) {
|
||||
// must not be set on the import attributes object.
|
||||
if (!ObjectPrototypeHasOwnProperty(importAttributes, 'type')) {
|
||||
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.
|
||||
return true;
|
||||
|
||||
default:
|
||||
// There is an expected type for this format, but the value of
|
||||
// `importAssertions.type` might not have been it.
|
||||
if (!ObjectPrototypeHasOwnProperty(importAssertions, 'type')) {
|
||||
// `importAttributes.type` might not have been it.
|
||||
if (!ObjectPrototypeHasOwnProperty(importAttributes, 'type')) {
|
||||
// `type` wasn't specified at all.
|
||||
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 = {
|
||||
kImplicitAssertType,
|
||||
validateAssertions,
|
||||
validateAttributes,
|
||||
};
|
||||
|
@ -11,6 +11,7 @@ const {
|
||||
ObjectDefineProperty,
|
||||
ObjectSetPrototypeOf,
|
||||
Promise,
|
||||
ReflectSet,
|
||||
SafeSet,
|
||||
StringPrototypeSlice,
|
||||
StringPrototypeToUpperCase,
|
||||
@ -65,6 +66,30 @@ let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
|
||||
});
|
||||
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
|
||||
* @property {Function} resolve Resolve hook.
|
||||
@ -164,21 +189,21 @@ class Hooks {
|
||||
* @param {string} originalSpecifier The specified URL path of the module to
|
||||
* be resolved.
|
||||
* @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.
|
||||
* @returns {Promise<{ format: string, url: URL['href'] }>}
|
||||
*/
|
||||
async resolve(
|
||||
originalSpecifier,
|
||||
parentURL,
|
||||
importAssertions = { __proto__: null },
|
||||
importAttributes = { __proto__: null },
|
||||
) {
|
||||
throwIfInvalidParentURL(parentURL);
|
||||
|
||||
const chain = this.#chains.resolve;
|
||||
const context = {
|
||||
conditions: getDefaultConditions(),
|
||||
importAssertions,
|
||||
importAttributes,
|
||||
parentURL,
|
||||
};
|
||||
const meta = {
|
||||
@ -220,9 +245,9 @@ class Hooks {
|
||||
throw new ERR_LOADER_CHAIN_INCOMPLETE(hookErrIdentifier);
|
||||
}
|
||||
|
||||
let resolvedImportAttributes;
|
||||
const {
|
||||
format,
|
||||
importAssertions: resolvedImportAssertions,
|
||||
url,
|
||||
} = resolution;
|
||||
|
||||
@ -252,15 +277,22 @@ class Hooks {
|
||||
this.#validatedUrls.add(url);
|
||||
}
|
||||
|
||||
if (!('importAttributes' in resolution) && ('importAssertions' in resolution)) {
|
||||
emitImportAssertionWarning();
|
||||
resolvedImportAttributes = resolution.importAssertions;
|
||||
} else {
|
||||
resolvedImportAttributes = resolution.importAttributes;
|
||||
}
|
||||
|
||||
if (
|
||||
resolvedImportAssertions != null &&
|
||||
typeof resolvedImportAssertions !== 'object'
|
||||
resolvedImportAttributes != null &&
|
||||
typeof resolvedImportAttributes !== 'object'
|
||||
) {
|
||||
throw new ERR_INVALID_RETURN_PROPERTY_VALUE(
|
||||
'an object',
|
||||
hookErrIdentifier,
|
||||
'importAssertions',
|
||||
resolvedImportAssertions,
|
||||
'importAttributes',
|
||||
resolvedImportAttributes,
|
||||
);
|
||||
}
|
||||
|
||||
@ -279,12 +311,12 @@ class Hooks {
|
||||
return {
|
||||
__proto__: null,
|
||||
format,
|
||||
importAssertions: resolvedImportAssertions,
|
||||
importAttributes: resolvedImportAttributes,
|
||||
url,
|
||||
};
|
||||
}
|
||||
|
||||
resolveSync(_originalSpecifier, _parentURL, _importAssertions) {
|
||||
resolveSync(_originalSpecifier, _parentURL, _importAttributes) {
|
||||
throw new ERR_METHOD_NOT_IMPLEMENTED('resolveSync()');
|
||||
}
|
||||
|
||||
@ -347,7 +379,7 @@ class Hooks {
|
||||
|
||||
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
|
||||
|
||||
validateOutput(hookErrIdentifier, loaded);
|
||||
|
@ -8,7 +8,7 @@ const {
|
||||
const { kEmptyObject } = require('internal/util');
|
||||
|
||||
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 { readFileSync } = require('fs');
|
||||
|
||||
@ -107,19 +107,29 @@ function getSourceSync(url, context) {
|
||||
*/
|
||||
async function defaultLoad(url, context = kEmptyObject) {
|
||||
let responseURL = url;
|
||||
const { importAssertions } = context;
|
||||
let {
|
||||
importAttributes,
|
||||
format,
|
||||
source,
|
||||
} = 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);
|
||||
|
||||
throwIfUnsupportedURLScheme(urlInstance, experimentalNetworkImports);
|
||||
|
||||
format ??= await defaultGetFormat(urlInstance, context);
|
||||
|
||||
validateAssertions(url, format, importAssertions);
|
||||
validateAttributes(url, format, importAttributes);
|
||||
|
||||
if (
|
||||
format === 'builtin' ||
|
||||
@ -141,7 +151,7 @@ async function defaultLoad(url, context = kEmptyObject) {
|
||||
* @typedef LoadContext
|
||||
* @property {string} [format] A hint (possibly returned from `resolve`)
|
||||
* @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) {
|
||||
let responseURL = url;
|
||||
const { importAssertions } = context;
|
||||
const { importAttributes } = context;
|
||||
let {
|
||||
format,
|
||||
source,
|
||||
@ -170,7 +180,7 @@ function defaultLoadSync(url, context = kEmptyObject) {
|
||||
|
||||
format ??= defaultGetFormat(urlInstance, context);
|
||||
|
||||
validateAssertions(url, format, importAssertions);
|
||||
validateAttributes(url, format, importAttributes);
|
||||
|
||||
if (format === 'builtin') {
|
||||
source = null;
|
||||
|
@ -165,12 +165,12 @@ class ModuleLoader {
|
||||
* resolve(
|
||||
* originalSpecifier:
|
||||
* string, parentURL: string,
|
||||
* importAssertions: Record<string, string>
|
||||
* importAttributes: Record<string, string>
|
||||
* ): Promise<ResolveResult>
|
||||
* resolveSync(
|
||||
* originalSpecifier:
|
||||
* string, parentURL: string,
|
||||
* importAssertions: Record<string, string>
|
||||
* importAttributes: Record<string, string>
|
||||
* ) ResolveResult;
|
||||
* register(specifier: string, parentURL: string): any;
|
||||
* forceLoadHooks(): void;
|
||||
@ -204,8 +204,8 @@ class ModuleLoader {
|
||||
registerModule(module, {
|
||||
__proto__: null,
|
||||
initializeImportMeta: (meta, wrap) => this.importMetaInitialize(meta, { url }),
|
||||
importModuleDynamically: (specifier, { url }, importAssertions) => {
|
||||
return this.import(specifier, url, importAssertions);
|
||||
importModuleDynamically: (specifier, { url }, importAttributes) => {
|
||||
return this.import(specifier, url, importAttributes);
|
||||
},
|
||||
});
|
||||
|
||||
@ -232,24 +232,24 @@ class ModuleLoader {
|
||||
* @param {string | undefined} parentURL The URL of the module importing this
|
||||
* one, unless this is the Node.js entry
|
||||
* point.
|
||||
* @param {Record<string, string>} importAssertions Validations for the
|
||||
* @param {Record<string, string>} importAttributes Validations for the
|
||||
* module import.
|
||||
* @returns {Promise<ModuleJob>} The (possibly pending) module job
|
||||
*/
|
||||
async getModuleJob(specifier, parentURL, importAssertions) {
|
||||
const resolveResult = await this.resolve(specifier, parentURL, importAssertions);
|
||||
return this.getJobFromResolveResult(resolveResult, parentURL, importAssertions);
|
||||
async getModuleJob(specifier, parentURL, importAttributes) {
|
||||
const resolveResult = await this.resolve(specifier, parentURL, importAttributes);
|
||||
return this.getJobFromResolveResult(resolveResult, parentURL, importAttributes);
|
||||
}
|
||||
|
||||
getModuleJobSync(specifier, parentURL, importAssertions) {
|
||||
const resolveResult = this.resolveSync(specifier, parentURL, importAssertions);
|
||||
return this.getJobFromResolveResult(resolveResult, parentURL, importAssertions, true);
|
||||
getModuleJobSync(specifier, parentURL, importAttributes) {
|
||||
const resolveResult = this.resolveSync(specifier, parentURL, importAttributes);
|
||||
return this.getJobFromResolveResult(resolveResult, parentURL, importAttributes, true);
|
||||
}
|
||||
|
||||
getJobFromResolveResult(resolveResult, parentURL, importAssertions, sync) {
|
||||
getJobFromResolveResult(resolveResult, parentURL, importAttributes, sync) {
|
||||
const { url, format } = resolveResult;
|
||||
const resolvedImportAssertions = resolveResult.importAssertions ?? importAssertions;
|
||||
let job = this.loadCache.get(url, resolvedImportAssertions.type);
|
||||
const resolvedImportAttributes = resolveResult.importAttributes ?? importAttributes;
|
||||
let job = this.loadCache.get(url, resolvedImportAttributes.type);
|
||||
|
||||
// CommonJS will set functions for lazy job evaluation.
|
||||
if (typeof job === 'function') {
|
||||
@ -257,7 +257,7 @@ class ModuleLoader {
|
||||
}
|
||||
|
||||
if (job === undefined) {
|
||||
job = this.#createModuleJob(url, resolvedImportAssertions, parentURL, format, sync);
|
||||
job = this.#createModuleJob(url, resolvedImportAttributes, parentURL, format, sync);
|
||||
}
|
||||
|
||||
return job;
|
||||
@ -266,7 +266,7 @@ class ModuleLoader {
|
||||
/**
|
||||
* Create and cache an object representing a loaded 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.
|
||||
* @param {string} [parentURL] The absolute URL of the module importing this
|
||||
* one, unless this is the Node.js entry point
|
||||
@ -274,7 +274,7 @@ class ModuleLoader {
|
||||
* `resolve` hook
|
||||
* @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 translator = getTranslators().get(finalFormat);
|
||||
|
||||
@ -284,7 +284,8 @@ class ModuleLoader {
|
||||
|
||||
return FunctionPrototypeCall(translator, this, responseURL, source, isMain);
|
||||
};
|
||||
const context = { format, importAssertions };
|
||||
const context = { format, importAttributes };
|
||||
|
||||
const moduleProvider = sync ?
|
||||
(url, isMain) => callTranslator(this.loadSync(url, context), isMain) :
|
||||
async (url, isMain) => callTranslator(await this.load(url, context), isMain);
|
||||
@ -302,14 +303,14 @@ class ModuleLoader {
|
||||
const job = new ModuleJob(
|
||||
this,
|
||||
url,
|
||||
importAssertions,
|
||||
importAttributes,
|
||||
moduleProvider,
|
||||
parentURL === undefined,
|
||||
inspectBrk,
|
||||
sync,
|
||||
);
|
||||
|
||||
this.loadCache.set(url, importAssertions.type, job);
|
||||
this.loadCache.set(url, importAttributes.type, job);
|
||||
|
||||
return job;
|
||||
}
|
||||
@ -319,12 +320,12 @@ class ModuleLoader {
|
||||
* Use directly with caution.
|
||||
* @param {string} specifier The first parameter of an `import()` expression.
|
||||
* @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.
|
||||
* @returns {Promise<ModuleExports>}
|
||||
*/
|
||||
async import(specifier, parentURL, importAssertions) {
|
||||
const moduleJob = await this.getModuleJob(specifier, parentURL, importAssertions);
|
||||
async import(specifier, parentURL, importAttributes) {
|
||||
const moduleJob = await this.getModuleJob(specifier, parentURL, importAttributes);
|
||||
const { module } = await moduleJob.run();
|
||||
return module.getNamespace();
|
||||
}
|
||||
@ -348,20 +349,20 @@ class ModuleLoader {
|
||||
* @param {string} originalSpecifier The specified URL path of the module to
|
||||
* be resolved.
|
||||
* @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.
|
||||
* @returns {{ format: string, url: URL['href'] }}
|
||||
*/
|
||||
resolve(originalSpecifier, parentURL, importAssertions) {
|
||||
resolve(originalSpecifier, parentURL, importAttributes) {
|
||||
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);
|
||||
if (cachedResult != null) {
|
||||
return cachedResult;
|
||||
}
|
||||
const result = this.defaultResolve(originalSpecifier, parentURL, importAssertions);
|
||||
const result = this.defaultResolve(originalSpecifier, parentURL, importAttributes);
|
||||
this.#resolveCache.set(requestKey, parentURL, result);
|
||||
return result;
|
||||
}
|
||||
@ -370,11 +371,11 @@ class ModuleLoader {
|
||||
* Just like `resolve` except synchronous. This is here specifically to support
|
||||
* `import.meta.resolve` which must happen synchronously.
|
||||
*/
|
||||
resolveSync(originalSpecifier, parentURL, importAssertions) {
|
||||
resolveSync(originalSpecifier, parentURL, importAttributes) {
|
||||
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
|
||||
* repeating the same code block twice in those functions.
|
||||
*/
|
||||
defaultResolve(originalSpecifier, parentURL, importAssertions) {
|
||||
defaultResolve(originalSpecifier, parentURL, importAttributes) {
|
||||
defaultResolve ??= require('internal/modules/esm/resolve').defaultResolve;
|
||||
|
||||
const context = {
|
||||
__proto__: null,
|
||||
conditions: this.#defaultConditions,
|
||||
importAssertions,
|
||||
importAttributes,
|
||||
parentURL,
|
||||
};
|
||||
|
||||
@ -483,17 +484,17 @@ class CustomizedModuleLoader {
|
||||
* @param {string} originalSpecifier The specified URL path of the module to
|
||||
* be resolved.
|
||||
* @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.
|
||||
* @returns {{ format: string, url: URL['href'] }}
|
||||
*/
|
||||
resolve(originalSpecifier, parentURL, importAssertions) {
|
||||
return hooksProxy.makeAsyncRequest('resolve', undefined, originalSpecifier, parentURL, importAssertions);
|
||||
resolve(originalSpecifier, parentURL, importAttributes) {
|
||||
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.
|
||||
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 {
|
||||
// `loader` is the Loader instance used for loading dependencies.
|
||||
// `moduleProvider` is a function
|
||||
constructor(loader, url, importAssertions = { __proto__: null },
|
||||
constructor(loader, url, importAttributes = { __proto__: null },
|
||||
moduleProvider, isMain, inspectBrk, sync = false) {
|
||||
this.loader = loader;
|
||||
this.importAssertions = importAssertions;
|
||||
this.importAttributes = importAttributes;
|
||||
this.isMain = isMain;
|
||||
this.inspectBrk = inspectBrk;
|
||||
|
||||
@ -81,8 +81,8 @@ class ModuleJob {
|
||||
// so that circular dependencies can't cause a deadlock by two of
|
||||
// these `link` callbacks depending on each other.
|
||||
const dependencyJobs = [];
|
||||
const promises = this.module.link(async (specifier, assertions) => {
|
||||
const job = await this.loader.getModuleJob(specifier, url, assertions);
|
||||
const promises = this.module.link(async (specifier, attributes) => {
|
||||
const job = await this.loader.getModuleJob(specifier, url, attributes);
|
||||
ArrayPrototypePush(dependencyJobs, job);
|
||||
return job.modulePromise;
|
||||
});
|
||||
@ -157,7 +157,7 @@ class ModuleJob {
|
||||
let format;
|
||||
try {
|
||||
// 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.
|
||||
({ format } =
|
||||
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.
|
||||
* 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
|
||||
* https://tc39.es/ecma262/#sec-HostLoadImportedModule.
|
||||
* 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.
|
||||
* @param {string} specifier
|
||||
* @param {Record<string,string>} importAssertions
|
||||
* @param {Record<string,string>} importAttributes
|
||||
* @returns {string}
|
||||
*/
|
||||
serializeKey(specifier, importAssertions) {
|
||||
// To serialize the ModuleRequest (specifier + list of import assertions),
|
||||
// we need to sort the assertions by key, then stringifying,
|
||||
// so that different import statements with the same assertions are always treated
|
||||
serializeKey(specifier, importAttributes) {
|
||||
// To serialize the ModuleRequest (specifier + list of import attributes),
|
||||
// we need to sort the attributes by key, then stringifying,
|
||||
// so that different import statements with the same attributes are always treated
|
||||
// as identical.
|
||||
const keys = ObjectKeys(importAssertions);
|
||||
const keys = ObjectKeys(importAttributes);
|
||||
|
||||
if (keys.length === 0) {
|
||||
return specifier + '::';
|
||||
@ -47,7 +47,7 @@ class ResolveCache extends SafeMap {
|
||||
return specifier + '::' + ArrayPrototypeJoin(
|
||||
ArrayPrototypeMap(
|
||||
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 {object} options - An object containing options for 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.
|
||||
*/
|
||||
async function importModuleDynamically(specifier, { url }, assertions) {
|
||||
return asyncESM.esmLoader.import(specifier, url, assertions);
|
||||
async function importModuleDynamically(specifier, { url }, attributes) {
|
||||
return asyncESM.esmLoader.import(specifier, url, attributes);
|
||||
}
|
||||
|
||||
// Strategy for loading a standard JavaScript module.
|
||||
@ -201,8 +201,8 @@ function loadCJSModule(module, source, url, filename) {
|
||||
'__dirname',
|
||||
], {
|
||||
filename,
|
||||
importModuleDynamically(specifier, _, importAssertions) {
|
||||
return asyncESM.esmLoader.import(specifier, url, importAssertions);
|
||||
importModuleDynamically(specifier, _, importAttributes) {
|
||||
return asyncESM.esmLoader.import(specifier, url, importAttributes);
|
||||
},
|
||||
}).function;
|
||||
} catch (err) {
|
||||
@ -213,14 +213,14 @@ function loadCJSModule(module, source, url, filename) {
|
||||
const __dirname = dirname(filename);
|
||||
// eslint-disable-next-line func-name-matching,func-style
|
||||
const requireFn = function require(specifier) {
|
||||
let importAssertions = kEmptyObject;
|
||||
let importAttributes = kEmptyObject;
|
||||
if (!StringPrototypeStartsWith(specifier, 'node:')) {
|
||||
// TODO: do not depend on the monkey-patchable CJS loader here.
|
||||
const path = CJSModule._resolveFilename(specifier, module);
|
||||
if (specifier !== path) {
|
||||
switch (extname(path)) {
|
||||
case '.json':
|
||||
importAssertions = { __proto__: null, type: 'json' };
|
||||
importAttributes = { __proto__: null, type: 'json' };
|
||||
break;
|
||||
case '.node':
|
||||
return CJSModule._load(specifier, module);
|
||||
@ -230,7 +230,7 @@ function loadCJSModule(module, source, url, filename) {
|
||||
specifier = `${pathToFileURL(path)}`;
|
||||
}
|
||||
}
|
||||
const job = asyncESM.esmLoader.getModuleJobSync(specifier, url, importAssertions);
|
||||
const job = asyncESM.esmLoader.getModuleJobSync(specifier, url, importAttributes);
|
||||
job.runSync();
|
||||
return cjsCache.get(job.url).exports;
|
||||
};
|
||||
|
@ -88,7 +88,7 @@ function getConditionsSet(conditions) {
|
||||
* @callback ImportModuleDynamicallyCallback
|
||||
* @param {string} specifier
|
||||
* @param {ModuleWrap|ContextifyScript|Function|vm.Module} callbackReferrer
|
||||
* @param {object} assertions
|
||||
* @param {Record<string, string>} attributes
|
||||
* @returns { Promise<void> }
|
||||
*/
|
||||
|
||||
@ -162,15 +162,15 @@ function initializeImportMetaObject(symbol, meta) {
|
||||
* Asynchronously imports a module dynamically using a callback function. The native callback.
|
||||
* @param {symbol} symbol - Reference to the module.
|
||||
* @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.
|
||||
* @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)) {
|
||||
const { importModuleDynamically, callbackReferrer } = moduleRegistries.get(symbol);
|
||||
if (importModuleDynamically !== undefined) {
|
||||
return importModuleDynamically(specifier, callbackReferrer, assertions);
|
||||
return importModuleDynamically(specifier, callbackReferrer, attributes);
|
||||
}
|
||||
}
|
||||
throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING();
|
||||
|
@ -84,9 +84,9 @@ function evalScript(name, body, breakFirstLine, print, shouldLoadESM = false) {
|
||||
filename: name,
|
||||
displayErrors: true,
|
||||
[kVmBreakFirstLineSymbol]: !!breakFirstLine,
|
||||
importModuleDynamically(specifier, _, importAssertions) {
|
||||
importModuleDynamically(specifier, _, importAttributes) {
|
||||
const loader = asyncESM.esmLoader;
|
||||
return loader.import(specifier, baseUrl, importAssertions);
|
||||
return loader.import(specifier, baseUrl, importAttributes);
|
||||
},
|
||||
}));
|
||||
if (print) {
|
||||
|
@ -483,9 +483,9 @@ function REPLServer(prompt,
|
||||
vm.createScript(fallbackCode, {
|
||||
filename: file,
|
||||
displayErrors: true,
|
||||
importModuleDynamically: (specifier, _, importAssertions) => {
|
||||
importModuleDynamically: (specifier, _, importAttributes) => {
|
||||
return asyncESM.esmLoader.import(specifier, parentURL,
|
||||
importAssertions);
|
||||
importAttributes);
|
||||
},
|
||||
});
|
||||
} catch (fallbackError) {
|
||||
@ -527,9 +527,9 @@ function REPLServer(prompt,
|
||||
script = vm.createScript(code, {
|
||||
filename: file,
|
||||
displayErrors: true,
|
||||
importModuleDynamically: (specifier, _, importAssertions) => {
|
||||
importModuleDynamically: (specifier, _, importAttributes) => {
|
||||
return asyncESM.esmLoader.import(specifier, parentURL,
|
||||
importAssertions);
|
||||
importAttributes);
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
|
@ -249,19 +249,19 @@ void ModuleWrap::New(const FunctionCallbackInfo<Value>& args) {
|
||||
args.GetReturnValue().Set(that);
|
||||
}
|
||||
|
||||
static Local<Object> createImportAssertionContainer(Environment* env,
|
||||
Isolate* isolate, Local<FixedArray> raw_assertions) {
|
||||
Local<Object> assertions =
|
||||
Object::New(isolate, v8::Null(env->isolate()), nullptr, nullptr, 0);
|
||||
for (int i = 0; i < raw_assertions->Length(); i += 3) {
|
||||
assertions
|
||||
->Set(env->context(),
|
||||
raw_assertions->Get(env->context(), i).As<String>(),
|
||||
raw_assertions->Get(env->context(), i + 1).As<Value>())
|
||||
.ToChecked();
|
||||
static Local<Object> createImportAttributesContainer(
|
||||
Environment* env, Isolate* isolate, Local<FixedArray> raw_attributes) {
|
||||
Local<Object> attributes =
|
||||
Object::New(isolate, v8::Null(env->isolate()), nullptr, nullptr, 0);
|
||||
for (int i = 0; i < raw_attributes->Length(); i += 3) {
|
||||
attributes
|
||||
->Set(env->context(),
|
||||
raw_attributes->Get(env->context(), i).As<String>(),
|
||||
raw_attributes->Get(env->context(), i + 1).As<Value>())
|
||||
.ToChecked();
|
||||
}
|
||||
|
||||
return assertions;
|
||||
return attributes;
|
||||
}
|
||||
|
||||
void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
|
||||
@ -297,13 +297,13 @@ void ModuleWrap::Link(const FunctionCallbackInfo<Value>& args) {
|
||||
Utf8Value specifier_utf8(env->isolate(), specifier);
|
||||
std::string specifier_std(*specifier_utf8, specifier_utf8.length());
|
||||
|
||||
Local<FixedArray> raw_assertions = module_request->GetImportAssertions();
|
||||
Local<Object> assertions =
|
||||
createImportAssertionContainer(env, isolate, raw_assertions);
|
||||
Local<FixedArray> raw_attributes = module_request->GetImportAssertions();
|
||||
Local<Object> attributes =
|
||||
createImportAttributesContainer(env, isolate, raw_attributes);
|
||||
|
||||
Local<Value> argv[] = {
|
||||
specifier,
|
||||
assertions,
|
||||
attributes,
|
||||
};
|
||||
|
||||
MaybeLocal<Value> maybe_resolve_return_value =
|
||||
@ -499,7 +499,7 @@ void ModuleWrap::GetError(const FunctionCallbackInfo<Value>& args) {
|
||||
MaybeLocal<Module> ModuleWrap::ResolveModuleCallback(
|
||||
Local<Context> context,
|
||||
Local<String> specifier,
|
||||
Local<FixedArray> import_assertions,
|
||||
Local<FixedArray> import_attributes,
|
||||
Local<Module> referrer) {
|
||||
Environment* env = Environment::GetCurrent(context);
|
||||
if (env == nullptr) {
|
||||
@ -552,7 +552,7 @@ static MaybeLocal<Promise> ImportModuleDynamically(
|
||||
Local<v8::Data> host_defined_options,
|
||||
Local<Value> resource_name,
|
||||
Local<String> specifier,
|
||||
Local<FixedArray> import_assertions) {
|
||||
Local<FixedArray> import_attributes) {
|
||||
Isolate* isolate = context->GetIsolate();
|
||||
Environment* env = Environment::GetCurrent(context);
|
||||
if (env == nullptr) {
|
||||
@ -580,13 +580,13 @@ static MaybeLocal<Promise> ImportModuleDynamically(
|
||||
Local<Symbol> id =
|
||||
options->Get(context, HostDefinedOptions::kID).As<Symbol>();
|
||||
|
||||
Local<Object> assertions =
|
||||
createImportAssertionContainer(env, isolate, import_assertions);
|
||||
Local<Object> attributes =
|
||||
createImportAttributesContainer(env, isolate, import_attributes);
|
||||
|
||||
Local<Value> import_args[] = {
|
||||
id,
|
||||
Local<Value>(specifier),
|
||||
assertions,
|
||||
attributes,
|
||||
};
|
||||
|
||||
Local<Value> result;
|
||||
|
@ -97,7 +97,7 @@ class ModuleWrap : public BaseObject {
|
||||
static v8::MaybeLocal<v8::Module> ResolveModuleCallback(
|
||||
v8::Local<v8::Context> context,
|
||||
v8::Local<v8::String> specifier,
|
||||
v8::Local<v8::FixedArray> import_assertions,
|
||||
v8::Local<v8::FixedArray> import_attributes,
|
||||
v8::Local<v8::Module> referrer);
|
||||
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()) {
|
||||
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;
|
||||
if (std::find(v8_args.begin(), v8_args.end(),
|
||||
|
@ -9,7 +9,7 @@ async function test() {
|
||||
import('../fixtures/experimental.json'),
|
||||
import(
|
||||
'../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',
|
||||
{ assert: { type: 'json' } }
|
||||
{ with: { type: 'json' } }
|
||||
),
|
||||
]);
|
||||
|
||||
@ -39,7 +39,7 @@ async function test() {
|
||||
import('../fixtures/experimental.json#test'),
|
||||
import(
|
||||
'../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',
|
||||
{ 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}',
|
||||
{ assert: { type: 'json' } }
|
||||
{ with: { type: 'json' } }
|
||||
),
|
||||
]);
|
||||
|
||||
|
@ -60,21 +60,21 @@ function createBase64URL(mime, body) {
|
||||
}
|
||||
{
|
||||
const ns = await import('data:application/json;foo="test,"this"',
|
||||
{ assert: { type: 'json' } });
|
||||
{ with: { type: 'json' } });
|
||||
assert.deepStrictEqual(Object.keys(ns), ['default']);
|
||||
assert.strictEqual(ns.default, 'this');
|
||||
}
|
||||
{
|
||||
const ns = await import(`data:application/json;foo=${
|
||||
encodeURIComponent('test,')
|
||||
},0`, { assert: { type: 'json' } });
|
||||
},0`, { with: { type: 'json' } });
|
||||
assert.deepStrictEqual(Object.keys(ns), ['default']);
|
||||
assert.strictEqual(ns.default, 0);
|
||||
}
|
||||
{
|
||||
await assert.rejects(async () =>
|
||||
import('data:application/json;foo="test,",0',
|
||||
{ assert: { type: 'json' } }), {
|
||||
{ with: { type: 'json' } }), {
|
||||
name: 'SyntaxError',
|
||||
message: /Unterminated string in JSON at position 3/
|
||||
});
|
||||
@ -82,14 +82,14 @@ function createBase64URL(mime, body) {
|
||||
{
|
||||
const body = '{"x": 1}';
|
||||
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.strictEqual(ns.default.x, 1);
|
||||
}
|
||||
{
|
||||
const body = '{"default": 2}';
|
||||
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.strictEqual(ns.default.default, 2);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ const { strictEqual } = require('assert');
|
||||
async function test() {
|
||||
{
|
||||
const results = await Promise.allSettled([
|
||||
import('../fixtures/empty.js', { assert: { type: 'json' } }),
|
||||
import('../fixtures/empty.js', { with: { type: 'json' } }),
|
||||
import('../fixtures/empty.js'),
|
||||
]);
|
||||
|
||||
@ -16,7 +16,7 @@ async function test() {
|
||||
{
|
||||
const results = await Promise.allSettled([
|
||||
import('../fixtures/empty.js'),
|
||||
import('../fixtures/empty.js', { assert: { type: 'json' } }),
|
||||
import('../fixtures/empty.js', { with: { type: 'json' } }),
|
||||
]);
|
||||
|
||||
strictEqual(results[0].status, 'fulfilled');
|
||||
@ -25,7 +25,7 @@ async function test() {
|
||||
|
||||
{
|
||||
const results = await Promise.allSettled([
|
||||
import('../fixtures/empty.json', { assert: { type: 'json' } }),
|
||||
import('../fixtures/empty.json', { with: { type: 'json' } }),
|
||||
import('../fixtures/empty.json'),
|
||||
]);
|
||||
|
||||
@ -36,7 +36,7 @@ async function test() {
|
||||
{
|
||||
const results = await Promise.allSettled([
|
||||
import('../fixtures/empty.json'),
|
||||
import('../fixtures/empty.json', { assert: { type: 'json' } }),
|
||||
import('../fixtures/empty.json', { with: { type: 'json' } }),
|
||||
]);
|
||||
|
||||
strictEqual(results[0].status, 'rejected');
|
@ -3,7 +3,7 @@ import { strictEqual } from 'assert';
|
||||
|
||||
{
|
||||
const results = await Promise.allSettled([
|
||||
import('../fixtures/empty.js', { assert: { type: 'json' } }),
|
||||
import('../fixtures/empty.js', { with: { type: 'json' } }),
|
||||
import('../fixtures/empty.js'),
|
||||
]);
|
||||
|
||||
@ -14,7 +14,7 @@ import { strictEqual } from 'assert';
|
||||
{
|
||||
const results = await Promise.allSettled([
|
||||
import('../fixtures/empty.js'),
|
||||
import('../fixtures/empty.js', { assert: { type: 'json' } }),
|
||||
import('../fixtures/empty.js', { with: { type: 'json' } }),
|
||||
]);
|
||||
|
||||
strictEqual(results[0].status, 'fulfilled');
|
||||
@ -23,7 +23,7 @@ import { strictEqual } from 'assert';
|
||||
|
||||
{
|
||||
const results = await Promise.allSettled([
|
||||
import('../fixtures/empty.json', { assert: { type: 'json' } }),
|
||||
import('../fixtures/empty.json', { with: { type: 'json' } }),
|
||||
import('../fixtures/empty.json'),
|
||||
]);
|
||||
|
||||
@ -34,7 +34,7 @@ import { strictEqual } from 'assert';
|
||||
{
|
||||
const results = await Promise.allSettled([
|
||||
import('../fixtures/empty.json'),
|
||||
import('../fixtures/empty.json', { assert: { type: 'json' } }),
|
||||
import('../fixtures/empty.json', { with: { type: 'json' } }),
|
||||
]);
|
||||
|
||||
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(
|
||||
'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 Promise.all([
|
||||
// Using importAssertions in the resolve hook should warn but still work.
|
||||
`data:text/javascript,export ${encodeURIComponent(function resolve() {
|
||||
return { shortCircuit: true, url: 'data:application/json,1', importAssertions: { type: 'json' } };
|
||||
})}`,
|
||||
// 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 { 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);
|
@ -1,9 +1,9 @@
|
||||
import '../common/index.mjs';
|
||||
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', {
|
||||
assert: { type: 'json' },
|
||||
with: { type: 'json' },
|
||||
});
|
||||
|
||||
strictEqual(secret0.ofLife, 42);
|
@ -1,9 +1,9 @@
|
||||
import '../common/index.mjs';
|
||||
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',
|
||||
{ assert: { type: 'json' } });
|
||||
{ with: { type: 'json' } });
|
||||
|
||||
strictEqual(secret0.ofLife, 42);
|
||||
strictEqual(secret1.default.ofLife, 42);
|
@ -5,31 +5,29 @@ const { rejects } = require('assert');
|
||||
const jsModuleDataUrl = 'data:text/javascript,export{}';
|
||||
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() {
|
||||
await rejects(
|
||||
import('data:text/css,', { assert: { type: 'css' } }),
|
||||
import('data:text/css,', { with: { type: 'css' } }),
|
||||
{ code: 'ERR_UNKNOWN_MODULE_FORMAT' }
|
||||
);
|
||||
|
||||
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' }
|
||||
);
|
||||
|
||||
await rejects(
|
||||
import(jsModuleDataUrl, { assert: { type: 'json' } }),
|
||||
import(jsModuleDataUrl, { with: { type: 'json' } }),
|
||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED' }
|
||||
);
|
||||
|
||||
await rejects(
|
||||
import(jsModuleDataUrl, { assert: { type: 'unsupported' } }),
|
||||
import(jsModuleDataUrl, { with: { type: 'unsupported' } }),
|
||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED' }
|
||||
);
|
||||
|
||||
@ -39,17 +37,17 @@ async function test() {
|
||||
);
|
||||
|
||||
await rejects(
|
||||
import(jsonModuleDataUrl, { assert: {} }),
|
||||
import(jsonModuleDataUrl, { with: {} }),
|
||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING' }
|
||||
);
|
||||
|
||||
await rejects(
|
||||
import(jsonModuleDataUrl, { assert: { foo: 'bar' } }),
|
||||
import(jsonModuleDataUrl, { with: { foo: 'bar' } }),
|
||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING' }
|
||||
);
|
||||
|
||||
await rejects(
|
||||
import(jsonModuleDataUrl, { assert: { type: 'unsupported' } }),
|
||||
import(jsonModuleDataUrl, { with: { 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';
|
||||
|
||||
const jsModuleDataUrl = 'data:text/javascript,export{}';
|
||||
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(
|
||||
// This rejects because of the unsupported MIME type, not because of the
|
||||
// unsupported assertion.
|
||||
import('data:text/css,', { assert: { type: 'css' } }),
|
||||
import('data:text/css,', { with: { type: 'css' } }),
|
||||
{ code: 'ERR_UNKNOWN_MODULE_FORMAT' }
|
||||
);
|
||||
|
||||
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' }
|
||||
);
|
||||
|
||||
await rejects(
|
||||
import(jsModuleDataUrl, { assert: { type: 'json' } }),
|
||||
import(jsModuleDataUrl, { with: { type: 'json' } }),
|
||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_FAILED' }
|
||||
);
|
||||
|
||||
await rejects(
|
||||
import(import.meta.url, { assert: { type: 'unsupported' } }),
|
||||
import(import.meta.url, { with: { type: 'unsupported' } }),
|
||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED' }
|
||||
);
|
||||
|
||||
@ -40,16 +32,16 @@ await rejects(
|
||||
);
|
||||
|
||||
await rejects(
|
||||
import(jsonModuleDataUrl, { assert: {} }),
|
||||
import(jsonModuleDataUrl, { with: {} }),
|
||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING' }
|
||||
);
|
||||
|
||||
await rejects(
|
||||
import(jsonModuleDataUrl, { assert: { foo: 'bar' } }),
|
||||
import(jsonModuleDataUrl, { with: { foo: 'bar' } }),
|
||||
{ code: 'ERR_IMPORT_ASSERTION_TYPE_MISSING' }
|
||||
);
|
||||
|
||||
await rejects(
|
||||
import(jsonModuleDataUrl, { assert: { type: 'unsupported' } }),
|
||||
import(jsonModuleDataUrl, { with: { 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 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' };
|
||||
|
||||
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 * 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', () => {
|
||||
it('should load JSON', () => {
|
||||
@ -20,7 +20,6 @@ describe('ESM: importing JSON', () => {
|
||||
]);
|
||||
|
||||
assert.match(stderr, /ExperimentalWarning: Importing JSON modules/);
|
||||
assert.match(stderr, /ExperimentalWarning: Import assertions/);
|
||||
assert.strictEqual(code, 0);
|
||||
assert.strictEqual(signal, null);
|
||||
});
|
||||
@ -35,19 +34,19 @@ describe('ESM: importing JSON', () => {
|
||||
const url = new URL('./foo.json', root);
|
||||
await writeFile(url, JSON.stringify({ id: i++ }));
|
||||
const absoluteURL = await import(`${url}`, {
|
||||
assert: { type: 'json' },
|
||||
with: { type: 'json' },
|
||||
});
|
||||
await writeFile(url, JSON.stringify({ id: i++ }));
|
||||
const queryString = await import(`${url}?a=2`, {
|
||||
assert: { type: 'json' },
|
||||
with: { type: 'json' },
|
||||
});
|
||||
await writeFile(url, JSON.stringify({ id: i++ }));
|
||||
const hash = await import(`${url}#a=2`, {
|
||||
assert: { type: 'json' },
|
||||
with: { type: 'json' },
|
||||
});
|
||||
await writeFile(url, JSON.stringify({ id: i++ }));
|
||||
const queryStringAndHash = await import(`${url}?a=2#a=2`, {
|
||||
assert: { type: 'json' },
|
||||
with: { type: 'json' },
|
||||
});
|
||||
|
||||
assert.notDeepStrictEqual(absoluteURL, queryString);
|
||||
|
@ -12,7 +12,7 @@ async function resolve(referrer, context, next) {
|
||||
}
|
||||
|
||||
function load(url, context, next) {
|
||||
if (context.importAssertions.type === 'json') {
|
||||
if (context.importAttributes.type === 'json') {
|
||||
return {
|
||||
shortCircuit: true,
|
||||
format: 'json',
|
||||
@ -25,6 +25,6 @@ function load(url, context, next) {
|
||||
register(`data:text/javascript,export ${encodeURIComponent(resolve)};export ${encodeURIComponent(load)}`);
|
||||
|
||||
assert.notDeepStrictEqual(
|
||||
await import(fixtures.fileURL('empty.json'), { assert: { type: 'json' } }),
|
||||
await import(fixtures.fileURL('empty.json'), { assert: { type: 'json' } }),
|
||||
await import(fixtures.fileURL('empty.json'), { with: { 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(\?[^#]*)?(#.*)?$/;
|
||||
|
||||
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.
|
||||
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).
|
||||
const result = await next(specifier, context);
|
||||
|
||||
if (noAssertionSpecified &&
|
||||
if (noAttributesSpecified &&
|
||||
(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.
|
||||
result.importAssertions = {
|
||||
...(result.importAssertions ?? context.importAssertions),
|
||||
// Clean new import attributes object to ensure that this test isn't passing due to mutation.
|
||||
result.importAttributes = {
|
||||
...(result.importAttributes ?? context.importAttributes),
|
||||
type: 'json',
|
||||
};
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ export async function resolve(specifier, context, next) {
|
||||
return {
|
||||
shortCircuit: true,
|
||||
url: `custom-${def.url}`,
|
||||
importAssertions: context.importAssertions,
|
||||
importAttributes: context.importAttributes,
|
||||
};
|
||||
}
|
||||
return def;
|
||||
|
@ -6,7 +6,7 @@ import count from '../es-modules/stateful.mjs';
|
||||
// used to assert node-land and user-land have different contexts
|
||||
count();
|
||||
|
||||
export function resolve(specifier, { importAssertions }, next) {
|
||||
export function resolve(specifier, { importAttributes }, next) {
|
||||
let format = '';
|
||||
|
||||
if (specifier === 'esmHook/format.false') {
|
||||
@ -24,7 +24,7 @@ export function resolve(specifier, { importAssertions }, next) {
|
||||
format,
|
||||
shortCircuit: true,
|
||||
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.deepStrictEqual(context.importAssertions, {});
|
||||
assert.deepStrictEqual(context.importAttributes, {});
|
||||
} else if (resolveCalls === 2) {
|
||||
url = new URL(specifier, context.parentURL).href;
|
||||
assert.match(specifier, /experimental\.json$/);
|
||||
assert.match(context.parentURL, /json-modules\.mjs$/);
|
||||
assert.deepStrictEqual(context.importAssertions, {
|
||||
assert.deepStrictEqual(context.importAttributes, {
|
||||
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
|
||||
assert.deepStrictEqual(Reflect.ownKeys(context), [
|
||||
'conditions',
|
||||
'importAssertions',
|
||||
'importAttributes',
|
||||
'parentURL',
|
||||
]);
|
||||
assert.ok(Array.isArray(context.conditions));
|
||||
@ -59,11 +59,11 @@ export async function load(url, context, next) {
|
||||
|
||||
if (loadCalls === 1) {
|
||||
assert.match(url, /json-modules\.mjs$/);
|
||||
assert.deepStrictEqual(context.importAssertions, {});
|
||||
assert.deepStrictEqual(context.importAttributes, {});
|
||||
format = 'module';
|
||||
} else if (loadCalls === 2) {
|
||||
assert.match(url, /experimental\.json$/);
|
||||
assert.deepStrictEqual(context.importAssertions, {
|
||||
assert.deepStrictEqual(context.importAttributes, {
|
||||
type: '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
|
||||
assert.deepStrictEqual(Object.keys(context), [
|
||||
'format',
|
||||
'importAssertions',
|
||||
'importAttributes',
|
||||
]);
|
||||
assert.strictEqual(context.format, 'test');
|
||||
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') {
|
||||
return {
|
||||
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') {
|
||||
return {
|
||||
shortCircuit: true,
|
||||
url: specifier,
|
||||
importAssertions,
|
||||
importAttributes,
|
||||
};
|
||||
}
|
||||
return next(specifier);
|
||||
|
@ -3,9 +3,9 @@ import {createRequire} from '../../common/index.mjs';
|
||||
const require = createRequire(import.meta.url);
|
||||
const dep = require('./loader-dep.js');
|
||||
|
||||
export async function resolve(specifier, { parentURL, importAssertions }, defaultResolve) {
|
||||
export async function resolve(specifier, { parentURL, importAttributes }, defaultResolve) {
|
||||
return {
|
||||
url: (await defaultResolve(specifier, { parentURL, importAssertions }, defaultResolve)).url,
|
||||
url: (await defaultResolve(specifier, { parentURL, importAttributes }, defaultResolve)).url,
|
||||
format: dep.format
|
||||
};
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import assert from 'node:assert';
|
||||
// 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).
|
||||
let mainLoad = true;
|
||||
export async function resolve(specifier, { importAssertions }, next) {
|
||||
export async function resolve(specifier, { importAttributes }, next) {
|
||||
if (mainLoad || specifier === 'path' || specifier === 'worker_threads') {
|
||||
mainLoad = false;
|
||||
return next(specifier);
|
||||
@ -11,6 +11,6 @@ export async function resolve(specifier, { importAssertions }, next) {
|
||||
await assert.rejects(next(specifier), { code: 'ERR_MODULE_NOT_FOUND' });
|
||||
return {
|
||||
url: 'node:fs',
|
||||
importAssertions,
|
||||
importAttributes,
|
||||
};
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ const SOURCES = {
|
||||
export function resolve(specifier, context, next) {
|
||||
if (specifier.startsWith('test:')) {
|
||||
return {
|
||||
importAssertions: context.importAssertions,
|
||||
importAttributes: context.importAttributes,
|
||||
shortCircuit: true,
|
||||
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" } })', {
|
||||
importModuleDynamically: common.mustCall((specifier, wrap, assertion) => {
|
||||
const s = new Script('import("foo", { with: { key: "value" } })', {
|
||||
importModuleDynamically: common.mustCall((specifier, wrap, attributes) => {
|
||||
assert.strictEqual(specifier, 'foo');
|
||||
assert.strictEqual(wrap, s);
|
||||
assert.deepStrictEqual(assertion, { __proto__: null, key: 'value' });
|
||||
assert.deepStrictEqual(attributes, { __proto__: null, key: 'value' });
|
||||
return foo;
|
||||
}),
|
||||
});
|
||||
|
@ -47,7 +47,7 @@ rm -rf ../node_modules/eslint
|
||||
eslint-plugin-markdown \
|
||||
@babel/core \
|
||||
@babel/eslint-parser \
|
||||
@babel/plugin-syntax-import-assertions
|
||||
@babel/plugin-syntax-import-attributes
|
||||
)
|
||||
(
|
||||
cd node_modules/eslint
|
||||
@ -62,7 +62,7 @@ rm -rf ../node_modules/eslint
|
||||
eslint-plugin-markdown \
|
||||
@babel/core \
|
||||
@babel/eslint-parser \
|
||||
@babel/plugin-syntax-import-assertions
|
||||
@babel/plugin-syntax-import-attributes
|
||||
)
|
||||
# Use dmn to remove some unneeded files.
|
||||
"$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",
|
||||
"description": "Allow parsing of the module assertion attributes in the import statement",
|
||||
"description": "Allow parsing of the module attributes in the import statement",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/babel/babel.git",
|
||||
"directory": "packages/babel-plugin-syntax-import-assertions"
|
||||
"directory": "packages/babel-plugin-syntax-import-attributes"
|
||||
},
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
@ -28,5 +28,9 @@
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"author": "The Babel Team (https://babel.dev/team)",
|
||||
"exports": {
|
||||
".": "./lib/index.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"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",
|
||||
"version": "1.0.30001546",
|
||||
"version": "1.0.30001547",
|
||||
"description": "A smaller version of caniuse-db, with only the essentials!",
|
||||
"main": "dist/unpacker/index.js",
|
||||
"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.24",
|
||||
"22.3.25",
|
||||
"22.3.26"
|
||||
"22.3.26",
|
||||
"22.3.27"
|
||||
],
|
||||
"110.0.5415.0": [
|
||||
"23.0.0-alpha.1",
|
||||
@ -2512,7 +2513,8 @@ module.exports = {
|
||||
"24.8.3",
|
||||
"24.8.4",
|
||||
"24.8.5",
|
||||
"24.8.6"
|
||||
"24.8.6",
|
||||
"24.8.7"
|
||||
],
|
||||
"114.0.5694.0": [
|
||||
"25.0.0-alpha.1",
|
||||
@ -2812,6 +2814,9 @@ module.exports = {
|
||||
"27.0.0-nightly.20230814",
|
||||
"27.0.0-nightly.20230815"
|
||||
],
|
||||
"118.0.5993.54": [
|
||||
"27.0.0"
|
||||
],
|
||||
"118.0.5991.0": [
|
||||
"28.0.0-nightly.20230906"
|
||||
],
|
||||
@ -2847,6 +2852,8 @@ module.exports = {
|
||||
"28.0.0-nightly.20231005"
|
||||
],
|
||||
"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.25": "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.2": "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.5": "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.2": "114.0.5694.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.20230815": "117.0.5921.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.20230818": "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.20231004": "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",
|
||||
"version": "1.4.544",
|
||||
"version": "1.4.549",
|
||||
"description": "Provides a list of electron-to-chromium version mappings",
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
|
Loading…
x
Reference in New Issue
Block a user