ts-const-value-transformer 0.5.0 → 0.6.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,19 @@
1
1
  # Changelog
2
2
 
3
+ ## v0.6.0
4
+
5
+ - Remove skipping satisfies expression
6
+ - Accept `undefined` for `context` and remove dependencies for `context`
7
+ - Fix referring `ts` instance and add `ts` parameter for printSource
8
+ - Add cache to createPortalTransformer
9
+ - Add `recreateProgramOnTransformCount` option for PortalTransformer
10
+ - Fix to use `createPortalTransformerSync` for webpack loader
11
+ - Search tsconfig before loading
12
+
13
+ ## v0.5.1
14
+
15
+ - Fix missing for handling `ignoreFiles` for `createTransformer` (used from ts-loader, etc.)
16
+
3
17
  ## v0.5.0
4
18
 
5
19
  - Add `useUndefinedSymbolForUndefinedValue` and `hoistUndefinedSymbol` options
package/README.md CHANGED
@@ -264,6 +264,8 @@ Prints (generates) source code from `SourceFile`, along with raw source-map data
264
264
 
265
265
  Transforms the source file with TypeScript project. You don't need to call this function directly; use `createTransformer` or `createPortalTransformer` instead.
266
266
 
267
+ Note that `ignoreFiles` of `options` will be ignored for this function.
268
+
267
269
  #### version: string
268
270
 
269
271
  The version string of this package.
@@ -277,7 +279,24 @@ See [Transform options](#transform-options).
277
279
  Creates 'portal transformer', which can be used the transformer easily from the code which does not use TypeScript Compiler API.
278
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.)
279
281
 
280
- `CreatePortalTransformerOptions` has three optional options: `project` (path to tsconfig.json), `typescript` (package path to `typescript` or `typescript` namespace object), and `cwd` (current directory for file search). Also, `ignoreFiles` can be used.
282
+ `CreatePortalTransformerOptions` has a following signature. Also, `ignoreFiles` of `TransformOptions` can be used.
283
+
284
+ ```ts
285
+ interface CreatePortalTransformerOptions extends TransformOptions {
286
+ /** Path to tsconfig.json. If omitted, `tsconfig.json` will be used. */
287
+ project?: string;
288
+ /** Package path to `typescript` or `typescript` namespace object. */
289
+ typescript?: string | typeof tsNamespace;
290
+ /** The current directory for file search. Also affects to `project` option. */
291
+ cwd?: string;
292
+ /**
293
+ * Speficies the count. When the transformation count reaches this value, `program` instance will be recreated (and count will be reset).
294
+ * This is useful if the project is big and out-of-memory occurs during transformation, but the process may be slower.
295
+ * If 0 or `undefined`, recreation will not be performed.
296
+ */
297
+ recreateProgramOnTransformCount?: number;
298
+ }
299
+ ```
281
300
 
282
301
  If `Promise` cannot be used for some reason, use `createPortalTransformerSync` instead.
283
302
 
@@ -2,15 +2,28 @@ import type { RawSourceMap } from 'source-map';
2
2
  import type * as tsNamespace from 'typescript';
3
3
  import { type TransformOptions } from './transform.mjs';
4
4
  export interface CreatePortalTransformerOptions extends TransformOptions {
5
+ /** Path to tsconfig.json. If omitted, `tsconfig.json` will be used. */
5
6
  project?: string;
7
+ /** Package path to `typescript` or `typescript` namespace object. */
6
8
  typescript?: string | typeof tsNamespace;
9
+ /** The current directory for file search. Also affects to `project` option. */
7
10
  cwd?: string;
11
+ /**
12
+ * Speficies the count. When the transformation count reaches this value, `program` instance will be recreated (and count will be reset).
13
+ * This is useful if the project is big and out-of-memory occurs during transformation, but the process may be slower.
14
+ * If 0 or `undefined`, recreation will not be performed.
15
+ */
16
+ recreateProgramOnTransformCount?: number;
8
17
  }
