-
Notifications
You must be signed in to change notification settings - Fork 30.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
lib: add parser.stripTypeScriptTypes
- Loading branch information
1 parent
8af1382
commit 76ff249
Showing
8 changed files
with
229 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Path | ||
|
||
<!--introduced_in=REPLACEME--> | ||
|
||
> Stability: 1.0 - Early Development | ||
<!-- source_link=lib/parser.js --> | ||
|
||
The `node:parser` module provides utilities for working with source code. It can be accessed using: | ||
|
||
```js | ||
const parser = require('node:parser'); | ||
``` | ||
|
||
## `parser.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-only'`. Possible values are: | ||
* `'strip-only'` 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. | ||
* `filename` {string} Only when `mode` is `'transform'`, specifies the filename used in the source map. | ||
* Returns: {string} The code with type annotations stripped. | ||
`parser.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-only'`, source maps are not generated, because locations are preserved. | ||
If `sourceMap` or `filename` is provided, when mode is `'strip-only'`, an error will be thrown. | ||
|
||
```js | ||
const parser = require('node:parser'); | ||
const code = `const a: number = 1;`; | ||
const strippedCode = parser.stripTypeScriptTypes(code); | ||
console.log(strippedCode); | ||
// Prints: const a = 1; | ||
``` | ||
|
||
When `mode` is `'transform'`, the code is transformed to JavaScript: | ||
|
||
```js | ||
const parser = require('node:parser'); | ||
const code = ` | ||
namespace MathUtil { | ||
export const add = (a: number, b: number) => a + b; | ||
}`; | ||
const strippedCode = parser.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, ... | ||
``` | ||
|
||
[transform TypeScript features]: typescript.md#typescript-features | ||
[type-stripping]: typescript.md#type-stripping |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
'use strict'; | ||
|
||
const { | ||
validateBoolean, | ||
validateOneOf, | ||
validateObject, | ||
validateString, | ||
} = require('internal/validators'); | ||
const { | ||
emitExperimentalWarning, | ||
kEmptyObject, | ||
} = require('internal/util'); | ||
const { parseTypeScript } = require('internal/modules/helpers'); | ||
const { Buffer } = require('buffer'); | ||
|
||
function stripTypeScriptTypes(code, options = kEmptyObject) { | ||
emitExperimentalWarning('parser.stripTypeScriptTypes'); | ||
validateObject(options, 'options'); | ||
const { mode = 'strip-only', sourceMap = false, filename = '' } = options; | ||
validateOneOf(mode, 'options.mode', ['strip-only', 'transform']); | ||
if (mode === 'strip-only') { | ||
validateOneOf(sourceMap, 'options.sourceMap', [false, undefined]); | ||
validateOneOf(filename, 'options.filename', ['', undefined]); | ||
} | ||
validateBoolean(sourceMap, 'options.sourceMap'); | ||
validateString(filename, 'options.filename'); | ||
|
||
const transformOptions = { | ||
__proto__: null, | ||
mode, | ||
sourceMap, | ||
filename, | ||
}; | ||
|
||
const { code: transformed, map } = parseTypeScript(code, transformOptions); | ||
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 `${transformed}\n\n//# sourceMappingURL=data:application/json;base64,${base64SourceMap}`; | ||
} | ||
return transformed; | ||
} | ||
|
||
module.exports = { | ||
stripTypeScriptTypes, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
'use strict'; | ||
|
||
const common = require('../common'); | ||
const assert = require('node:assert'); | ||
const parser = require('node:parser'); | ||
const vm = require('node:vm'); | ||
const { test } = require('node:test'); | ||
|
||
common.expectWarning( | ||
'ExperimentalWarning', | ||
'parser.stripTypeScriptTypes is an experimental feature and might change at any time', | ||
); | ||
|
||
test('parser.stripTypeScriptTypes', () => { | ||
const source = 'const x: number = 1;'; | ||
const result = parser.stripTypeScriptTypes(source); | ||
assert.strictEqual(result, 'const x = 1;'); | ||
}); | ||
|
||
test('parser.stripTypeScriptTypes explicit', () => { | ||
const source = 'const x: number = 1;'; | ||
const result = parser.stripTypeScriptTypes(source, { mode: 'strip-only' }); | ||
assert.strictEqual(result, 'const x = 1;'); | ||
}); | ||
|
||
test('parser.stripTypeScriptTypes invalid mode', () => { | ||
const source = 'const x: number = 1;'; | ||
assert.throws(() => parser.stripTypeScriptTypes(source, { mode: 'invalid' }), { code: 'ERR_INVALID_ARG_VALUE' }); | ||
}); | ||
|
||
test('parser.stripTypeScriptTypes sourceMap throws when mode is strip-only', () => { | ||
const source = 'const x: number = 1;'; | ||
assert.throws(() => parser.stripTypeScriptTypes(source, | ||
{ mode: 'strip-only', sourceMap: true }), | ||
{ code: 'ERR_INVALID_ARG_VALUE' }); | ||
}); | ||
|
||
test('parser.stripTypeScriptTypes filename throws when mode is strip-only', () => { | ||
const source = 'const x: number = 1;'; | ||
assert.throws(() => parser.stripTypeScriptTypes(source, | ||
{ mode: 'strip-only', filename: 'foo.ts' }), | ||
{ code: 'ERR_INVALID_ARG_VALUE' }); | ||
}); | ||
|
||
test('parser.stripTypeScriptTypes source map when mode is transform', () => { | ||
const source = ` | ||
namespace MathUtil { | ||
export const add = (a: number, b: number) => a + b; | ||
}`; | ||
const result = parser.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('parser.stripTypeScriptTypes source map when mode is transform and filename', () => { | ||
const source = ` | ||
namespace MathUtil { | ||
export const add = (a: number, b: number) => a + b; | ||
}`; | ||
const result = parser.stripTypeScriptTypes(source, { mode: 'transform', sourceMap: true, filename: '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)}`); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters