ts-const-value-transformer 0.7.1 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +3 -1
- package/dist/createPortalTransformer.d.mts +2 -0
- package/dist/createPortalTransformer.mjs +21 -10
- package/dist/loader.mjs +3 -0
- package/dist/transform.mjs +22 -70
- package/dist/version.d.mts +1 -1
- package/dist/version.mjs +1 -1
- package/package.json +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.8.1
|
|
4
|
+
|
|
5
|
+
- Fix to parenthesize expression with multi-line
|
|
6
|
+
- Reduce mappings to only have position changings
|
|
7
|
+
- Minor changes in development environment
|
|
8
|
+
|
|
9
|
+
## v0.8.0
|
|
10
|
+
|
|
11
|
+
- Add `cacheResult` option (enable by default but disable by default for webpack loader)
|
|
12
|
+
- Fix for treating `as` expression (don't see parent expression)
|
|
13
|
+
- Fix some codes
|
|
14
|
+
|
|
3
15
|
## v0.7.1
|
|
4
16
|
|
|
5
17
|
- Fix to wrap import() with eval to prevent from static analysis
|
package/README.md
CHANGED
|
@@ -279,7 +279,7 @@ See [Transform options](#transform-options).
|
|
|
279
279
|
Creates 'portal transformer', which can be used the transformer easily from the code which does not use TypeScript Compiler API.
|
|
280
280
|
The return object has `transform` method with signature: `(content: string, fileName: string, sourceMap?: string | RawSourceMap | null, options?: TransformOptions) => [newSource: string, newSourceMap: RawSourceMap | undefined]`. You can call to transform TypeScript source code. (Note that this API does not transpile to JavaScript; the output code is still TypeScript code.)
|
|
281
281
|
|
|
282
|
-
`CreatePortalTransformerOptions` has a following signature. Also, `
|
|
282
|
+
`CreatePortalTransformerOptions` has a following signature. Also, `TransformOptions` fields, including `ignoreFiles`, can be used.
|
|
283
283
|
|
|
284
284
|
```ts
|
|
285
285
|
interface CreatePortalTransformerOptions extends TransformOptions {
|
|
@@ -297,6 +297,8 @@ interface CreatePortalTransformerOptions extends TransformOptions {
|
|
|
297
297
|
recreateProgramOnTransformCount?: number;
|
|
298
298
|
/** Specifies to cache base (original) source code for check if the input is changed. Default is false. */
|
|
299
299
|
cacheBaseSource?: boolean;
|
|
300
|
+
/** Specifies to cache result source code. Default is true (false for webpack loader). If the latter process has cache system, specifies false to reduce memory usage. */
|
|
301
|
+
cacheResult?: boolean;
|
|
300
302
|
}
|
|
301
303
|
```
|
|
302
304
|
|
|
@@ -16,6 +16,8 @@ export interface CreatePortalTransformerOptions extends TransformOptions {
|
|
|
16
16
|
recreateProgramOnTransformCount?: number;
|
|
17
17
|
/** Specifies to cache base (original) source code for check if the input is changed. Default is false. */
|
|
18
18
|
cacheBaseSource?: boolean;
|
|
19
|
+
/** Specifies to cache result source code. Default is true (false for webpack loader). If the latter process has cache system, specifies false to reduce memory usage. */
|
|
20
|
+
cacheResult?: boolean;
|
|
19
21
|
}
|
|
20
22
|
export type PortalTransformerResult = [
|
|
21
23
|
newSource: string | null,
|
|
@@ -21,6 +21,7 @@ function createPortalTransformerImpl(options, ts) {
|
|
|
21
21
|
const cwd = options.cwd ?? process.cwd();
|
|
22
22
|
const recreateProgramOnTransformCount = options.recreateProgramOnTransformCount ?? 0;
|
|
23
23
|
const cacheBaseSource = options.cacheBaseSource ?? false;
|
|
24
|
+
const cacheResult = options.cacheResult ?? true;
|
|
24
25
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
25
26
|
const foundConfigPath = ts.findConfigFile(cwd, ts.sys.fileExists, project);
|
|
26
27
|
if (foundConfigPath == null) {
|
|
@@ -72,11 +73,13 @@ function createPortalTransformerImpl(options, ts) {
|
|
|
72
73
|
recreateProgram,
|
|
73
74
|
transform: (content, fileName, sourceMap, individualOptions) => {
|
|
74
75
|
const individualOptionsJson = optionsToString(individualOptions ?? {});
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
(
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
if (cacheResult) {
|
|
77
|
+
const cachedData = cache.get(fileName);
|
|
78
|
+
if (cachedData &&
|
|
79
|
+
(!cacheBaseSource || cachedData.content === content) &&
|
|
80
|
+
cachedData.optJson === individualOptionsJson) {
|
|
81
|
+
return cachedData.result;
|
|
82
|
+
}
|
|
80
83
|
}
|
|
81
84
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
82
85
|
const rawSourceMap = typeof sourceMap === 'string'
|
|
@@ -115,11 +118,19 @@ function createPortalTransformerImpl(options, ts) {
|
|
|
115
118
|
else {
|
|
116
119
|
result = printSourceWithMap(transformedSource, fileName, rawSourceMap, ts);
|
|
117
120
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
result
|
|
122
|
-
|
|
121
|
+
if (cacheResult) {
|
|
122
|
+
// This forces to concatenate strings into flatten one, to reduce object trees for ConsString
|
|
123
|
+
void (result[0] | 0);
|
|
124
|
+
const json = result[1];
|
|
125
|
+
if (json) {
|
|
126
|
+
void (json.mappings | 0);
|
|
127
|
+
}
|
|
128
|
+
cache.set(fileName, {
|
|
129
|
+
content: cacheBaseSource ? content : '',
|
|
130
|
+
optJson: individualOptionsJson,
|
|
131
|
+
result,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
123
134
|
return result;
|
|
124
135
|
},
|
|
125
136
|
};
|
package/dist/loader.mjs
CHANGED
|
@@ -9,11 +9,14 @@ const loader = function (content, sourceMap) {
|
|
|
9
9
|
try {
|
|
10
10
|
const options = this.getOptions() || {};
|
|
11
11
|
const project = options.project ?? 'tsconfig.json';
|
|
12
|
+
// Use webpack's cache system by default
|
|
13
|
+
const cacheResult = options.cacheResult ?? false;
|
|
12
14
|
let transformer = transformerMap.get(project);
|
|
13
15
|
if (!transformer) {
|
|
14
16
|
transformer = await createPortalTransformer({
|
|
15
17
|
cwd: path.dirname(this.resourcePath),
|
|
16
18
|
...options,
|
|
19
|
+
cacheResult,
|
|
17
20
|
});
|
|
18
21
|
transformerMap.set(project, transformer);
|
|
19
22
|
}
|
package/dist/transform.mjs
CHANGED
|
@@ -41,11 +41,11 @@ export function getIgnoreFilesFunction(ignoreFiles) {
|
|
|
41
41
|
////////////////////////////////////////////////////////////////////////////////
|
|
42
42
|
export function transformSource(sourceFile, program, context, options) {
|
|
43
43
|
const requiredOptions = assignDefaultValues(options);
|
|
44
|
-
return requiredOptions.ts.visitEachChild(sourceFile, (node) => visitNodeChildren(node, sourceFile, sourceFile, program, requiredOptions), context);
|
|
44
|
+
return requiredOptions.ts.visitEachChild(sourceFile, (node) => visitNodeChildren(node, sourceFile, sourceFile, program, requiredOptions, context), context);
|
|
45
45
|
}
|
|
46
|
-
function visitNodeChildren(node, parent, sourceFile, program, options) {
|
|
46
|
+
function visitNodeChildren(node, parent, sourceFile, program, options, context) {
|
|
47
47
|
const ts = options.ts;
|
|
48
|
-
const newNode = visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, options);
|
|
48
|
+
const newNode = visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, options, context);
|
|
49
49
|
if (newNode[SYMBOL_ORIGINAL_NODE_DATA]) {
|
|
50
50
|
return newNode;
|
|
51
51
|
}
|
|
@@ -57,9 +57,9 @@ function visitNodeChildren(node, parent, sourceFile, program, options) {
|
|
|
57
57
|
ts.isTypeOnlyExportDeclaration(newNode)) {
|
|
58
58
|
return newNode;
|
|
59
59
|
}
|
|
60
|
-
return ts.visitEachChild(newNode, (node) => visitNodeChildren(node, newNode, sourceFile, program, options),
|
|
60
|
+
return ts.visitEachChild(newNode, (node) => visitNodeChildren(node, newNode, sourceFile, program, options, context), context);
|
|
61
61
|
}
|
|
62
|
-
function visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, options) {
|
|
62
|
+
function visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, options, context) {
|
|
63
63
|
const ts = options.ts;
|
|
64
64
|
if (ts.isCallLikeExpression(node)) {
|
|
65
65
|
if (!ts.isExpression(node) ||
|
|
@@ -108,8 +108,7 @@ function visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, options)
|
|
|
108
108
|
isExternalReference(node, program, options.externalNames, ts)) {
|
|
109
109
|
return node;
|
|
110
110
|
}
|
|
111
|
-
if (!options.unsafeHoistAsExpresion &&
|
|
112
|
-
(hasAsExpression(node, ts) || hasParentAsExpression(parent, ts))) {
|
|
111
|
+
if (!options.unsafeHoistAsExpresion && hasAsExpression(node, ts, context)) {
|
|
113
112
|
return node;
|
|
114
113
|
}
|
|
115
114
|
if (!options.unsafeHoistWritableValues) {
|
|
@@ -175,10 +174,17 @@ function visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, options)
|
|
|
175
174
|
else {
|
|
176
175
|
return node;
|
|
177
176
|
}
|
|
178
|
-
const
|
|
177
|
+
const originalSource = node.getText(sourceFile);
|
|
178
|
+
const comment = ` ${originalSource.replace(/\/\*/g, ' *').replace(/\*\//g, '* ')} `;
|
|
179
|
+
let result = ts.addSyntheticTrailingComment(newNode, ts.SyntaxKind.MultiLineCommentTrivia, comment);
|
|
180
|
+
newSource = `${newSource} /*${comment}*/`;
|
|
181
|
+
if (/[\r\n]/m.test(originalSource)) {
|
|
182
|
+
result = ts.factory.createParenthesizedExpression(result);
|
|
183
|
+
newSource = `(${newSource})`;
|
|
184
|
+
}
|
|
179
185
|
ts.setTextRange(result, node);
|
|
180
186
|
result[SYMBOL_ORIGINAL_NODE_DATA] = [
|
|
181
|
-
|
|
187
|
+
originalSource,
|
|
182
188
|
newSource,
|
|
183
189
|
node.pos,
|
|
184
190
|
node.end,
|
|
@@ -252,10 +258,7 @@ function isExternalReference(node, program, externalNames, tsInstance) {
|
|
|
252
258
|
}
|
|
253
259
|
return false;
|
|
254
260
|
}
|
|
255
|
-
function
|
|
256
|
-
return node.type.getText() === 'const';
|
|
257
|
-
}
|
|
258
|
-
function hasAsExpression(node, tsInstance) {
|
|
261
|
+
function hasAsExpression(node, tsInstance, context) {
|
|
259
262
|
const ts = tsInstance;
|
|
260
263
|
// including 'as const'
|
|
261
264
|
if (ts.isAsExpression(node)) {
|
|
@@ -264,29 +267,12 @@ function hasAsExpression(node, tsInstance) {
|
|
|
264
267
|
let found = false;
|
|
265
268
|
ts.visitEachChild(node, (node) => {
|
|
266
269
|
if (!found) {
|
|
267
|
-
found = hasAsExpression(node, ts);
|
|
270
|
+
found = hasAsExpression(node, ts, context);
|
|
268
271
|
}
|
|
269
272
|
return node;
|
|
270
|
-
},
|
|
273
|
+
}, context);
|
|
271
274
|
return found;
|
|
272
275
|
}
|
|
273
|
-
function hasParentAsExpression(node, tsInstance) {
|
|
274
|
-
const ts = tsInstance;
|
|
275
|
-
if (node == null) {
|
|
276
|
-
return false;
|
|
277
|
-
}
|
|
278
|
-
// excluding 'as const'
|
|
279
|
-
if (ts.isAsExpression(node) && !isAsConstExpression(node)) {
|
|
280
|
-
return true;
|
|
281
|
-
}
|
|
282
|
-
if (ts.isPropertyAccessExpression(node) ||
|
|
283
|
-
ts.isElementAccessExpression(node)) {
|
|
284
|
-
if (hasAsExpression(node.expression, ts)) {
|
|
285
|
-
return true;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
return hasParentAsExpression(node.parent, ts);
|
|
289
|
-
}
|
|
290
276
|
function hasPureAnnotation(node, sourceFile, tsInstance) {
|
|
291
277
|
const ts = tsInstance;
|
|
292
278
|
const fullText = node.getFullText(sourceFile);
|
|
@@ -454,24 +440,12 @@ function positionToLineAndColumn(sourceFile, pos, generatedDiff) {
|
|
|
454
440
|
function printSourceImpl(tsInstance, sourceFile, originalSourceName, mapGenerator) {
|
|
455
441
|
const ts = tsInstance ?? tsNamespace;
|
|
456
442
|
const r = printNode(ts, sourceFile.getFullText(), sourceFile, sourceFile, { pos: 0, diff: 0, lastLine: 0 }, originalSourceName, mapGenerator);
|
|
457
|
-
|
|
458
|
-
void (r | 0);
|
|
459
|
-
const json = mapGenerator?.toJSON();
|
|
460
|
-
if (json) {
|
|
461
|
-
void (json.mappings | 0);
|
|
462
|
-
}
|
|
463
|
-
return [r, json];
|
|
443
|
+
return [r, mapGenerator?.toJSON()];
|
|
464
444
|
}
|
|
465
445
|
function printNode(tsInstance, baseSource, sourceFile, node, posContext, originalSourceName, mapGenerator) {
|
|
466
446
|
const originalNodeData = node[SYMBOL_ORIGINAL_NODE_DATA];
|
|
467
447
|
if (originalNodeData) {
|
|
468
|
-
|
|
469
|
-
const comments = tsInstance.getSyntheticTrailingComments(node);
|
|
470
|
-
if (comments) {
|
|
471
|
-
for (const comment of comments) {
|
|
472
|
-
result += ` /*${comment.text}*/`;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
448
|
+
const result = originalNodeData[1];
|
|
475
449
|
const old = originalNodeData[0];
|
|
476
450
|
const oldFull = baseSource.substring(originalNodeData[2], originalNodeData[3]);
|
|
477
451
|
const i = oldFull.lastIndexOf(old);
|
|
@@ -479,22 +453,12 @@ function printNode(tsInstance, baseSource, sourceFile, node, posContext, origina
|
|
|
479
453
|
const newText = i < 0
|
|
480
454
|
? result
|
|
481
455
|
: oldFull.substring(0, i) + result + oldFull.substring(i + old.length);
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
addMappingForCurrent();
|
|
485
|
-
}
|
|
486
|
-
posContext.pos = node.pos;
|
|
487
|
-
if (leadingUnchanged > 0) {
|
|
488
|
-
addMappingForCurrent();
|
|
489
|
-
}
|
|
490
|
-
posContext.pos = node.pos + leadingUnchanged;
|
|
491
|
-
addMappingForCurrent(old);
|
|
492
|
-
}
|
|
456
|
+
posContext.pos = node.pos + leadingUnchanged;
|
|
457
|
+
addMappingForCurrent(old);
|
|
493
458
|
posContext.diff += result.length - old.length;
|
|
494
459
|
posContext.pos += old.length;
|
|
495
460
|
addMappingForCurrent();
|
|
496
461
|
posContext.pos = node.end;
|
|
497
|
-
addMappingForCurrent();
|
|
498
462
|
return newText;
|
|
499
463
|
}
|
|
500
464
|
let output = '';
|
|
@@ -506,14 +470,12 @@ function printNode(tsInstance, baseSource, sourceFile, node, posContext, origina
|
|
|
506
470
|
if (child.pos > node.pos) {
|
|
507
471
|
const text = baseSource.substring(node.pos, child.pos);
|
|
508
472
|
output += text;
|
|
509
|
-
addMappingForCurrent();
|
|
510
473
|
posContext.pos = child.pos;
|
|
511
474
|
}
|
|
512
475
|
}
|
|
513
476
|
else if (child.pos > lastChildPos) {
|
|
514
477
|
const text = baseSource.substring(lastChildPos, child.pos);
|
|
515
478
|
output += text;
|
|
516
|
-
addMappingForCurrent();
|
|
517
479
|
posContext.pos = child.pos;
|
|
518
480
|
}
|
|
519
481
|
output += printNode(tsInstance, baseSource, sourceFile, child, posContext, originalSourceName, mapGenerator);
|
|
@@ -522,29 +484,19 @@ function printNode(tsInstance, baseSource, sourceFile, node, posContext, origina
|
|
|
522
484
|
}, void 0);
|
|
523
485
|
if (!headPrinted) {
|
|
524
486
|
output = baseSource.substring(node.pos, node.end);
|
|
525
|
-
addMappingForCurrent();
|
|
526
487
|
posContext.pos = node.end;
|
|
527
488
|
}
|
|
528
489
|
else if (lastChildPos < node.end) {
|
|
529
490
|
const text = baseSource.substring(lastChildPos, node.end);
|
|
530
491
|
output += text;
|
|
531
|
-
addMappingForCurrent();
|
|
532
492
|
posContext.pos = node.end;
|
|
533
493
|
}
|
|
534
|
-
addMappingForCurrent();
|
|
535
494
|
return output;
|
|
536
495
|
function addMappingForCurrent(name) {
|
|
537
496
|
const original = positionToLineAndColumn(sourceFile, posContext.pos, 0);
|
|
538
497
|
if (original.line !== posContext.lastLine) {
|
|
539
498
|
posContext.diff = 0;
|
|
540
499
|
posContext.lastLine = original.line;
|
|
541
|
-
if (mapGenerator && original.column > 0) {
|
|
542
|
-
mapGenerator.addMapping({
|
|
543
|
-
original: { line: original.line, column: 0 },
|
|
544
|
-
generated: { line: original.line, column: 0 },
|
|
545
|
-
source: originalSourceName,
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
500
|
}
|
|
549
501
|
if (mapGenerator) {
|
|
550
502
|
mapGenerator.addMapping({
|
package/dist/version.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "0.
|
|
1
|
+
declare const _default: "0.8.1";
|
|
2
2
|
export default _default;
|
package/dist/version.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '0.
|
|
1
|
+
export default '0.8.1';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-const-value-transformer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=20.19.3"
|
|
6
6
|
},
|
|
@@ -90,10 +90,13 @@
|
|
|
90
90
|
"version": "node ./tools/updateVersion.mjs ./src/main/version.mts && git add -A ./src/main/version.mts"
|
|
91
91
|
},
|
|
92
92
|
"devDependencies": {
|
|
93
|
+
"@babel/preset-typescript": "^7.28.5",
|
|
94
|
+
"@swc/core": "^1.15.10",
|
|
93
95
|
"@types/jest": "^30.0.0",
|
|
94
96
|
"@types/node": "~20.19.22",
|
|
95
97
|
"@typescript-eslint/eslint-plugin": "^8.48.0",
|
|
96
98
|
"@typescript-eslint/parser": "^8.48.0",
|
|
99
|
+
"babel-loader": "^10.0.0",
|
|
97
100
|
"eslint": "^9.39.1",
|
|
98
101
|
"eslint-config-prettier": "^10.1.8",
|
|
99
102
|
"eslint-plugin-import-x": "^4.16.1",
|
|
@@ -103,6 +106,7 @@
|
|
|
103
106
|
"memfs": "^4.51.0",
|
|
104
107
|
"neostandard": "^0.12.2",
|
|
105
108
|
"prettier": "^3.6.2",
|
|
109
|
+
"swc-loader": "^0.2.7",
|
|
106
110
|
"ts-jest": "^29.4.5",
|
|
107
111
|
"ts-loader": "^9.5.4",
|
|
108
112
|
"ts-patch": "^3.3.0",
|