ts-const-value-transformer 0.9.0 → 0.10.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.
@@ -0,0 +1,377 @@
1
+ import * as tsNamespace from 'typescript';
2
+ import { printSourceWithMapWithProxy, printSourceWithProxy, transformAndPrintSourceWithMapWithProxy, transformAndPrintSourceWithProxy, transformSourceWithProxy, } from './transform.mjs';
3
+ function getNameFromElementAccessExpression(node, typeChecker) {
4
+ const type = typeChecker.getTypeAtLocation(node.argumentExpression);
5
+ if (type.isStringLiteral() || type.isNumberLiteral()) {
6
+ return `${type.value}`;
7
+ }
8
+ return null;
9
+ }
10
+ function makeTscProxy(tsInstance, program) {
11
+ const typeChecker = program && program.getTypeChecker();
12
+ const isEnumAccess = (node) => {
13
+ if (!typeChecker) {
14
+ return false;
15
+ }
16
+ const type = typeChecker.getTypeAtLocation(node);
17
+ return (type.getFlags() & tsInstance.TypeFlags.EnumLiteral) !== 0;
18
+ };
19
+ const isReadonlyPropertyAccess = (node) => {
20
+ if (!typeChecker) {
21
+ return false;
22
+ }
23
+ const type = typeChecker.getTypeAtLocation(node.expression);
24
+ const memberName = tsInstance.isPropertyAccessExpression(node)
25
+ ? node.name.getText()
26
+ : getNameFromElementAccessExpression(node, typeChecker);
27
+ if (memberName == null) {
28
+ return false;
29
+ }
30
+ if (type.getFlags() & tsInstance.TypeFlags.Object) {
31
+ const prop = type.getProperty(memberName);
32
+ if (prop) {
33
+ // Use internal but exported function to improve memory performance
34
+ if ('getCheckFlags' in tsInstance &&
35
+ 'CheckFlags' in tsInstance &&
36
+ tsInstance.CheckFlags.Readonly != null) {
37
+ const checkFlags = tsInstance.getCheckFlags(prop);
38
+ if (checkFlags &
39
+ tsInstance.CheckFlags.Readonly) {
40
+ return true;
41
+ }
42
+ }
43
+ if ('getDeclarationModifierFlagsFromSymbol' in tsInstance) {
44
+ const modifierFlags = tsInstance.getDeclarationModifierFlagsFromSymbol(prop);
45
+ if (modifierFlags & tsInstance.ModifierFlags.Readonly) {
46
+ return true;
47
+ }
48
+ }
49
+ if (prop.declarations && prop.declarations.length > 0) {
50
+ const decl = prop.declarations[0];
51
+ if (tsInstance.isPropertySignature(decl) &&
52
+ decl.modifiers?.some((m) => m.kind === tsInstance.SyntaxKind.ReadonlyKeyword)) {
53
+ return true;
54
+ }
55
+ if (tsInstance.isVariableDeclaration(decl) &&
56
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
57
+ decl.parent &&
58
+ tsInstance.isVariableDeclarationList(decl.parent) &&
59
+ decl.parent.flags & tsInstance.NodeFlags.Const) {
60
+ return true;
61
+ }
62
+ }
63
+ }
64
+ }
65
+ return false;
66
+ };
67
+ return {
68
+ visitEachChild(node, visitor, context) {
69
+ return tsInstance.visitEachChild(node, visitor, context);
70
+ },
71
+ getNodeText(node, sourceFile) {
72
+ return node.getText(sourceFile);
73
+ },
74
+ getNodeFullText(node, sourceFile) {
75
+ return node.getFullText(sourceFile);
76
+ },
77
+ appendMultiLineComment(node, comment) {
78
+ return tsInstance.addSyntheticTrailingComment(node, tsInstance.SyntaxKind.MultiLineCommentTrivia, comment);
79
+ },
80
+ setTextRange(range, location) {
81
+ return tsInstance.setTextRange(range, location);
82
+ },
83
+ isExpression(node) {
84
+ return tsInstance.isExpression(node);
85
+ },
86
+ isAsExpression(node) {
87
+ return tsInstance.isAsExpression(node);
88
+ },
89
+ isCallLikeExpression(node) {
90
+ return tsInstance.isCallLikeExpression(node);
91
+ },
92
+ isTemplateExpression(node) {
93
+ return tsInstance.isTemplateExpression(node);
94
+ },
95
+ isPropertyAccessExpression(node) {
96
+ return tsInstance.isPropertyAccessExpression(node);
97
+ },
98
+ isElementAccessExpression(node) {
99
+ return tsInstance.isElementAccessExpression(node);
100
+ },
101
+ isInterfaceDeclaration(node) {
102
+ return tsInstance.isInterfaceDeclaration(node);
103
+ },
104
+ isTypeAliasDeclaration(node) {
105
+ return tsInstance.isTypeAliasDeclaration(node);
106
+ },
107
+ isImportDeclaration(node) {
108
+ return tsInstance.isImportDeclaration(node);
109
+ },
110
+ isTypeOnlyExportDeclaration(node) {
111
+ return tsInstance.isTypeOnlyExportDeclaration(node);
112
+ },
113
+ isIdentifier(node) {
114
+ return tsInstance.isIdentifier(node);
115
+ },
116
+ isComputedPropertyName(node) {
117
+ return tsInstance.isComputedPropertyName(node);
118
+ },
119
+ getTypeAtLocation(node) {
120
+ return typeChecker?.getTypeAtLocation(node);
121
+ },
122
+ isEnumLiteral(type) {
123
+ return ((type.getFlags() & tsInstance.TypeFlags.EnumLiteral) !== 0);
124
+ },
125
+ isStringLiteral(type) {
126
+ return type.isStringLiteral();
127
+ },
128
+ isNumberLiteral(type) {
129
+ return type.isNumberLiteral();
130
+ },
131
+ isBigIntLiteral(type) {
132
+ return ((type.getFlags() & tsInstance.TypeFlags.BigIntLiteral) !==
133
+ 0);
134
+ },
135
+ isBooleanLiteral(type) {
136
+ return ((type.getFlags() & tsInstance.TypeFlags.BooleanLiteral) !==
137
+ 0);
138
+ },
139
+ isNullType(type) {
140
+ return (type.getFlags() & tsInstance.TypeFlags.Null) !== 0;
141
+ },
142
+ isUndefinedType(type) {
143
+ return ((type.getFlags() & tsInstance.TypeFlags.Undefined) !== 0);
144
+ },
145
+ typeToString(type) {
146
+ return typeChecker?.typeToString(type) ?? '';
147
+ },
148
+ factory: {
149
+ createIdentifier(text) {
150
+ return tsInstance.factory.createIdentifier(text);
151
+ },
152
+ createStringLiteral(value) {
153
+ return tsInstance.factory.createStringLiteral(value);
154
+ },
155
+ createNumericLiteral(value) {
156
+ return tsInstance.factory.createNumericLiteral(value);
157
+ },
158
+ createExpressionWithMinusToken(operand) {
159
+ return tsInstance.factory.createPrefixUnaryExpression(tsInstance.SyntaxKind.MinusToken, operand);
160
+ },
161
+ createBigIntLiteral(value) {
162
+ return tsInstance.factory.createBigIntLiteral(value);
163
+ },
164
+ createTrue() {
165
+ return tsInstance.factory.createTrue();
166
+ },
167
+ createFalse() {
168
+ return tsInstance.factory.createFalse();
169
+ },
170
+ createNull() {
171
+ return tsInstance.factory.createNull();
172
+ },
173
+ createParenthesizedExpression(expression) {
174
+ return tsInstance.factory.createParenthesizedExpression(expression);
175
+ },
176
+ createVoidZero() {
177
+ return tsInstance.factory.createVoidZero();
178
+ },
179
+ },
180
+ isEnumAccess(node) {
181
+ return isEnumAccess(node);
182
+ },
183
+ isEnumIdentifier(node) {
184
+ if (!typeChecker) {
185
+ return false;
186
+ }
187
+ const type = typeChecker.getTypeAtLocation(node);
188
+ return (type.getFlags() & tsInstance.TypeFlags.EnumLiteral) !== 0;
189
+ },
190
+ isExternalReference(node, externalNames) {
191
+ if (!typeChecker) {
192
+ return false;
193
+ }
194
+ const nodeSym = typeChecker.getSymbolAtLocation(node);
195
+ let nodeFrom = nodeSym?.getDeclarations()?.[0];
196
+ while (nodeFrom) {
197
+ const sourceFileName = nodeFrom.getSourceFile();
198
+ if (externalNames.length === 0) {
199
+ if (/[\\/]node_modules[\\/]/.test(sourceFileName.fileName)) {
200
+ return true;
201
+ }
202
+ }
203
+ else {
204
+ if (externalNames.some((part) => {
205
+ if (typeof part === 'string') {
206
+ return sourceFileName.fileName
207
+ .replace(/\\/g, '/')
208
+ .includes(part);
209
+ }
210
+ else {
211
+ return part.test(sourceFileName.fileName);
212
+ }
213
+ })) {
214
+ return true;
215
+ }
216
+ }
217
+ // Walk into the 'import' variables
218
+ if (!tsInstance.isImportSpecifier(nodeFrom)) {
219
+ break;
220
+ }
221
+ const baseName = nodeFrom.propertyName ?? nodeFrom.name;
222
+ const baseSym = typeChecker.getSymbolAtLocation(baseName);
223
+ // We must follow 'aliased' symbol for parsing the symbol which name is not changed from the exported symbol name
224
+ const exportedSym = baseSym && baseSym.getFlags() & tsInstance.SymbolFlags.Alias
225
+ ? typeChecker.getAliasedSymbol(baseSym)
226
+ : baseSym;
227
+ nodeFrom = exportedSym?.getDeclarations()?.[0];
228
+ }
229
+ const type = typeChecker.getTypeAtLocation(node);
230
+ const sym = type.getSymbol();
231
+ if (!sym) {
232
+ return false;
233
+ }
234
+ const def = sym.getDeclarations()?.[0];
235
+ if (!def) {
236
+ return false;
237
+ }
238
+ const typeDefinitionSource = def.getSourceFile();
239
+ if (program.isSourceFileFromExternalLibrary(typeDefinitionSource)) {
240
+ return true;
241
+ }
242
+ return false;
243
+ },
244
+ hasPureAnnotation(node, sourceFile) {
245
+ const fullText = node.getFullText(sourceFile);
246
+ const ranges = tsInstance.getLeadingCommentRanges(fullText, 0) ?? [];
247
+ for (const range of ranges) {
248
+ if (range.kind !== tsInstance.SyntaxKind.MultiLineCommentTrivia) {
249
+ continue;
250
+ }
251
+ const text = fullText.slice(range.pos + 2, range.end - 2).trim();
252
+ if ((text[0] === '@' || text[0] === '#') &&
253
+ text.slice(1) === '__PURE__') {
254
+ return true;
255
+ }
256
+ }
257
+ return false;
258
+ },
259
+ isReadonlyExpression(_node) {
260
+ if (!typeChecker) {
261
+ return null;
262
+ }
263
+ const node = _node;
264
+ if (tsInstance.isIdentifier(node) &&
265
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
266
+ node.parent &&
267
+ !tsInstance.isPropertyAccessExpression(node.parent)) {
268
+ const nodeSym = typeChecker.getSymbolAtLocation(node);
269
+ if (nodeSym?.valueDeclaration) {
270
+ let target = nodeSym.valueDeclaration;
271
+ for (;;) {
272
+ // Parameters are writable
273
+ if (tsInstance.isParameter(target)) {
274
+ return false;
275
+ }
276
+ if (tsInstance.isVariableDeclarationList(target)) {
277
+ if (target.flags & tsInstance.NodeFlags.Const) {
278
+ return true;
279
+ }
280
+ else {
281
+ return false;
282
+ }
283
+ }
284
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
285
+ if (!target.parent || target === target.parent) {
286
+ return false;
287
+ }
288
+ target = target.parent;
289
+ }
290
+ }
291
+ }
292
+ if (tsInstance.isPropertyAccessExpression(node) ||
293
+ tsInstance.isElementAccessExpression(node)) {
294
+ if (isEnumAccess(node)) {
295
+ return true;
296
+ }
297
+ return isReadonlyPropertyAccess(node);
298
+ }
299
+ return null;
300
+ },
301
+ isHoistablePropertyAccess(_node) {
302
+ if (!typeChecker) {
303
+ return false;
304
+ }
305
+ const node = _node;
306
+ const type = typeChecker.getTypeAtLocation(node.expression);
307
+ const memberName = tsInstance.isPropertyAccessExpression(node)
308
+ ? node.name.getText()
309
+ : getNameFromElementAccessExpression(node, typeChecker);
310
+ if (memberName == null) {
311
+ return false;
312
+ }
313
+ if (type.getFlags() & tsInstance.TypeFlags.Object) {
314
+ const prop = type.getProperty(memberName);
315
+ // If the property access uses indexed access, `prop` will be undefined
316
+ if (prop) {
317
+ return true;
318
+ }
319
+ }
320
+ return false;
321
+ },
322
+ isUndefinedIdentifier(node, parent) {
323
+ if (!typeChecker) {
324
+ return false;
325
+ }
326
+ if (tsInstance.isPropertyAccessExpression(parent) ||
327
+ tsInstance.isElementAccessExpression(parent)) {
328
+ return false;
329
+ }
330
+ const type = typeChecker.getTypeAtLocation(node);
331
+ const sym = typeChecker.getSymbolAtLocation(node);
332
+ if (!sym || sym.getEscapedName().toString() !== 'undefined') {
333
+ return false;
334
+ }
335
+ if (type.isUnionOrIntersection() ||
336
+ !(type.getFlags() & tsInstance.TypeFlags.Undefined)) {
337
+ return false;
338
+ }
339
+ return true;
340
+ },
341
+ makeStringLiteralSource(value) {
342
+ // TypeScript namespace may export `function escapeNonAsciiString(s: string, quoteChar?: CharacterCodes.doubleQuote | CharacterCodes.singleQuote | CharacterCodes.backtick): string`
343
+ return 'escapeNonAsciiString' in tsInstance
344
+ ? `"${tsInstance.escapeNonAsciiString(value, 'CharacterCodes' in tsInstance
345
+ ? tsInstance.CharacterCodes
346
+ .doubleQuote
347
+ : 34 /* doubleQuote */)}"`
348
+ : JSON.stringify(value);
349
+ },
350
+ getLineStarts(sourceFile) {
351
+ return sourceFile.getLineStarts();
352
+ },
353
+ };
354
+ }
355
+ export function printSource(sourceFile, tsInstance) {
356
+ const _ts = tsInstance ?? tsNamespace;
357
+ return printSourceWithProxy(sourceFile, makeTscProxy(_ts, null));
358
+ }
359
+ export function printSourceWithMap(sourceFile, originalSourceName, startOfSourceMap, tsInstance) {
360
+ const _ts = tsInstance ?? tsNamespace;
361
+ return printSourceWithMapWithProxy(sourceFile, originalSourceName, makeTscProxy(_ts, null), startOfSourceMap);
362
+ }
363
+ export function transformSource(sourceFile, program, context, options) {
364
+ const ts = options?.ts ?? tsNamespace;
365
+ const proxy = makeTscProxy(ts, program);
366
+ return transformSourceWithProxy(sourceFile, proxy, context, options);
367
+ }
368
+ export function transformAndPrintSource(sourceFile, program, context, options) {
369
+ const ts = options?.ts ?? tsNamespace;
370
+ const proxy = makeTscProxy(ts, program);
371
+ return transformAndPrintSourceWithProxy(sourceFile, proxy, context, options);
372
+ }
373
+ export function transformAndPrintSourceWithMap(sourceFile, program, context, originalSourceName, options, startOfSourceMap) {
374
+ const ts = options?.ts ?? tsNamespace;
375
+ const proxy = makeTscProxy(ts, program);
376
+ return transformAndPrintSourceWithMapWithProxy(sourceFile, proxy, context, originalSourceName, options, startOfSourceMap);
377
+ }
@@ -1,2 +1,2 @@
1
- declare const _default: "0.9.0";
1
+ declare const _default: "0.10.0";
2
2
  export default _default;