9
18
  export interface PortalTransformer {
10
19
  /** The `typescript` namespace object */
11
20
  readonly ts: typeof tsNamespace;
12
21
  /** Active `Program` instance for the transformer */
13
22
  readonly program: tsNamespace.Program;
23
+ /** Clears transformed cache. */
24
+ clearCache(): void;
25
+ /** Forces `program` recreation. The transformation count for `recreateProgramOnTransformCount` will also be resetted. */
26
+ recreateProgram(): void;
14
27
  /**
15
28
  * Performs transformation.
16
29
  * @param content Base source code. If null, uses loaded source code in the TS project.
@@ -2,27 +2,31 @@ import * as fs from 'fs';
2
2
  import { createRequire } from 'module';
3
3
  import * as path from 'path';
4
4
  import createTransformer from './createTransformer.mjs';
5
- import { printSourceWithMap } from './transform.mjs';
5
+ import { getIgnoreFilesFunction, printSourceWithMap, } from './transform.mjs';
6
6
  const require = createRequire(import.meta.url);
7
+ function optionsToString(options) {
8
+ return JSON.stringify(options, (key, value) => {
9
+ if (typeof value === 'function' || value instanceof RegExp) {
10
+ return value.toString();
11
+ }
12
+ if (key === 'typescript' && typeof value === 'object' && value != null) {
13
+ return '[object typescript]';
14
+ }
15
+ return value;
16
+ });
17
+ }
7
18
  function createPortalTransformerImpl(options, ts) {
8
19
  const project = options.project ?? 'tsconfig.json';
9
- let ignoreFiles = options.ignoreFiles ?? [];
10
- if (typeof ignoreFiles !== 'function') {
11
- const a = ignoreFiles;
12
- ignoreFiles = (fileName) => {
13
- return a.some((t) => {
14
- if (typeof t === 'string') {
15
- return fileName.indexOf(t) >= 0;
16
- }
17
- else {
18
- return t.test(fileName);
19
- }
20
- });
21
- };
22
- }
20
+ const ignoreFiles = getIgnoreFilesFunction(options.ignoreFiles);
23
21
  const cwd = options.cwd ?? process.cwd();
22
+ const recreateProgramOnTransformCount = options.recreateProgramOnTransformCount ?? 0;
23
+ // eslint-disable-next-line @typescript-eslint/unbound-method
24
+ const foundConfigPath = ts.findConfigFile(cwd, ts.sys.fileExists, project);
25
+ if (foundConfigPath == null) {
26
+ throw new Error(`[ts-const-value-transformer] Unable to load tsconfig file (effective name = '${project}')`);
27
+ }
24
28
  const getCurrentDirectory = () => cwd;
25
- const config = ts.getParsedCommandLineOfConfigFile(project, void 0, {
29
+ const config = ts.getParsedCommandLineOfConfigFile(foundConfigPath, void 0, {
26
30
  fileExists: fs.existsSync,
27
31
  getCurrentDirectory,
28
32
  // eslint-disable-next-line @typescript-eslint/unbound-method
@@ -38,16 +42,37 @@ function createPortalTransformerImpl(options, ts) {
38
42
  },
39
43
  });
40
44
  if (!config) {
41
- throw new Error(`[ts-const-value-transformer] Unable to load tsconfig file (effective name = '${project}')`);
45
+ throw new Error(`[ts-const-value-transformer] Unable to load tsconfig file (effective name = '${foundConfigPath}')`);
42
46
  }
43
- const program = ts.createProgram({
47
+ let program = ts.createProgram({
44
48
  options: config.options,
45
49
  rootNames: config.fileNames,
46
50
  });
47
- return {
51
+ let transformationCount = 0;
52
+ const recreateProgram = () => {
53
+ const oldProgram = program;
54
+ program = ts.createProgram({
55
+ options: config.options,
56
+ rootNames: config.fileNames,
57
+ oldProgram,
58
+ });
59
+ instance.program = program;
60
+ transformationCount = 0;
61
+ };
62
+ const cache = new Map();
63
+ const instance = {
48
64
  ts,
49
65
  program,
66
+ clearCache: () => cache.clear(),
67
+ recreateProgram,
50
68
  transform: (content, fileName, sourceMap, individualOptions) => {
69
+ const individualOptionsJson = optionsToString(individualOptions ?? {});
70
+ const cachedData = cache.get(fileName);
71
+ if (cachedData &&
72
+ cachedData.content === content &&
73
+ cachedData.optJson === individualOptionsJson) {
74
+ return cachedData.result;
75
+ }
51
76
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
52
77
  const rawSourceMap = typeof sourceMap === 'string'
53
78
  ? JSON.parse(sourceMap)
@@ -55,30 +80,38 @@ function createPortalTransformerImpl(options, ts) {
55
80
  if (ignoreFiles(fileName)) {
56
81
  return [content, rawSourceMap];
57
82
  }
83
+ transformationCount++;
84
+ if (recreateProgramOnTransformCount > 0 &&
85
+ transformationCount >= recreateProgramOnTransformCount) {
86
+ recreateProgram();
87
+ }
58
88
  const sourceFile = program.getSourceFile(fileName);
59
89
  if (!sourceFile) {
60
90
  return [content, rawSourceMap];
61
91
  }
62
92
  // If input content is changed, replace it
63
- if (content != null && sourceFile.getFullText() !== content) {
93
+ if (content != null && sourceFile.text !== content) {
64
94
  sourceFile.update(content, {
65
95
  span: { start: 0, length: sourceFile.end },
66
96
  newLength: content.length,
67
97
  });
98
+ sourceFile.text = content;
68
99
  }
69
100
  const transformer = createTransformer(program, {
70
101
  options: { ...options, ...individualOptions, ts },
71
102
  });
72
- const result = ts.transform(sourceFile, [transformer], program.getCompilerOptions());
73
- const transformedSource = result.transformed[0];
103
+ const transformResult = ts.transform(sourceFile, [transformer], program.getCompilerOptions());
104
+ const transformedSource = transformResult.transformed[0];
74
105
  // If unchanged, return base file as-is
75
106
  if (transformedSource === sourceFile) {
76
- return [content ?? sourceFile.getFullText(), rawSourceMap];
107
+ return [content ?? sourceFile.text, rawSourceMap];
77
108
  }
78
- const printed = printSourceWithMap(transformedSource, fileName, rawSourceMap);
79
- return printed;
109
+ const result = printSourceWithMap(transformedSource, fileName, rawSourceMap, ts);
110
+ cache.set(fileName, { content, optJson: individualOptionsJson, result });
111
+ return result;
80
112
  },
81
113
  };
114
+ return instance;
82
115
  }
83
116
  /**
84
117
  * Creates the new portal transformer instance for the TS project.
@@ -3,7 +3,8 @@ import { type TransformOptions } from './transform.mjs';
3
3
  interface Config {
4
4
  options?: TransformOptions;
5
5
  }
6
+ export type TransformerFactory = (context?: ts.TransformationContext) => (sourceFile: ts.SourceFile) => ts.SourceFile;
6
7
  export default function createTransformer(program: ts.Program, config?: Config, extras?: {
7
8
  ts?: typeof ts;
8
- }): ts.TransformerFactory<ts.SourceFile>;
9
+ }): TransformerFactory;
9
10
  export {};
@@ -1,15 +1,20 @@
1
- import { transformSource } from './transform.mjs';
1
+ import { getIgnoreFilesFunction, transformSource, } from './transform.mjs';
2
2
  export default function createTransformer(program,
3
3
  // for ttypescript and ts-patch
4
4
  config,
5
5
  // for ts-patch
6
6
  extras) {
7
- return (context) => {
7
+ const options = {
8
+ ...config?.options,
9
+ ...(extras?.ts && { ts: extras?.ts }),
10
+ };
11
+ const ignoreFiles = getIgnoreFilesFunction(options.ignoreFiles);
12
+ return ((context) => {
8
13
  return (sourceFile) => {
9
- return transformSource(sourceFile, program, context, {
10
- ...config?.options,
11
- ...(extras?.ts && { ts: extras?.ts }),
12
- });
14
+ if (ignoreFiles(sourceFile.fileName)) {
15
+ return sourceFile;
16
+ }
17
+ return transformSource(sourceFile, program, context, options);
13
18
  };
14
- };
19
+ });
15
20
  }
package/dist/loader.d.mts CHANGED
@@ -1,9 +1,5 @@
1
- import type * as tsNamespace from 'typescript';
2
1
  import type * as webpack from 'webpack';
3
- import type { TransformOptions } from './transform.mjs';
4
- export interface TsConstValueTransformerLoaderOptions extends TransformOptions {
5
- project?: string;
6
- typescript?: string | typeof tsNamespace;
7
- }
2
+ import { type CreatePortalTransformerOptions } from './createPortalTransformer.mjs';
3
+ export type TsConstValueTransformerLoaderOptions = CreatePortalTransformerOptions;
8
4
  declare const loader: webpack.LoaderDefinitionFunction<TsConstValueTransformerLoaderOptions | undefined>;
9
5
  export default loader;
package/dist/loader.mjs CHANGED
@@ -1,17 +1,19 @@
1
1
  import * as path from 'path';
2
- import createPortalTransformer, {} from './createPortalTransformer.mjs';
2
+ import { createPortalTransformerSync, } from './createPortalTransformer.mjs';
3
3
  const transformerMap = new Map();
4
4
  const loader = function (content, sourceMap) {
5
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions, @typescript-eslint/strict-boolean-expressions
6
+ this.cacheable && this.cacheable();
5
7
  this.async();
6
- void (async () => {
8
+ void Promise.resolve().then(() => {
7
9
  try {
8
10
  const options = this.getOptions() || {};
9
11
  const project = options.project ?? 'tsconfig.json';
10
12
  let transformer = transformerMap.get(project);
11
13
  if (!transformer) {
12
- transformer = await createPortalTransformer({
13
- ...options,
14
+ transformer = createPortalTransformerSync({
14
15
  cwd: path.dirname(this.resourcePath),
16
+ ...options,
15
17
  });
16
18
  transformerMap.set(project, transformer);
17
19
  }
@@ -21,6 +23,6 @@ const loader = function (content, sourceMap) {
21
23
  catch (e) {
22
24
  this.callback(e);
23
25
  }
24
- })();
26
+ });
25
27
  };
26
28
  export default loader;
@@ -1,5 +1,5 @@
1
1
  import * as sourceMap from 'source-map';
2
- import * as ts from 'typescript';
2
+ import type * as ts from 'typescript';
3
3
  export interface TransformOptions {
4
4
  /** `typescript` namespace object */
5
5
  ts?: typeof ts;
@@ -35,6 +35,7 @@ export interface TransformOptions {
35
35
  */
36
36
  ignoreFiles?: ReadonlyArray<string | RegExp> | ((fileName: string) => boolean);
37
37
  }
38
- export declare function transformSource(sourceFile: ts.SourceFile, program: ts.Program, context: ts.TransformationContext, options?: TransformOptions): ts.SourceFile;
39
- export declare function printSource(sourceFile: ts.SourceFile): string;
40
- export declare function printSourceWithMap(sourceFile: ts.SourceFile, originalSourceName: string, startOfSourceMap?: sourceMap.RawSourceMap): [string, sourceMap.RawSourceMap];
38
+ export declare function getIgnoreFilesFunction(ignoreFiles: TransformOptions['ignoreFiles']): (fileName: string) => boolean;
39
+ export declare function transformSource(sourceFile: ts.SourceFile, program: ts.Program, context: ts.TransformationContext | undefined, options?: TransformOptions): ts.SourceFile;
40
+ export declare function printSource(sourceFile: ts.SourceFile, tsInstance?: typeof ts): string;
41
+ export declare function printSourceWithMap(sourceFile: ts.SourceFile, originalSourceName: string, startOfSourceMap?: sourceMap.RawSourceMap, tsInstance?: typeof ts): [string, sourceMap.RawSourceMap];
@@ -1,10 +1,10 @@
1
1
  import * as sourceMap from 'source-map';
2
- import * as ts from 'typescript';
2
+ import * as tsNamespace from 'typescript';
3
3
  const SYMBOL_ORIGINAL_NODE = Symbol('originalNode');
4
4
  function assignDefaultValues(options = {}) {
5
5
  return {
6
6
  // avoid using spread syntax to override `undefined` (not missing) values
7
- ts: options.ts ?? ts,
7
+ ts: options.ts ?? tsNamespace,
8
8
  hoistProperty: options.hoistProperty ?? true,
9
9
  hoistEnumValues: options.hoistEnumValues ?? true,
10
10
  hoistExternalValues: options.hoistExternalValues ?? true,
@@ -19,18 +19,36 @@ function assignDefaultValues(options = {}) {
19
19
  };
20
20
  }
21
21
  ////////////////////////////////////////////////////////////////////////////////
22
+ export function getIgnoreFilesFunction(ignoreFiles) {
23
+ if (!ignoreFiles) {
24
+ return () => false;
25
+ }
26
+ if (typeof ignoreFiles === 'function') {
27
+ return ignoreFiles;
28
+ }
29
+ const a = ignoreFiles;
30
+ return (fileName) => {
31
+ return a.some((t) => {
32
+ if (typeof t === 'string') {
33
+ return fileName.indexOf(t) >= 0;
34
+ }
35
+ else {
36
+ return t.test(fileName);
37
+ }
38
+ });
39
+ };
40
+ }
41
+ ////////////////////////////////////////////////////////////////////////////////
22
42
  export function transformSource(sourceFile, program, context, options) {
23
- return visitNodeChildren(sourceFile, sourceFile, sourceFile, program, context, assignDefaultValues(options));
43
+ const requiredOptions = assignDefaultValues(options);
44
+ return requiredOptions.ts.visitEachChild(sourceFile, (node) => visitNodeChildren(node, sourceFile, sourceFile, program, requiredOptions), context);
24
45
  }
25
- function visitNodeChildren(node, parent, sourceFile, program, context, options) {
26
- const newNode = visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, context, options);
46
+ function visitNodeChildren(node, parent, sourceFile, program, options) {
47
+ const ts = options.ts;
48
+ const newNode = visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, options);
27
49
  if (newNode[SYMBOL_ORIGINAL_NODE]) {
28
50
  return newNode;
29
51
  }
30
- // skip children for satisifes expression
31
- if (ts.isSatisfiesExpression(newNode)) {
32
- return newNode;
33
- }
34
52
  // skip statements which would not have 'value' expressions
35
53
  if (ts.isInterfaceDeclaration(newNode) ||
36
54
  ts.isTypeAliasDeclaration(newNode) ||
@@ -39,9 +57,9 @@ function visitNodeChildren(node, parent, sourceFile, program, context, options)
39
57
  ts.isTypeOnlyExportDeclaration(newNode)) {
40
58
  return newNode;
41
59
  }
42
- return ts.visitEachChild(newNode, (node) => visitNodeChildren(node, newNode, sourceFile, program, context, options), context);
60
+ return ts.visitEachChild(newNode, (node) => visitNodeChildren(node, newNode, sourceFile, program, options), void 0);
43
61
  }
44
- function visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, context, options) {
62
+ function visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, options) {
45
63
  const ts = options.ts;
46
64
  if (ts.isCallLikeExpression(node)) {
47
65
  if (!ts.isExpression(node) ||
@@ -87,12 +105,11 @@ function visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, context,
87
105
  return node;
88
106
  }
89
107
  if (!options.hoistExternalValues &&
90
- isExternalReference(node, program, options.externalNames)) {
108
+ isExternalReference(node, program, options.externalNames, ts)) {
91
109
  return node;
92
110
  }
93
111
  if (!options.unsafeHoistAsExpresion &&
94
- (hasAsExpression(node, context, ts) ||
95
- hasParentAsExpression(parent, context, ts))) {
112
+ (hasAsExpression(node, ts) || hasParentAsExpression(parent, ts))) {
96
113
  return node;
97
114
  }
98
115
  if (!options.unsafeHoistWritableValues) {
@@ -110,35 +127,33 @@ function visitNodeAndReplaceIfNeeded(node, parent, sourceFile, program, context,
110
127
  return node;
111
128
  }
112
129
  if (type.isStringLiteral()) {
113
- newNode = context.factory.createStringLiteral(type.value);
130
+ newNode = ts.factory.createStringLiteral(type.value);
114
131
  }
115
132
  else if (type.isNumberLiteral()) {
116
133
  if (type.value < 0) {
117
- newNode = context.factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, context.factory.createNumericLiteral(-type.value));
134
+ newNode = ts.factory.createPrefixUnaryExpression(ts.SyntaxKind.MinusToken, ts.factory.createNumericLiteral(-type.value));
118
135
  }
119
136
  else {
120
- newNode = context.factory.createNumericLiteral(type.value);
137
+ newNode = ts.factory.createNumericLiteral(type.value);
121
138
  }
122
139
  }
123
140
  else if (flags & ts.TypeFlags.BigIntLiteral) {
124
- newNode = context.factory.createBigIntLiteral(typeChecker.typeToString(type));
141
+ newNode = ts.factory.createBigIntLiteral(typeChecker.typeToString(type));
125
142
  }
126
143
  else if (flags & ts.TypeFlags.BooleanLiteral) {
127
144
  const text = typeChecker.typeToString(type);
128
145
  newNode =
129
- text === 'true'
130
- ? context.factory.createTrue()
131
- : context.factory.createFalse();
146
+ text === 'true' ? ts.factory.createTrue() : ts.factory.createFalse();
132
147
  }
133
148
  else if (flags & ts.TypeFlags.Null) {
134
- newNode = context.factory.createNull();
149
+ newNode = ts.factory.createNull();
135
150
  }
136
151
  else if (flags & ts.TypeFlags.Undefined) {
137
152
  if (options.useUndefinedSymbolForUndefinedValue) {
138
- newNode = context.factory.createIdentifier('undefined');
153
+ newNode = ts.factory.createIdentifier('undefined');
139
154
  }
140
155
  else {
141
- newNode = context.factory.createVoidZero();
156
+ newNode = ts.factory.createVoidZero();
142
157
  }
143
158
  }
144
159
  else {
@@ -165,7 +180,8 @@ function isEnumIdentifier(node, program, tsInstance) {
165
180
  const type = typeChecker.getTypeAtLocation(node);
166
181
  return (type.getFlags() & ts.TypeFlags.EnumLiteral) !== 0;
167
182
  }
168
- function isExternalReference(node, program, externalNames) {
183
+ function isExternalReference(node, program, externalNames, tsInstance) {
184
+ const ts = tsInstance;
169
185
  const typeChecker = program.getTypeChecker();
170
186
  const nodeSym = typeChecker.getSymbolAtLocation(node);
171
187
  let nodeFrom = nodeSym?.getDeclarations()?.[0];
@@ -218,7 +234,7 @@ function isExternalReference(node, program, externalNames) {
218
234
  function isAsConstExpression(node) {
219
235
  return node.type.getText() === 'const';
220
236
  }
221
- function hasAsExpression(node, context, tsInstance) {
237
+ function hasAsExpression(node, tsInstance) {
222
238
  const ts = tsInstance;
223
239
  // including 'as const'
224
240
  if (ts.isAsExpression(node)) {
@@ -227,13 +243,13 @@ function hasAsExpression(node, context, tsInstance) {
227
243
  let found = false;
228
244
  ts.visitEachChild(node, (node) => {
229
245
  if (!found) {
230
- found = hasAsExpression(node, context, ts);
246
+ found = hasAsExpression(node, ts);
231
247
  }
232
248
  return node;
233
- }, context);
249
+ }, void 0);
234
250
  return found;
235
251
  }
236
- function hasParentAsExpression(node, context, tsInstance) {
252
+ function hasParentAsExpression(node, tsInstance) {
237
253
  const ts = tsInstance;
238
254
  if (node == null) {
239
255
  return false;
@@ -244,11 +260,11 @@ function hasParentAsExpression(node, context, tsInstance) {
244
260
  }
245
261
  if (ts.isPropertyAccessExpression(node) ||
246
262
  ts.isElementAccessExpression(node)) {
247
- if (hasAsExpression(node.expression, context, ts)) {
263
+ if (hasAsExpression(node.expression, ts)) {
248
264
  return true;
249
265
  }
250
266
  }
251
- return hasParentAsExpression(node.parent, context, ts);
267
+ return hasParentAsExpression(node.parent, ts);
252
268
  }
253
269
  function hasPureAnnotation(node, sourceFile, tsInstance) {
254
270
  const ts = tsInstance;
@@ -388,19 +404,19 @@ function isUndefinedIdentifier(node, parent, program, tsInstance) {
388
404
  return false;
389
405
  }
390
406
  if (type.isUnionOrIntersection() ||
391
- !(type.getFlags() & ts.TypeFlags.Undefined)) {
407
+ !(type.getFlags() & tsInstance.TypeFlags.Undefined)) {
392
408
  return false;
393
409
  }
394
410
  return true;
395
411
  }
396
412
  ////////////////////////////////////////////////////////////////////////////////
397
- export function printSource(sourceFile) {
398
- return printSourceImpl(sourceFile)[0];
413
+ export function printSource(sourceFile, tsInstance) {
414
+ return printSourceImpl(tsInstance, sourceFile)[0];
399
415
  }
400
- export function printSourceWithMap(sourceFile, originalSourceName, startOfSourceMap) {
416
+ export function printSourceWithMap(sourceFile, originalSourceName, startOfSourceMap, tsInstance) {
401
417
  const generator = new sourceMap.SourceMapGenerator(startOfSourceMap);
402
418
  generator.setSourceContent(originalSourceName, sourceFile.getFullText());
403
- return printSourceImpl(sourceFile, originalSourceName, generator);
419
+ return printSourceImpl(tsInstance, sourceFile, originalSourceName, generator);
404
420
  }
405
421
  function positionToLineAndColumn(sourceFile, pos, generatedDiff) {
406
422
  let line = 0;
@@ -414,16 +430,17 @@ function positionToLineAndColumn(sourceFile, pos, generatedDiff) {
414
430
  }
415
431
  return { line, column: pos - lastLinePos + generatedDiff };
416
432
  }
417
- function printSourceImpl(sourceFile, originalSourceName, mapGenerator) {
433
+ function printSourceImpl(tsInstance, sourceFile, originalSourceName, mapGenerator) {
434
+ const ts = tsInstance ?? tsNamespace;
418
435
  const printer = ts.createPrinter({ removeComments: true });
419
- const r = printNode(printer, sourceFile.getFullText(), sourceFile, sourceFile, { pos: 0, diff: 0, lastLine: 0 }, originalSourceName, mapGenerator);
436
+ const r = printNode(ts, printer, sourceFile.getFullText(), sourceFile, sourceFile, { pos: 0, diff: 0, lastLine: 0 }, originalSourceName, mapGenerator);
420
437
  return [r, mapGenerator?.toJSON()];
421
438
  }
422
- function printNode(printer, baseSource, sourceFile, node, posContext, originalSourceName, mapGenerator) {
439
+ function printNode(tsInstance, printer, baseSource, sourceFile, node, posContext, originalSourceName, mapGenerator) {
423
440
  const originalNode = node[SYMBOL_ORIGINAL_NODE];
424
441
  if (originalNode) {
425
- let result = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile);
426
- const comments = ts.getSyntheticTrailingComments(node);
442
+ let result = printer.printNode(tsInstance.EmitHint.Unspecified, node, sourceFile);
443
+ const comments = tsInstance.getSyntheticTrailingComments(node);
427
444
  if (comments) {
428
445
  for (const comment of comments) {
429
446
  result += ` /*${comment.text}*/`;
@@ -457,7 +474,7 @@ function printNode(printer, baseSource, sourceFile, node, posContext, originalSo
457
474
  let output = '';
458
475
  let headPrinted = false;
459
476
  let lastChildPos = 0;
460
- ts.visitEachChild(node, (child) => {
477
+ tsInstance.visitEachChild(node, (child) => {
461
478
  if (!headPrinted) {
462
479
  headPrinted = true;
463
480
  if (child.pos > node.pos) {
@@ -473,7 +490,7 @@ function printNode(printer, baseSource, sourceFile, node, posContext, originalSo
473
490
  addMappingForCurrent();
474
491
  posContext.pos = child.pos;
475
492
  }
476
- output += printNode(printer, baseSource, sourceFile, child, posContext, originalSourceName, mapGenerator);
493
+ output += printNode(tsInstance, printer, baseSource, sourceFile, child, posContext, originalSourceName, mapGenerator);
477
494
  lastChildPos = child.end;
478
495
  return child;
479
496
  }, void 0);
@@ -1,2 +1,2 @@
1
- declare const _default: "0.5.0";
1
+ declare const _default: "0.6.0";
2
2
  export default _default;
package/dist/version.mjs CHANGED
@@ -1 +1 @@
1
- export default '0.5.0';
1
+ export default '0.6.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-const-value-transformer",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "engines": {
5
5
  "node": ">=20.19.3"
6
6
  },