mirror of https://github.com/nodejs/node.git
module: add module.stripTypeScriptTypes
PR-URL: https://github.com/nodejs/node/pull/55282 Fixes: https://github.com/nodejs/node/issues/54300 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Chemi Atlow <chemi@atlow.co.il> Reviewed-By: Paolo Insogna <paolo@cowtech.it> Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <rlau@redhat.com>
This commit is contained in:
parent
cbb72ebfa7
commit
53b1050e6f
|
@ -270,6 +270,105 @@ changes:
|
|||
Register a module that exports [hooks][] that customize Node.js module
|
||||
resolution and loading behavior. See [Customization hooks][].
|
||||
|
||||
## `module.stripTypeScriptTypes(code[, options])`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
> Stability: 1.0 - Early development
|
||||
|
||||
* `code` {string} The code to strip type annotations from.
|
||||
* `options` {Object}
|
||||
* `mode` {string} **Default:** `'strip'`. Possible values are:
|
||||
* `'strip'` Only strip type annotations without performing the transformation of TypeScript features.
|
||||
* `'transform'` Strip type annotations and transform TypeScript features to JavaScript.
|
||||
* `sourceMap` {boolean} **Default:** `false`. Only when `mode` is `'transform'`, if `true`, a source map
|
||||
will be generated for the transformed code.
|
||||
* `sourceUrl` {string} Specifies the source url used in the source map.
|
||||
* Returns: {string} The code with type annotations stripped.
|
||||
`module.stripTypeScriptTypes()` removes type annotations from TypeScript code. It
|
||||
can be used to strip type annotations from TypeScript code before running it
|
||||
with `vm.runInContext()` or `vm.compileFunction()`.
|
||||
By default, it will throw an error if the code contains TypeScript features
|
||||
that require transformation such as `Enums`,
|
||||
see [type-stripping][] for more information.
|
||||
When mode is `'transform'`, it also transforms TypeScript features to JavaScript,
|
||||
see [transform TypeScript features][] for more information.
|
||||
When mode is `'strip'`, source maps are not generated, because locations are preserved.
|
||||
If `sourceMap` is provided, when mode is `'strip'`, an error will be thrown.
|
||||
|
||||
_WARNING_: The output of this function should not be considered stable across Node.js versions,
|
||||
due to changes in the TypeScript parser.
|
||||
|
||||
```mjs
|
||||
import { stripTypeScriptTypes } from 'node:module';
|
||||
const code = 'const a: number = 1;';
|
||||
const strippedCode = stripTypeScriptTypes(code);
|
||||
console.log(strippedCode);
|
||||
// Prints: const a = 1;
|
||||
```
|
||||
|
||||
```cjs
|
||||
const { stripTypeScriptTypes } = require('node:module');
|
||||
const code = 'const a: number = 1;';
|
||||
const strippedCode = stripTypeScriptTypes(code);
|
||||
console.log(strippedCode);
|
||||
// Prints: const a = 1;
|
||||
```
|
||||
|
||||
If `sourceUrl` is provided, it will be used appended as a comment at the end of the output:
|
||||
|
||||
```mjs
|
||||
import { stripTypeScriptTypes } from 'node:module';
|
||||
const code = 'const a: number = 1;';
|
||||
const strippedCode = stripTypeScriptTypes(code, { mode: 'strip', sourceUrl: 'source.ts' });
|
||||
console.log(strippedCode);
|
||||
// Prints: const a = 1\n\n//# sourceURL=source.ts;
|
||||
```
|
||||
|
||||
```cjs
|
||||
const { stripTypeScriptTypes } = require('node:module');
|
||||
const code = 'const a: number = 1;';
|
||||
const strippedCode = stripTypeScriptTypes(code, { mode: 'strip', sourceUrl: 'source.ts' });
|
||||
console.log(strippedCode);
|
||||
// Prints: const a = 1\n\n//# sourceURL=source.ts;
|
||||
```
|
||||
|
||||
When `mode` is `'transform'`, the code is transformed to JavaScript:
|
||||
|
||||
```mjs
|
||||
import { stripTypeScriptTypes } from 'node:module';
|
||||
const code = `
|
||||
namespace MathUtil {
|
||||
export const add = (a: number, b: number) => a + b;
|
||||
}`;
|
||||
const strippedCode = stripTypeScriptTypes(code, { mode: 'transform', sourceMap: true });
|
||||
console.log(strippedCode);
|
||||
// Prints:
|
||||
// var MathUtil;
|
||||
// (function(MathUtil) {
|
||||
// MathUtil.add = (a, b)=>a + b;
|
||||
// })(MathUtil || (MathUtil = {}));
|
||||
// # sourceMappingURL=data:application/json;base64, ...
|
||||
```
|
||||
|
||||
```cjs
|
||||
const { stripTypeScriptTypes } = require('node:module');
|
||||
const code = `
|
||||
namespace MathUtil {
|
||||
export const add = (a: number, b: number) => a + b;
|
||||
}`;
|
||||
const strippedCode = stripTypeScriptTypes(code, { mode: 'transform', sourceMap: true });
|
||||
console.log(strippedCode);
|
||||
// Prints:
|
||||
// var MathUtil;
|
||||
// (function(MathUtil) {
|
||||
// MathUtil.add = (a, b)=>a + b;
|
||||
// })(MathUtil || (MathUtil = {}));
|
||||
// # sourceMappingURL=data:application/json;base64, ...
|
||||
```
|
||||
|
||||
### `module.syncBuiltinESMExports()`
|
||||
|
||||
<!-- YAML
|
||||
|
@ -1252,3 +1351,5 @@ returned object contains the following keys:
|
|||
[realm]: https://tc39.es/ecma262/#realm
|
||||
[source map include directives]: https://sourcemaps.info/spec.html#h.lmz475t4mvbx
|
||||
[transferable objects]: worker_threads.md#portpostmessagevalue-transferlist
|
||||
[transform TypeScript features]: typescript.md#typescript-features
|
||||
[type-stripping]: typescript.md#type-stripping
|
||||
|
|
|
@ -14,8 +14,8 @@ const {
|
|||
markBootstrapComplete,
|
||||
} = require('internal/process/pre_execution');
|
||||
const { evalModuleEntryPoint, evalScript } = require('internal/process/execution');
|
||||
const { addBuiltinLibsToObject, stripTypeScriptTypes } = require('internal/modules/helpers');
|
||||
|
||||
const { addBuiltinLibsToObject } = require('internal/modules/helpers');
|
||||
const { stripTypeScriptModuleTypes } = require('internal/modules/typescript');
|
||||
const { getOptionValue } = require('internal/options');
|
||||
|
||||
prepareMainThreadExecution();
|
||||
|
@ -24,7 +24,7 @@ markBootstrapComplete();
|
|||
|
||||
const code = getOptionValue('--eval');
|
||||
const source = getOptionValue('--experimental-strip-types') ?
|
||||
stripTypeScriptTypes(code) :
|
||||
stripTypeScriptModuleTypes(code) :
|
||||
code;
|
||||
|
||||
const print = getOptionValue('--print');
|
||||
|
|
|
@ -151,8 +151,8 @@ const {
|
|||
setHasStartedUserCJSExecution,
|
||||
stripBOM,
|
||||
toRealPath,
|
||||
stripTypeScriptTypes,
|
||||
} = require('internal/modules/helpers');
|
||||
const { stripTypeScriptModuleTypes } = require('internal/modules/typescript');
|
||||
const packageJsonReader = require('internal/modules/package_json_reader');
|
||||
const { getOptionValue, getEmbedderOptions } = require('internal/options');
|
||||
const shouldReportRequiredModules = getLazy(() => process.env.WATCH_REPORT_DEPENDENCIES);
|
||||
|
@ -1357,7 +1357,7 @@ let hasPausedEntry = false;
|
|||
function loadESMFromCJS(mod, filename) {
|
||||
let source = getMaybeCachedSource(mod, filename);
|
||||
if (getOptionValue('--experimental-strip-types') && path.extname(filename) === '.mts') {
|
||||
source = stripTypeScriptTypes(source, filename);
|
||||
source = stripTypeScriptModuleTypes(source, filename);
|
||||
}
|
||||
const cascadedLoader = require('internal/modules/esm/loader').getOrInitializeCascadedLoader();
|
||||
const isMain = mod[kIsMainSymbol];
|
||||
|
@ -1599,7 +1599,7 @@ function getMaybeCachedSource(mod, filename) {
|
|||
|
||||
function loadCTS(module, filename) {
|
||||
const source = getMaybeCachedSource(module, filename);
|
||||
const code = stripTypeScriptTypes(source, filename);
|
||||
const code = stripTypeScriptModuleTypes(source, filename);
|
||||
module._compile(code, filename, 'commonjs');
|
||||
}
|
||||
|
||||
|
@ -1611,7 +1611,7 @@ function loadCTS(module, filename) {
|
|||
function loadTS(module, filename) {
|
||||
// If already analyzed the source, then it will be cached.
|
||||
const source = getMaybeCachedSource(module, filename);
|
||||
const content = stripTypeScriptTypes(source, filename);
|
||||
const content = stripTypeScriptModuleTypes(source, filename);
|
||||
let format;
|
||||
const pkg = packageJsonReader.getNearestParentPackageJSON(filename);
|
||||
// Function require shouldn't be used in ES modules.
|
||||
|
@ -1631,7 +1631,7 @@ function loadTS(module, filename) {
|
|||
if (Module._cache[parentPath]) {
|
||||
let parentSource;
|
||||
try {
|
||||
parentSource = stripTypeScriptTypes(fs.readFileSync(parentPath, 'utf8'), parentPath);
|
||||
parentSource = stripTypeScriptModuleTypes(fs.readFileSync(parentPath, 'utf8'), parentPath);
|
||||
} catch {
|
||||
// Continue regardless of error.
|
||||
}
|
||||
|
|
|
@ -164,9 +164,10 @@ function getFileProtocolModuleFormat(url, context = { __proto__: null }, ignoreE
|
|||
// Since experimental-strip-types depends on detect-module, we always return null
|
||||
// if source is undefined.
|
||||
if (!source) { return null; }
|
||||
const { stripTypeScriptTypes, stringify } = require('internal/modules/helpers');
|
||||
const { stringify } = require('internal/modules/helpers');
|
||||
const { stripTypeScriptModuleTypes } = require('internal/modules/typescript');
|
||||
const stringifiedSource = stringify(source);
|
||||
const parsedSource = stripTypeScriptTypes(stringifiedSource, fileURLToPath(url));
|
||||
const parsedSource = stripTypeScriptModuleTypes(stringifiedSource, fileURLToPath(url));
|
||||
const detectedFormat = detectModuleFormat(parsedSource, url);
|
||||
const format = `${detectedFormat}-typescript`;
|
||||
if (format === 'module-typescript' && foundPackageJson) {
|
||||
|
|
|
@ -31,10 +31,10 @@ const {
|
|||
assertBufferSource,
|
||||
loadBuiltinModule,
|
||||
stringify,
|
||||
stripTypeScriptTypes,
|
||||
stripBOM,
|
||||
urlToFilename,
|
||||
} = require('internal/modules/helpers');
|
||||
const { stripTypeScriptModuleTypes } = require('internal/modules/typescript');
|
||||
const {
|
||||
kIsCachedByESMLoader,
|
||||
Module: CJSModule,
|
||||
|
@ -248,7 +248,7 @@ translators.set('require-commonjs', (url, source, isMain) => {
|
|||
translators.set('require-commonjs-typescript', (url, source, isMain) => {
|
||||
emitExperimentalWarning('Type Stripping');
|
||||
assert(cjsParse);
|
||||
const code = stripTypeScriptTypes(stringify(source), url);
|
||||
const code = stripTypeScriptModuleTypes(stringify(source), url);
|
||||
return createCJSModuleWrap(url, code);
|
||||
});
|
||||
|
||||
|
@ -463,7 +463,7 @@ translators.set('wasm', async function(url, source) {
|
|||
translators.set('commonjs-typescript', function(url, source) {
|
||||
emitExperimentalWarning('Type Stripping');
|
||||
assertBufferSource(source, true, 'load');
|
||||
const code = stripTypeScriptTypes(stringify(source), url);
|
||||
const code = stripTypeScriptModuleTypes(stringify(source), url);
|
||||
debug(`Translating TypeScript ${url}`);
|
||||
return FunctionPrototypeCall(translators.get('commonjs'), this, url, code, false);
|
||||
});
|
||||
|
@ -472,7 +472,7 @@ translators.set('commonjs-typescript', function(url, source) {
|
|||
translators.set('module-typescript', function(url, source) {
|
||||
emitExperimentalWarning('Type Stripping');
|
||||
assertBufferSource(source, true, 'load');
|
||||
const code = stripTypeScriptTypes(stringify(source), url);
|
||||
const code = stripTypeScriptModuleTypes(stringify(source), url);
|
||||
debug(`Translating TypeScript ${url}`);
|
||||
return FunctionPrototypeCall(translators.get('module'), this, url, code, false);
|
||||
});
|
||||
|
|
|
@ -15,8 +15,6 @@ const {
|
|||
const {
|
||||
ERR_INVALID_ARG_TYPE,
|
||||
ERR_INVALID_RETURN_PROPERTY_VALUE,
|
||||
ERR_INVALID_TYPESCRIPT_SYNTAX,
|
||||
ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING,
|
||||
} = require('internal/errors').codes;
|
||||
const { BuiltinModule } = require('internal/bootstrap/realm');
|
||||
|
||||
|
@ -27,9 +25,8 @@ const path = require('path');
|
|||
const { pathToFileURL, fileURLToPath } = require('internal/url');
|
||||
const assert = require('internal/assert');
|
||||
|
||||
const { Buffer } = require('buffer');
|
||||
const { getOptionValue } = require('internal/options');
|
||||
const { assertTypeScript, setOwnProperty, getLazy, isUnderNodeModules } = require('internal/util');
|
||||
const { setOwnProperty, getLazy } = require('internal/util');
|
||||
const { inspect } = require('internal/util/inspect');
|
||||
|
||||
const lazyTmpdir = getLazy(() => require('os').tmpdir());
|
||||
|
@ -314,74 +311,6 @@ function getBuiltinModule(id) {
|
|||
return normalizedId ? require(normalizedId) : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The TypeScript parsing mode, either 'strip-only' or 'transform'.
|
||||
* @type {string}
|
||||
*/
|
||||
const getTypeScriptParsingMode = getLazy(() =>
|
||||
(getOptionValue('--experimental-transform-types') ? 'transform' : 'strip-only'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Load the TypeScript parser.
|
||||
* and returns an object with a `code` property.
|
||||
* @returns {Function} The TypeScript parser function.
|
||||
*/
|
||||
const loadTypeScriptParser = getLazy(() => {
|
||||
assertTypeScript();
|
||||
const amaro = require('internal/deps/amaro/dist/index');
|
||||
return amaro.transformSync;
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} source the source code
|
||||
* @param {object} options the options to pass to the parser
|
||||
* @returns {TransformOutput} an object with a `code` property.
|
||||
*/
|
||||
function parseTypeScript(source, options) {
|
||||
const parse = loadTypeScriptParser();
|
||||
try {
|
||||
return parse(source, options);
|
||||
} catch (error) {
|
||||
throw new ERR_INVALID_TYPESCRIPT_SYNTAX(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} TransformOutput
|
||||
* @property {string} code The compiled code.
|
||||
* @property {string} [map] The source maps (optional).
|
||||
*
|
||||
* Performs type-stripping to TypeScript source code.
|
||||
* @param {string} source TypeScript code to parse.
|
||||
* @param {string} filename The filename of the source code.
|
||||
* @returns {TransformOutput} The stripped TypeScript code.
|
||||
*/
|
||||
function stripTypeScriptTypes(source, filename) {
|
||||
if (isUnderNodeModules(filename)) {
|
||||
throw new ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING(filename);
|
||||
}
|
||||
assert(typeof source === 'string');
|
||||
const options = {
|
||||
__proto__: null,
|
||||
mode: getTypeScriptParsingMode(),
|
||||
sourceMap: getOptionValue('--enable-source-maps'),
|
||||
filename,
|
||||
};
|
||||
const { code, map } = parseTypeScript(source, options);
|
||||
if (map) {
|
||||
// TODO(@marco-ippolito) When Buffer.transcode supports utf8 to
|
||||
// base64 transformation, we should change this line.
|
||||
const base64SourceMap = Buffer.from(map).toString('base64');
|
||||
return `${code}\n\n//# sourceMappingURL=data:application/json;base64,${base64SourceMap}`;
|
||||
}
|
||||
// Source map is not necessary in strip-only mode. However, to map the source
|
||||
// file in debuggers to the original TypeScript source, add a sourceURL magic
|
||||
// comment to hint that it is a generated source.
|
||||
return `${code}\n\n//# sourceURL=${filename}`;
|
||||
}
|
||||
|
||||
/** @type {import('internal/util/types')} */
|
||||
let _TYPES = null;
|
||||
/**
|
||||
|
@ -485,7 +414,6 @@ module.exports = {
|
|||
loadBuiltinModule,
|
||||
makeRequireFunction,
|
||||
normalizeReferrerURL,
|
||||
stripTypeScriptTypes,
|
||||
stringify,
|
||||
stripBOM,
|
||||
toRealPath,
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
'use strict';
|
||||
|
||||
const {
|
||||
validateBoolean,
|
||||
validateOneOf,
|
||||
validateObject,
|
||||
validateString,
|
||||
} = require('internal/validators');
|
||||
const { assertTypeScript,
|
||||
emitExperimentalWarning,
|
||||
getLazy,
|
||||
isUnderNodeModules,
|
||||
kEmptyObject } = require('internal/util');
|
||||
const {
|
||||
ERR_INVALID_TYPESCRIPT_SYNTAX,
|
||||
ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING,
|
||||
} = require('internal/errors').codes;
|
||||
const { getOptionValue } = require('internal/options');
|
||||
const assert = require('internal/assert');
|
||||
|
||||
/**
|
||||
* The TypeScript parsing mode, either 'strip-only' or 'transform'.
|
||||
* @type {string}
|
||||
*/
|
||||
const getTypeScriptParsingMode = getLazy(() =>
|
||||
(getOptionValue('--experimental-transform-types') ? 'transform' : 'strip-only'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Load the TypeScript parser.
|
||||
* and returns an object with a `code` property.
|
||||
* @returns {Function} The TypeScript parser function.
|
||||
*/
|
||||
const loadTypeScriptParser = getLazy(() => {
|
||||
assertTypeScript();
|
||||
const amaro = require('internal/deps/amaro/dist/index');
|
||||
return amaro.transformSync;
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} source the source code
|
||||
* @param {object} options the options to pass to the parser
|
||||
* @returns {TransformOutput} an object with a `code` property.
|
||||
*/
|
||||
function parseTypeScript(source, options) {
|
||||
const parse = loadTypeScriptParser();
|
||||
try {
|
||||
return parse(source, options);
|
||||
} catch (error) {
|
||||
throw new ERR_INVALID_TYPESCRIPT_SYNTAX(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs type-stripping to TypeScript source code.
|
||||
* @param {string} code TypeScript code to parse.
|
||||
* @param {TransformOptions} options The configuration for type stripping.
|
||||
* @returns {string} The stripped TypeScript code.
|
||||
*/
|
||||
function stripTypeScriptTypes(code, options = kEmptyObject) {
|
||||
emitExperimentalWarning('stripTypeScriptTypes');
|
||||
validateString(code, 'code');
|
||||
validateObject(options, 'options');
|
||||
|
||||
const {
|
||||
sourceMap = false,
|
||||
sourceUrl = '',
|
||||
} = options;
|
||||
let { mode = 'strip' } = options;
|
||||
validateOneOf(mode, 'options.mode', ['strip', 'transform']);
|
||||
validateBoolean(sourceMap, 'options.sourceMap');
|
||||
validateString(sourceUrl, 'options.sourceUrl');
|
||||
if (mode === 'strip') {
|
||||
validateOneOf(sourceMap, 'options.sourceMap', [false, undefined]);
|
||||
// Rename mode from 'strip' to 'strip-only'.
|
||||
// The reason is to match `process.features.typescript` which returns `strip`,
|
||||
// but the parser expects `strip-only`.
|
||||
mode = 'strip-only';
|
||||
}
|
||||
|
||||
return processTypeScriptCode(code, {
|
||||
mode,
|
||||
sourceMap,
|
||||
filename: sourceUrl,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes TypeScript code by stripping types or transforming.
|
||||
* Handles source maps if needed.
|
||||
* @param {string} code TypeScript code to process.
|
||||
* @param {object} options The configuration object.
|
||||
* @returns {string} The processed code.
|
||||
*/
|
||||
function processTypeScriptCode(code, options) {
|
||||
const { code: transformedCode, map } = parseTypeScript(code, options);
|
||||
|
||||
if (map) {
|
||||
return addSourceMap(transformedCode, map);
|
||||
}
|
||||
|
||||
if (options.filename) {
|
||||
return `${transformedCode}\n\n//# sourceURL=${options.filename}`;
|
||||
}
|
||||
|
||||
return transformedCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs type-stripping to TypeScript source code internally.
|
||||
* It is used by internal loaders.
|
||||
* @param {string} source TypeScript code to parse.
|
||||
* @param {string} filename The filename of the source code.
|
||||
* @returns {TransformOutput} The stripped TypeScript code.
|
||||
*/
|
||||
function stripTypeScriptModuleTypes(source, filename) {
|
||||
assert(typeof source === 'string');
|
||||
if (isUnderNodeModules(filename)) {
|
||||
throw new ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING(filename);
|
||||
}
|
||||
const options = {
|
||||
mode: getTypeScriptParsingMode(),
|
||||
sourceMap: getOptionValue('--enable-source-maps'),
|
||||
filename,
|
||||
};
|
||||
return processTypeScriptCode(source, options);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} code The compiled code.
|
||||
* @param {string} sourceMap The source map.
|
||||
* @returns {string} The code with the source map attached.
|
||||
*/
|
||||
function addSourceMap(code, sourceMap) {
|
||||
// TODO(@marco-ippolito) When Buffer.transcode supports utf8 to
|
||||
// base64 transformation, we should change this line.
|
||||
const base64SourceMap = internalBinding('buffer').btoa(sourceMap);
|
||||
return `${code}\n\n//# sourceMappingURL=data:application/json;base64,${base64SourceMap}`;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
stripTypeScriptModuleTypes,
|
||||
stripTypeScriptTypes,
|
||||
};
|
|
@ -10,6 +10,7 @@ const {
|
|||
flushCompileCache,
|
||||
getCompileCacheDir,
|
||||
} = require('internal/modules/helpers');
|
||||
const { stripTypeScriptTypes } = require('internal/modules/typescript');
|
||||
|
||||
Module.findSourceMap = findSourceMap;
|
||||
Module.register = register;
|
||||
|
@ -17,6 +18,6 @@ Module.SourceMap = SourceMap;
|
|||
Module.constants = constants;
|
||||
Module.enableCompileCache = enableCompileCache;
|
||||
Module.flushCompileCache = flushCompileCache;
|
||||
|
||||
Module.stripTypeScriptTypes = stripTypeScriptTypes;
|
||||
Module.getCompileCacheDir = getCompileCacheDir;
|
||||
module.exports = Module;
|
||||
|
|
|
@ -104,6 +104,7 @@ expected.beforePreExec = new Set([
|
|||
'NativeModule diagnostics_channel',
|
||||
'Internal Binding wasm_web_api',
|
||||
'NativeModule internal/events/abort_listener',
|
||||
'NativeModule internal/modules/typescript',
|
||||
]);
|
||||
|
||||
expected.atRunTime = new Set([
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
if (!process.config.variables.node_use_amaro) common.skip('Requires Amaro');
|
||||
const assert = require('assert');
|
||||
const vm = require('node:vm');
|
||||
const { stripTypeScriptTypes } = require('node:module');
|
||||
const { test } = require('node:test');
|
||||
|
||||
common.expectWarning(
|
||||
'ExperimentalWarning',
|
||||
'stripTypeScriptTypes is an experimental feature and might change at any time',
|
||||
);
|
||||
|
||||
test('stripTypeScriptTypes', () => {
|
||||
const source = 'const x: number = 1;';
|
||||
const result = stripTypeScriptTypes(source);
|
||||
assert.strictEqual(result, 'const x = 1;');
|
||||
});
|
||||
|
||||
test('stripTypeScriptTypes explicit', () => {
|
||||
const source = 'const x: number = 1;';
|
||||
const result = stripTypeScriptTypes(source, { mode: 'strip' });
|
||||
assert.strictEqual(result, 'const x = 1;');
|
||||
});
|
||||
|
||||
test('stripTypeScriptTypes code is not a string', () => {
|
||||
assert.throws(() => stripTypeScriptTypes({}),
|
||||
{ code: 'ERR_INVALID_ARG_TYPE' });
|
||||
});
|
||||
|
||||
test('stripTypeScriptTypes invalid mode', () => {
|
||||
const source = 'const x: number = 1;';
|
||||
assert.throws(() => stripTypeScriptTypes(source, { mode: 'invalid' }), { code: 'ERR_INVALID_ARG_VALUE' });
|
||||
});
|
||||
|
||||
test('stripTypeScriptTypes sourceMap throws when mode is strip', () => {
|
||||
const source = 'const x: number = 1;';
|
||||
assert.throws(() => stripTypeScriptTypes(source,
|
||||
{ mode: 'strip', sourceMap: true }),
|
||||
{ code: 'ERR_INVALID_ARG_VALUE' });
|
||||
});
|
||||
|
||||
test('stripTypeScriptTypes sourceUrl throws when mode is strip', () => {
|
||||
const source = 'const x: number = 1;';
|
||||
const result = stripTypeScriptTypes(source, { mode: 'strip', sourceUrl: 'foo.ts' });
|
||||
assert.strictEqual(result, 'const x = 1;\n\n//# sourceURL=foo.ts');
|
||||
});
|
||||
|
||||
test('stripTypeScriptTypes source map when mode is transform', () => {
|
||||
const source = `
|
||||
namespace MathUtil {
|
||||
export const add = (a: number, b: number) => a + b;
|
||||
}`;
|
||||
const result = stripTypeScriptTypes(source, { mode: 'transform', sourceMap: true });
|
||||
const script = new vm.Script(result);
|
||||
const sourceMap =
|
||||
{
|
||||
version: 3,
|
||||
sources: [
|
||||
'<anon>',
|
||||
],
|
||||
sourcesContent: [
|
||||
'\n namespace MathUtil {\n export const add = (a: number, b: number) => a + b;\n }',
|
||||
],
|
||||
names: [],
|
||||
mappings: ';UACY;aACK,MAAM,CAAC,GAAW,IAAc,IAAI;AACnD,GAFU,aAAA'
|
||||
};
|
||||
assert(script.sourceMapURL, `sourceMappingURL=data:application/json;base64,${JSON.stringify(sourceMap)}`);
|
||||
});
|
||||
|
||||
test('stripTypeScriptTypes source map when mode is transform and sourceUrl', () => {
|
||||
const source = `
|
||||
namespace MathUtil {
|
||||
export const add = (a: number, b: number) => a + b;
|
||||
}`;
|
||||
const result = stripTypeScriptTypes(source, { mode: 'transform', sourceMap: true, sourceUrl: 'test.ts' });
|
||||
const script = new vm.Script(result);
|
||||
const sourceMap =
|
||||
{
|
||||
version: 3,
|
||||
sources: [
|
||||
'test.ts',
|
||||
],
|
||||
sourcesContent: [
|
||||
'\n namespace MathUtil {\n export const add = (a: number, b: number) => a + b;\n }',
|
||||
],
|
||||
names: [],
|
||||
mappings: ';UACY;aACK,MAAM,CAAC,GAAW,IAAc,IAAI;AACnD,GAFU,aAAA'
|
||||
};
|
||||
assert(script.sourceMapURL, `sourceMappingURL=data:application/json;base64,${JSON.stringify(sourceMap)}`);
|
||||
});
|
Loading…
Reference in New Issue