package/dist/version.mjs CHANGED
@@ -1 +1 @@
1
- export default '0.9.0';
1
+ export default '0.10.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-const-value-transformer",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "engines": {
5
5
  "node": ">=20.19.3"
6
6
  },
@@ -33,6 +33,16 @@
33
33
  "import": "./dist/createPortalTransformer.mjs",
34
34
  "types": "./dist/createPortalTransformer.d.mts"
35
35
  },
36
+ "./createPortalTransformerWithTsLs": {
37
+ "default": "./dist/createPortalTransformerWithTsLs.mjs",
38
+ "import": "./dist/createPortalTransformerWithTsLs.mjs",
39
+ "types": "./dist/createPortalTransformerWithTsLs.d.mts"
40
+ },
41
+ "./createPortalTransformerWithTsLs.mjs": {
42
+ "default": "./dist/createPortalTransformerWithTsLs.mjs",
43
+ "import": "./dist/createPortalTransformerWithTsLs.mjs",
44
+ "types": "./dist/createPortalTransformerWithTsLs.d.mts"
45
+ },
36
46
  "./getCustomTransformers": {
37
47
  "default": "./dist/getCustomTransformers.mjs",
38
48
  "import": "./dist/getCustomTransformers.mjs",
@@ -96,6 +106,7 @@
96
106
  "@types/node": "~20.19.22",
97
107
  "@typescript-eslint/eslint-plugin": "^8.48.0",
98
108
  "@typescript-eslint/parser": "^8.48.0",
109
+ "@typescript/native-preview": "7.0.0-dev.20260211.1",
99
110
  "babel-loader": "^10.0.0",
100
111
  "eslint": "^9.39.1",
101
112
  "eslint-config-prettier": "^10.1.8",
@@ -112,12 +123,14 @@
112
123
  "ts-patch": "^3.3.0",
113
124
  "tslib": "^2.8.1",
114
125
  "typescript": "~5.5.4",
115
- "webpack": "^5.103.0"
126
+ "webpack": "^5.103.0",
127
+ "webpack-cli": "^6.0.1"
116
128
  },
117
129
  "peerDependencies": {
118
130
  "typescript": ">=5.5"
119
131
  },
120
132
  "dependencies": {
121
- "source-map": "^0.7.6"
133
+ "source-map": "^0.7.6",
134
+ "sync-child-process": "^1.0.2"
122
135
  }
123
136
  }