ts-const-value-transformer 0.7.0 → 0.8.0

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 CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.8.0
4
+
5
+ - Add `cacheResult` option (enable by default but disable by default for webpack loader)
6
+ - Fix for treating `as` expression (don't see parent expression)
7
+ - Fix some codes
8
+
9
+ ## v0.7.1
10
+
11
+ - Fix to wrap import() with eval to prevent from static analysis
12
+
3
13
  ## v0.7.0
4
14
 
5
15
  - Fix for printing 'minus numeric value' and 'void 0', and remove using `ts.createPrinter`
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, `ignoreFiles` of `TransformOptions` can be used.
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
- const cachedData = cache.get(fileName);
76
- if (cachedData &&
77
- (!cacheBaseSource || cachedData.content === content) &&
78
- cachedData.optJson === individualOptionsJson) {
79
- return cachedData.result;
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
- cache.set(fileName, {
119
- content: cacheBaseSource ? content : '',
120
- optJson: individualOptionsJson,
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
  };
@@ -133,7 +144,9 @@ export default async function createPortalTransformer(options = {}) {
133
144
  let ts;
134
145
  if (options.typescript != null) {
135
146
  if (typeof options.typescript === 'string') {
136
- ts = (await import(options.typescript));
147
+ // Use eval to avoid webpack warnings
148
+ // eslint-disable-next-line no-eval
149
+ ts = (await eval('import(options.typescript)'));
137
150
  }
138
151
  else {
139
152
  ts = options.typescript;
package/dist/loader.mjs CHANGED
@@ -1,19 +1,22 @@
1
1
  import * as path from 'path';
2
- import { createPortalTransformerSync, } from './createPortalTransformer.mjs';
2
+ import createPortalTransformer, {} from './createPortalTransformer.mjs';
3
3
  const transformerMap = new Map();
4
4
  const loader = function (content, sourceMap) {
5
5
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions, @typescript-eslint/strict-boolean-expressions
6
6
  this.cacheable && this.cacheable();
7
7
  this.async();
8
- void Promise.resolve().then(() => {
8
+ void (async () => {
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
- transformer = createPortalTransformerSync({
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
  }
@@ -23,6 +26,6 @@ const loader = function (content, sourceMap) {
23
26
  catch (e) {
24
27
  this.callback(e);
25
28
  }
26
- });
29
+ })();
27
30
  };
28
31
  export default loader;
@@ -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), void 0);
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) {
@@ -252,10 +251,7 @@ function isExternalReference(node, program, externalNames, tsInstance) {
252
251
  }
253
252
  return false;
254
253
  }
255
- function isAsConstExpression(node) {
256
- return node.type.getText() === 'const';
257
- }
258
- function hasAsExpression(node, tsInstance) {
254
+ function hasAsExpression(node, tsInstance, context) {
259
255
  const ts = tsInstance;
260
256
  // including 'as const'
261
257
  if (ts.isAsExpression(node)) {
@@ -264,29 +260,12 @@ function hasAsExpression(node, tsInstance) {
264
260
  let found = false;
265
261
  ts.visitEachChild(node, (node) => {
266
262
  if (!found) {
267
- found = hasAsExpression(node, ts);
263
+ found = hasAsExpression(node, ts, context);
268
264
  }
269
265
  return node;
270
- }, void 0);
266
+ }, context);
271
267
  return found;
272
268
  }
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
269
  function hasPureAnnotation(node, sourceFile, tsInstance) {
291
270
  const ts = tsInstance;
292
271
  const fullText = node.getFullText(sourceFile);
@@ -454,13 +433,7 @@ function positionToLineAndColumn(sourceFile, pos, generatedDiff) {
454
433
  function printSourceImpl(tsInstance, sourceFile, originalSourceName, mapGenerator) {
455
434
  const ts = tsInstance ?? tsNamespace;
456
435
  const r = printNode(ts, sourceFile.getFullText(), sourceFile, sourceFile, { pos: 0, diff: 0, lastLine: 0 }, originalSourceName, mapGenerator);
457
- // This forces to concatenate strings into flatten one to reduce object trees for ConsString
458
- void (r | 0);
459
- const json = mapGenerator?.toJSON();
460
- if (json) {
461
- void (json.mappings | 0);
462
- }
463
- return [r, json];
436
+ return [r, mapGenerator?.toJSON()];
464
437
  }
465
438
  function printNode(tsInstance, baseSource, sourceFile, node, posContext, originalSourceName, mapGenerator) {
466
439
  const originalNodeData = node[SYMBOL_ORIGINAL_NODE_DATA];
@@ -1,2 +1,2 @@
1
- declare const _default: "0.7.0";
1
+ declare const _default: "0.8.0";
2
2
  export default _default;
package/dist/version.mjs CHANGED
@@ -1 +1 @@
1
- export default '0.7.0';
1
+ export default '0.8.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-const-value-transformer",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "engines": {
5
5
  "node": ">=20.19.3"
6
6
  },