i18next-cli 1.67.3 → 1.67.4

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/dist/cjs/cli.js CHANGED
@@ -37,7 +37,7 @@ const program = new commander.Command();
37
37
  program
38
38
  .name('i18next-cli')
39
39
  .description('A unified, high-performance i18next CLI.')
40
- .version('1.67.3'); // This string is replaced with the actual version at build time by rollup
40
+ .version('1.67.4'); // This string is replaced with the actual version at build time by rollup
41
41
  // new: global config override option
42
42
  program.option('-c, --config <path>', 'Path to i18next-cli config file (overrides detection)');
43
43
  program
@@ -112,6 +112,13 @@ class ASTVisitors {
112
112
  // Type aliases → ExpressionResolver.sharedTypeAliasTable
113
113
  this.expressionResolver.captureTypeAliasDeclaration(node);
114
114
  break;
115
+ case 'TsInterfaceDeclaration':
116
+ case 'TSInterfaceDeclaration':
117
+ case 'TsInterfaceDecl':
118
+ // Interfaces → ExpressionResolver.objectTypeTable, so params typed by
119
+ // them (`{ size }: IProps`) resolve to their string-literal unions.
120
+ this.expressionResolver.captureInterfaceDeclaration(node);
121
+ break;
115
122
  case 'FunctionDeclaration':
116
123
  case 'FnDecl':
117
124
  // Return-type annotations or inferred return values for t(fn()) patterns
@@ -167,6 +174,7 @@ class ASTVisitors {
167
174
  let isNewScope = false;
168
175
  let isNewClassScope = false;
169
176
  let paramTemporaries;
177
+ let paramObjectTemporaries;
170
178
  // ENTER CLASS SCOPE for class declarations / expressions and pre-register
171
179
  // class field initializers so that later `this.<field>` references inside
172
180
  // method bodies can inherit the namespace/keyPrefix from the field.
@@ -215,6 +223,31 @@ class ASTVisitors {
215
223
  let ident;
216
224
  if (!p)
217
225
  continue;
226
+ // Destructured object param: `function f({ size }: IProps)`.
227
+ // Bind each destructured local name to its interface member's values.
228
+ const pat = p.pat ?? p.pattern ?? p;
229
+ if (pat.type === 'ObjectPattern') {
230
+ const patType = pat.typeAnnotation?.typeAnnotation ?? pat.typeAnnotation;
231
+ const members = this.expressionResolver.resolveTypeMembers(patType);
232
+ if (members) {
233
+ for (const prop of (pat.properties ?? [])) {
234
+ // `{ size }` / `{ size = 'all' }` → AssignmentPatternProperty (local name is the key)
235
+ // `{ size: s }` / `{ size: s = 'all' }` → KeyValuePatternProperty
236
+ const memberName = prop?.key?.value;
237
+ let localNode = prop?.type === 'KeyValuePatternProperty' ? prop.value : prop?.key;
238
+ if (localNode?.type === 'AssignmentPattern')
239
+ localNode = localNode.left;
240
+ const localName = localNode?.type === 'Identifier' ? localNode.value : undefined;
241
+ if (!memberName || !localName || !members[memberName])
242
+ continue;
243
+ this.expressionResolver.setTemporaryVariable(localName, members[memberName]);
244
+ if (!paramTemporaries)
245
+ paramTemporaries = [];
246
+ paramTemporaries.push(localName);
247
+ }
248
+ }
249
+ continue;
250
+ }
218
251
  // direct identifier (arrow fn params etc)
219
252
  if (p.type === 'Identifier')
220
253
  ident = p;
@@ -367,6 +400,16 @@ class ASTVisitors {
367
400
  paramTemporaries = [];
368
401
  paramTemporaries.push(paramKey);
369
402
  }
403
+ else {
404
+ // Object-shaped param (`props: IProps`) so `props.size` resolves.
405
+ const members = this.expressionResolver.resolveTypeMembers(typeAnn);
406
+ if (members) {
407
+ this.expressionResolver.setTemporaryObjectVariable(paramKey, members);
408
+ if (!paramObjectTemporaries)
409
+ paramObjectTemporaries = [];
410
+ paramObjectTemporaries.push(paramKey);
411
+ }
412
+ }
370
413
  }
371
414
  }
372
415
  }
@@ -392,6 +435,11 @@ class ASTVisitors {
392
435
  case 'TsTypeAliasDecl':
393
436
  this.expressionResolver.captureTypeAliasDeclaration(node);
394
437
  break;
438
+ case 'TsInterfaceDeclaration':
439
+ case 'TSInterfaceDeclaration':
440
+ case 'TsInterfaceDecl':
441
+ this.expressionResolver.captureInterfaceDeclaration(node);
442
+ break;
395
443
  // pattern 3: capture function return types so `t(fn())` can be resolved
396
444
  case 'FunctionDeclaration':
397
445
  case 'FnDecl':
@@ -568,6 +616,11 @@ class ASTVisitors {
568
616
  this.expressionResolver.deleteTemporaryVariable(name);
569
617
  }
570
618
  }
619
+ if (paramObjectTemporaries) {
620
+ for (const name of paramObjectTemporaries) {
621
+ this.expressionResolver.deleteTemporaryObjectVariable(name);
622
+ }
623
+ }
571
624
  this.scopeManager.exitScope();
572
625
  }
573
626
  // LEAVE CLASS SCOPE for classes
@@ -26,6 +26,13 @@ class ExpressionResolver {
26
26
  // Temporary per-scope variable overrides, used to inject .map() / .forEach()
27
27
  // callback parameters while the callback body is being walked.
28
28
  temporaryVariables = new Map();
29
+ // Shared (cross-file) table for object-shaped types: interfaces and object
30
+ // type aliases. Maps typeName -> { memberName: possible string values }.
31
+ // e.g. `interface IProps { size: ChangeType }` -> { IProps: { size: ['all','next'] } }
32
+ objectTypeTable = new Map();
33
+ // Temporary per-scope bindings for identifiers holding an object-shaped type,
34
+ // e.g. `function f(props: IProps)` -> { props: { size: ['all','next'] } }.
35
+ temporaryObjectVariables = new Map();
29
36
  constructor(hooks) {
30
37
  this.hooks = hooks;
31
38
  }
@@ -214,6 +221,13 @@ class ExpressionResolver {
214
221
  const tsType = node.typeAnnotation ?? node.typeAnn;
215
222
  if (!tsType)
216
223
  return;
224
+ // `type IProps = { size: ChangeType }` — object shape, not a string union.
225
+ if (tsType.type === 'TsTypeLiteral') {
226
+ const members = this.collectObjectTypeMembers(tsType.members);
227
+ if (members)
228
+ this.objectTypeTable.set(name, members);
229
+ return;
230
+ }
217
231
  const vals = this.resolvePossibleStringValuesFromType(tsType);
218
232
  if (vals.length > 0) {
219
233
  this.typeAliasTable.set(name, vals);
@@ -225,6 +239,78 @@ class ExpressionResolver {
225
239
  // noop
226
240
  }
227
241
  }
242
+ /**
243
+ * Capture a TypeScript interface so that parameters typed by it
244
+ * (`function f({ size }: IProps)` / `f(props: IProps)`) can resolve their
245
+ * members to string-literal unions.
246
+ *
247
+ * SWC node shape: `TsInterfaceDeclaration` with `body.body` members.
248
+ */
249
+ captureInterfaceDeclaration(node) {
250
+ try {
251
+ const name = node?.id?.type === 'Identifier' ? node.id.value : undefined;
252
+ if (!name)
253
+ return;
254
+ const members = this.collectObjectTypeMembers(node?.body?.body);
255
+ if (members)
256
+ this.objectTypeTable.set(name, members);
257
+ }
258
+ catch {
259
+ // noop
260
+ }
261
+ }
262
+ /**
263
+ * Build `{ memberName: possibleStringValues }` for an object-shaped type
264
+ * (interface body or object type-literal members). Only members whose type
265
+ * resolves to a finite string set are kept; returns undefined when none do.
266
+ */
267
+ collectObjectTypeMembers(members) {
268
+ if (!Array.isArray(members))
269
+ return undefined;
270
+ const map = {};
271
+ for (const m of members) {
272
+ if (!m || m.type !== 'TsPropertySignature')
273
+ continue;
274
+ const memberName = m.key?.type === 'Identifier' ? m.key.value : m.key?.type === 'StringLiteral' ? m.key.value : undefined;
275
+ if (!memberName)
276
+ continue;
277
+ const tsType = m.typeAnnotation?.typeAnnotation ?? m.typeAnnotation;
278
+ if (!tsType)
279
+ continue;
280
+ const vals = this.resolvePossibleStringValuesFromType(tsType);
281
+ if (vals.length > 0)
282
+ map[memberName] = vals;
283
+ }
284
+ return Object.keys(map).length > 0 ? map : undefined;
285
+ }
286
+ /**
287
+ * Resolve a type annotation that refers to an object shape (interface, object
288
+ * type alias, or inline type literal) to its member → string values map.
289
+ */
290
+ resolveTypeMembers(tsType) {
291
+ try {
292
+ if (!tsType)
293
+ return undefined;
294
+ if (tsType.type === 'TsTypeLiteral') {
295
+ return this.collectObjectTypeMembers(tsType.members);
296
+ }
297
+ if (tsType.type === 'TsTypeReference' && tsType.typeName?.type === 'Identifier') {
298
+ return this.objectTypeTable.get(tsType.typeName.value);
299
+ }
300
+ }
301
+ catch { }
302
+ return undefined;
303
+ }
304
+ /**
305
+ * Temporarily bind an identifier to an object-shaped type's members, so that
306
+ * `props.size` inside the function body resolves to the member's values.
307
+ */
308
+ setTemporaryObjectVariable(name, members) {
309
+ this.temporaryObjectVariables.set(name, members);
310
+ }
311
+ deleteTemporaryObjectVariable(name) {
312
+ this.temporaryObjectVariables.delete(name);
313
+ }
228
314
  /**
229
315
  * Capture the return-type annotation of a function declaration so that
230
316
  * `t(fn())` calls can be expanded to all union members.
@@ -552,6 +638,17 @@ class ExpressionResolver {
552
638
  const prop = expression.property;
553
639
  // only handle simple identifier base + simple property (Identifier or computed StringLiteral)
554
640
  if (obj.type === 'Identifier') {
641
+ // Parameter typed by an interface / object type: `props.size`
642
+ const objMembers = this.temporaryObjectVariables.get(obj.value);
643
+ if (objMembers) {
644
+ const propName = prop.type === 'Identifier'
645
+ ? prop.value
646
+ : prop.type === 'Computed' && prop.expression?.type === 'StringLiteral'
647
+ ? prop.expression.value
648
+ : undefined;
649
+ if (propName && objMembers[propName])
650
+ return objMembers[propName];
651
+ }
555
652
  const baseVar = this.variableTable.get(obj.value);
556
653
  const baseShared = this.sharedEnumTable.get(obj.value);
557
654
  const base = baseVar ?? baseShared;
package/dist/esm/cli.js CHANGED
@@ -31,7 +31,7 @@ const program = new Command();
31
31
  program
32
32
  .name('i18next-cli')
33
33
  .description('A unified, high-performance i18next CLI.')
34
- .version('1.67.3'); // This string is replaced with the actual version at build time by rollup
34
+ .version('1.67.4'); // This string is replaced with the actual version at build time by rollup
35
35
  // new: global config override option
36
36
  program.option('-c, --config <path>', 'Path to i18next-cli config file (overrides detection)');
37
37
  program
@@ -110,6 +110,13 @@ class ASTVisitors {
110
110
  // Type aliases → ExpressionResolver.sharedTypeAliasTable
111
111
  this.expressionResolver.captureTypeAliasDeclaration(node);
112
112
  break;
113
+ case 'TsInterfaceDeclaration':
114
+ case 'TSInterfaceDeclaration':
115
+ case 'TsInterfaceDecl':
116
+ // Interfaces → ExpressionResolver.objectTypeTable, so params typed by
117
+ // them (`{ size }: IProps`) resolve to their string-literal unions.
118
+ this.expressionResolver.captureInterfaceDeclaration(node);
119
+ break;
113
120
  case 'FunctionDeclaration':
114
121
  case 'FnDecl':
115
122
  // Return-type annotations or inferred return values for t(fn()) patterns
@@ -165,6 +172,7 @@ class ASTVisitors {
165
172
  let isNewScope = false;
166
173
  let isNewClassScope = false;
167
174
  let paramTemporaries;
175
+ let paramObjectTemporaries;
168
176
  // ENTER CLASS SCOPE for class declarations / expressions and pre-register
169
177
  // class field initializers so that later `this.<field>` references inside
170
178
  // method bodies can inherit the namespace/keyPrefix from the field.
@@ -213,6 +221,31 @@ class ASTVisitors {
213
221
  let ident;
214
222
  if (!p)
215
223
  continue;
224
+ // Destructured object param: `function f({ size }: IProps)`.
225
+ // Bind each destructured local name to its interface member's values.
226
+ const pat = p.pat ?? p.pattern ?? p;
227
+ if (pat.type === 'ObjectPattern') {
228
+ const patType = pat.typeAnnotation?.typeAnnotation ?? pat.typeAnnotation;
229
+ const members = this.expressionResolver.resolveTypeMembers(patType);
230
+ if (members) {
231
+ for (const prop of (pat.properties ?? [])) {
232
+ // `{ size }` / `{ size = 'all' }` → AssignmentPatternProperty (local name is the key)
233
+ // `{ size: s }` / `{ size: s = 'all' }` → KeyValuePatternProperty
234
+ const memberName = prop?.key?.value;
235
+ let localNode = prop?.type === 'KeyValuePatternProperty' ? prop.value : prop?.key;
236
+ if (localNode?.type === 'AssignmentPattern')
237
+ localNode = localNode.left;
238
+ const localName = localNode?.type === 'Identifier' ? localNode.value : undefined;
239
+ if (!memberName || !localName || !members[memberName])
240
+ continue;
241
+ this.expressionResolver.setTemporaryVariable(localName, members[memberName]);
242
+ if (!paramTemporaries)
243
+ paramTemporaries = [];
244
+ paramTemporaries.push(localName);
245
+ }
246
+ }
247
+ continue;
248
+ }
216
249
  // direct identifier (arrow fn params etc)
217
250
  if (p.type === 'Identifier')
218
251
  ident = p;
@@ -365,6 +398,16 @@ class ASTVisitors {
365
398
  paramTemporaries = [];
366
399
  paramTemporaries.push(paramKey);
367
400
  }
401
+ else {
402
+ // Object-shaped param (`props: IProps`) so `props.size` resolves.
403
+ const members = this.expressionResolver.resolveTypeMembers(typeAnn);
404
+ if (members) {
405
+ this.expressionResolver.setTemporaryObjectVariable(paramKey, members);
406
+ if (!paramObjectTemporaries)
407
+ paramObjectTemporaries = [];
408
+ paramObjectTemporaries.push(paramKey);
409
+ }
410
+ }
368
411
  }
369
412
  }
370
413
  }
@@ -390,6 +433,11 @@ class ASTVisitors {
390
433
  case 'TsTypeAliasDecl':
391
434
  this.expressionResolver.captureTypeAliasDeclaration(node);
392
435
  break;
436
+ case 'TsInterfaceDeclaration':
437
+ case 'TSInterfaceDeclaration':
438
+ case 'TsInterfaceDecl':
439
+ this.expressionResolver.captureInterfaceDeclaration(node);
440
+ break;
393
441
  // pattern 3: capture function return types so `t(fn())` can be resolved
394
442
  case 'FunctionDeclaration':
395
443
  case 'FnDecl':
@@ -566,6 +614,11 @@ class ASTVisitors {
566
614
  this.expressionResolver.deleteTemporaryVariable(name);
567
615
  }
568
616
  }
617
+ if (paramObjectTemporaries) {
618
+ for (const name of paramObjectTemporaries) {
619
+ this.expressionResolver.deleteTemporaryObjectVariable(name);
620
+ }
621
+ }
569
622
  this.scopeManager.exitScope();
570
623
  }
571
624
  // LEAVE CLASS SCOPE for classes
@@ -24,6 +24,13 @@ class ExpressionResolver {
24
24
  // Temporary per-scope variable overrides, used to inject .map() / .forEach()
25
25
  // callback parameters while the callback body is being walked.
26
26
  temporaryVariables = new Map();
27
+ // Shared (cross-file) table for object-shaped types: interfaces and object
28
+ // type aliases. Maps typeName -> { memberName: possible string values }.
29
+ // e.g. `interface IProps { size: ChangeType }` -> { IProps: { size: ['all','next'] } }
30
+ objectTypeTable = new Map();
31
+ // Temporary per-scope bindings for identifiers holding an object-shaped type,
32
+ // e.g. `function f(props: IProps)` -> { props: { size: ['all','next'] } }.
33
+ temporaryObjectVariables = new Map();
27
34
  constructor(hooks) {
28
35
  this.hooks = hooks;
29
36
  }
@@ -212,6 +219,13 @@ class ExpressionResolver {
212
219
  const tsType = node.typeAnnotation ?? node.typeAnn;
213
220
  if (!tsType)
214
221
  return;
222
+ // `type IProps = { size: ChangeType }` — object shape, not a string union.
223
+ if (tsType.type === 'TsTypeLiteral') {
224
+ const members = this.collectObjectTypeMembers(tsType.members);
225
+ if (members)
226
+ this.objectTypeTable.set(name, members);
227
+ return;
228
+ }
215
229
  const vals = this.resolvePossibleStringValuesFromType(tsType);
216
230
  if (vals.length > 0) {
217
231
  this.typeAliasTable.set(name, vals);
@@ -223,6 +237,78 @@ class ExpressionResolver {
223
237
  // noop
224
238
  }
225
239
  }
240
+ /**
241
+ * Capture a TypeScript interface so that parameters typed by it
242
+ * (`function f({ size }: IProps)` / `f(props: IProps)`) can resolve their
243
+ * members to string-literal unions.
244
+ *
245
+ * SWC node shape: `TsInterfaceDeclaration` with `body.body` members.
246
+ */
247
+ captureInterfaceDeclaration(node) {
248
+ try {
249
+ const name = node?.id?.type === 'Identifier' ? node.id.value : undefined;
250
+ if (!name)
251
+ return;
252
+ const members = this.collectObjectTypeMembers(node?.body?.body);
253
+ if (members)
254
+ this.objectTypeTable.set(name, members);
255
+ }
256
+ catch {
257
+ // noop
258
+ }
259
+ }
260
+ /**
261
+ * Build `{ memberName: possibleStringValues }` for an object-shaped type
262
+ * (interface body or object type-literal members). Only members whose type
263
+ * resolves to a finite string set are kept; returns undefined when none do.
264
+ */
265
+ collectObjectTypeMembers(members) {
266
+ if (!Array.isArray(members))
267
+ return undefined;
268
+ const map = {};
269
+ for (const m of members) {
270
+ if (!m || m.type !== 'TsPropertySignature')
271
+ continue;
272
+ const memberName = m.key?.type === 'Identifier' ? m.key.value : m.key?.type === 'StringLiteral' ? m.key.value : undefined;
273
+ if (!memberName)
274
+ continue;
275
+ const tsType = m.typeAnnotation?.typeAnnotation ?? m.typeAnnotation;
276
+ if (!tsType)
277
+ continue;
278
+ const vals = this.resolvePossibleStringValuesFromType(tsType);
279
+ if (vals.length > 0)
280
+ map[memberName] = vals;
281
+ }
282
+ return Object.keys(map).length > 0 ? map : undefined;
283
+ }
284
+ /**
285
+ * Resolve a type annotation that refers to an object shape (interface, object
286
+ * type alias, or inline type literal) to its member → string values map.
287
+ */
288
+ resolveTypeMembers(tsType) {
289
+ try {
290
+ if (!tsType)
291
+ return undefined;
292
+ if (tsType.type === 'TsTypeLiteral') {
293
+ return this.collectObjectTypeMembers(tsType.members);
294
+ }
295
+ if (tsType.type === 'TsTypeReference' && tsType.typeName?.type === 'Identifier') {
296
+ return this.objectTypeTable.get(tsType.typeName.value);
297
+ }
298
+ }
299
+ catch { }
300
+ return undefined;
301
+ }
302
+ /**
303
+ * Temporarily bind an identifier to an object-shaped type's members, so that
304
+ * `props.size` inside the function body resolves to the member's values.
305
+ */
306
+ setTemporaryObjectVariable(name, members) {
307
+ this.temporaryObjectVariables.set(name, members);
308
+ }
309
+ deleteTemporaryObjectVariable(name) {
310
+ this.temporaryObjectVariables.delete(name);
311
+ }
226
312
  /**
227
313
  * Capture the return-type annotation of a function declaration so that
228
314
  * `t(fn())` calls can be expanded to all union members.
@@ -550,6 +636,17 @@ class ExpressionResolver {
550
636
  const prop = expression.property;
551
637
  // only handle simple identifier base + simple property (Identifier or computed StringLiteral)
552
638
  if (obj.type === 'Identifier') {
639
+ // Parameter typed by an interface / object type: `props.size`
640
+ const objMembers = this.temporaryObjectVariables.get(obj.value);
641
+ if (objMembers) {
642
+ const propName = prop.type === 'Identifier'
643
+ ? prop.value
644
+ : prop.type === 'Computed' && prop.expression?.type === 'StringLiteral'
645
+ ? prop.expression.value
646
+ : undefined;
647
+ if (propName && objMembers[propName])
648
+ return objMembers[propName];
649
+ }
553
650
  const baseVar = this.variableTable.get(obj.value);
554
651
  const baseShared = this.sharedEnumTable.get(obj.value);
555
652
  const base = baseVar ?? baseShared;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "i18next-cli",
3
- "version": "1.67.3",
3
+ "version": "1.67.4",
4
4
  "description": "A unified, high-performance i18next CLI.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +1 @@
1
- {"version":3,"file":"ast-visitors.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/ast-visitors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAQ,MAAM,WAAW,CAAA;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC7G,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAA;AAItE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,KAAK,CAAiB;IAE9B,IAAW,UAAU,gBAEpB;IAED,SAAgB,YAAY,EAAE,YAAY,CAAA;IAC1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAoB;IACvD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAuB;IAC7D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;IACvC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,WAAW,CAAa;IAEhC;;;;;;OAMG;gBAED,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,eAAe,EACvB,kBAAkB,CAAC,EAAE,kBAAkB;IAiCzC;;;;;;;;;;;;;OAaG;IACI,mBAAmB,CAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAK/C;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IA8CzB;;;;;OAKG;IACI,KAAK,CAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAUjC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,IAAI;IAyZZ;;;;;;;;OAQG;IACH,OAAO,CAAC,gCAAgC;IAqDxC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;;;;;;;OAQG;IACI,eAAe,CAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAI5D;;OAEG;IACI,cAAc,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKxD;;;;;;OAMG;IACI,cAAc,IAAK,MAAM;IAIhC;;OAEG;IACI,cAAc,IAAK,MAAM;CAGjC"}
1
+ {"version":3,"file":"ast-visitors.d.ts","sourceRoot":"","sources":["../../../src/extractor/core/ast-visitors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAQ,MAAM,WAAW,CAAA;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC7G,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAA;AAItE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAe;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,KAAK,CAAiB;IAE9B,IAAW,UAAU,gBAEpB;IAED,SAAgB,YAAY,EAAE,YAAY,CAAA;IAC1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAoB;IACvD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAuB;IAC7D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAY;IACvC,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,WAAW,CAAa;IAEhC;;;;;;OAMG;gBAED,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,EAC7C,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,eAAe,EACvB,kBAAkB,CAAC,EAAE,kBAAkB;IAiCzC;;;;;;;;;;;;;OAaG;IACI,mBAAmB,CAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAK/C;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAqDzB;;;;;OAKG;IACI,KAAK,CAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAUjC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,IAAI;IAocZ;;;;;;;;OAQG;IACH,OAAO,CAAC,gCAAgC;IAqDxC;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;;;;;;;OAQG;IACI,eAAe,CAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAI5D;;OAEG;IACI,cAAc,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKxD;;;;;;OAMG;IACI,cAAc,IAAK,MAAM;IAIhC;;OAEG;IACI,cAAc,IAAK,MAAM;CAGjC"}
@@ -9,6 +9,8 @@ export declare class ExpressionResolver {
9
9
  private sharedTypeAliasTable;
10
10
  private sharedFunctionReturnTable;
11
11
  private temporaryVariables;
12
+ private objectTypeTable;
13
+ private temporaryObjectVariables;
12
14
  constructor(hooks: ASTVisitorHooks);
13
15
  /**
14
16
  * Clear per-file captured variables. Enums / shared maps are kept.
@@ -34,6 +36,31 @@ export declare class ExpressionResolver {
34
36
  * SWC node shapes: `TsTypeAliasDeclaration` / `TsTypeAliasDecl`
35
37
  */
36
38
  captureTypeAliasDeclaration(node: any): void;
39
+ /**
40
+ * Capture a TypeScript interface so that parameters typed by it
41
+ * (`function f({ size }: IProps)` / `f(props: IProps)`) can resolve their
42
+ * members to string-literal unions.
43
+ *
44
+ * SWC node shape: `TsInterfaceDeclaration` with `body.body` members.
45
+ */
46
+ captureInterfaceDeclaration(node: any): void;
47
+ /**
48
+ * Build `{ memberName: possibleStringValues }` for an object-shaped type
49
+ * (interface body or object type-literal members). Only members whose type
50
+ * resolves to a finite string set are kept; returns undefined when none do.
51
+ */
52
+ private collectObjectTypeMembers;
53
+ /**
54
+ * Resolve a type annotation that refers to an object shape (interface, object
55
+ * type alias, or inline type literal) to its member → string values map.
56
+ */
57
+ resolveTypeMembers(tsType: any): Record<string, string[]> | undefined;
58
+ /**
59
+ * Temporarily bind an identifier to an object-shaped type's members, so that
60
+ * `props.size` inside the function body resolves to the member's values.
61
+ */
62
+ setTemporaryObjectVariable(name: string, members: Record<string, string[]>): void;
63
+ deleteTemporaryObjectVariable(name: string): void;
37
64
  /**
38
65
  * Capture the return-type annotation of a function declaration so that
39
66
  * `t(fn())` calls can be expanded to all union members.
@@ -1 +1 @@
1
- {"version":3,"file":"expression-resolver.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/expression-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAkD,MAAM,WAAW,CAAA;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAErD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,KAAK,CAAiB;IAK9B,OAAO,CAAC,aAAa,CAA4D;IAGjF,OAAO,CAAC,eAAe,CAAiD;IAIxE,OAAO,CAAC,cAAc,CAAmC;IAIzD,OAAO,CAAC,mBAAmB,CAAmC;IAI9D,OAAO,CAAC,oBAAoB,CAAmC;IAM/D,OAAO,CAAC,yBAAyB,CAAmC;IAIpE,OAAO,CAAC,kBAAkB,CAAmC;gBAEhD,KAAK,EAAE,eAAe;IAInC;;OAEG;IACI,gBAAgB,IAAK,IAAI;IAMhC;;;;;;;;;OASG;IACH,yBAAyB,CAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IA2J3C;;;;;;;OAOG;IACH,2BAA2B,CAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAkB7C;;;;;;;;;OASG;IACH,0BAA0B,CAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAqC5C;;;;;;;;OAQG;IACH,OAAO,CAAC,iCAAiC;IA6CzC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAQ7B;;;;OAIG;IACI,oBAAoB,CAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAIlE;;OAEG;IACI,uBAAuB,CAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAInD;;;;OAIG;IACI,yBAAyB,CAAE,MAAM,EAAE,GAAG,GAAG,MAAM,EAAE;IAQxD;;;OAGG;IACI,iBAAiB,CAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAQ7D;;;;OAIG;IACI,YAAY,CAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAQtE;;;;;OAKG;IACH,sBAAsB,CAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAwBxC;;;;;;;OAOG;IACH,kCAAkC,CAAE,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE;IAKrE;;;;;;;OAOG;IACH,8BAA8B,CAAE,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE;IAKjE;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,yCAAyC;IA2NjD,OAAO,CAAC,mCAAmC;IAiH3C;;;;;;OAMG;IACH,OAAO,CAAC,6CAA6C;IAyBrD;;;;;;OAMG;IACH,OAAO,CAAC,kDAAkD;CAwB3D"}
1
+ {"version":3,"file":"expression-resolver.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/expression-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAkD,MAAM,WAAW,CAAA;AAC3F,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAErD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,KAAK,CAAiB;IAK9B,OAAO,CAAC,aAAa,CAA4D;IAGjF,OAAO,CAAC,eAAe,CAAiD;IAIxE,OAAO,CAAC,cAAc,CAAmC;IAIzD,OAAO,CAAC,mBAAmB,CAAmC;IAI9D,OAAO,CAAC,oBAAoB,CAAmC;IAM/D,OAAO,CAAC,yBAAyB,CAAmC;IAIpE,OAAO,CAAC,kBAAkB,CAAmC;IAK7D,OAAO,CAAC,eAAe,CAAmD;IAI1E,OAAO,CAAC,wBAAwB,CAAmD;gBAEtE,KAAK,EAAE,eAAe;IAInC;;OAEG;IACI,gBAAgB,IAAK,IAAI;IAMhC;;;;;;;;;OASG;IACH,yBAAyB,CAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IA2J3C;;;;;;;OAOG;IACH,2BAA2B,CAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAwB7C;;;;;;OAMG;IACH,2BAA2B,CAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAW7C;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAehC;;;OAGG;IACI,kBAAkB,CAAE,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS;IAa7E;;;OAGG;IACI,0BAA0B,CAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI;IAIlF,6BAA6B,CAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIzD;;;;;;;;;OASG;IACH,0BAA0B,CAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAqC5C;;;;;;;;OAQG;IACH,OAAO,CAAC,iCAAiC;IA6CzC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAQ7B;;;;OAIG;IACI,oBAAoB,CAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAIlE;;OAEG;IACI,uBAAuB,CAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAInD;;;;OAIG;IACI,yBAAyB,CAAE,MAAM,EAAE,GAAG,GAAG,MAAM,EAAE;IAQxD;;;OAGG;IACI,iBAAiB,CAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAQ7D;;;;OAIG;IACI,YAAY,CAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAQtE;;;;;OAKG;IACH,sBAAsB,CAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAwBxC;;;;;;;OAOG;IACH,kCAAkC,CAAE,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE;IAKrE;;;;;;;OAOG;IACH,8BAA8B,CAAE,UAAU,EAAE,UAAU,GAAG,MAAM,EAAE;IAKjE;;;;;;;;;;;;;;;;;;OAkBG;IACH,OAAO,CAAC,yCAAyC;IAqOjD,OAAO,CAAC,mCAAmC;IAiH3C;;;;;;OAMG;IACH,OAAO,CAAC,6CAA6C;IAyBrD;;;;;;OAMG;IACH,OAAO,CAAC,kDAAkD;CAwB3D"}