i18next-cli 1.69.2 → 1.70.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/dist/cjs/cli.js +1 -1
- package/dist/cjs/extractor/core/ast-visitors.js +164 -113
- package/dist/cjs/extractor/parsers/comment-parser.js +3 -1
- package/dist/cjs/extractor/parsers/expression-resolver.js +8 -0
- package/dist/cjs/extractor/parsers/scope-manager.js +62 -0
- package/dist/esm/cli.js +1 -1
- package/dist/esm/extractor/core/ast-visitors.js +164 -113
- package/dist/esm/extractor/parsers/comment-parser.js +3 -1
- package/dist/esm/extractor/parsers/expression-resolver.js +8 -0
- package/dist/esm/extractor/parsers/scope-manager.js +62 -0
- package/package.json +1 -1
- package/types/extractor/core/ast-visitors.d.ts +11 -0
- package/types/extractor/core/ast-visitors.d.ts.map +1 -1
- package/types/extractor/parsers/expression-resolver.d.ts +2 -0
- package/types/extractor/parsers/expression-resolver.d.ts.map +1 -1
- package/types/extractor/parsers/scope-manager.d.ts +6 -0
- package/types/extractor/parsers/scope-manager.d.ts.map +1 -1
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.
|
|
40
|
+
.version('1.70.1'); // 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
|
|
@@ -230,22 +230,24 @@ class ASTVisitors {
|
|
|
230
230
|
if (pat.type === 'ObjectPattern') {
|
|
231
231
|
const patType = pat.typeAnnotation?.typeAnnotation ?? pat.typeAnnotation;
|
|
232
232
|
const members = this.expressionResolver.resolveTypeMembers(patType);
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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)
|
|
242
|
+
continue;
|
|
243
|
+
// `({ t }: { t: TFunction<'ns'> })` → bind `t` to that namespace
|
|
244
|
+
this.bindTFunctionParam(localName, this.getMemberTypeNode(patType, memberName));
|
|
245
|
+
if (!members?.[memberName])
|
|
246
|
+
continue;
|
|
247
|
+
this.expressionResolver.setTemporaryVariable(localName, members[memberName]);
|
|
248
|
+
if (!paramTemporaries)
|
|
249
|
+
paramTemporaries = [];
|
|
250
|
+
paramTemporaries.push(localName);
|
|
249
251
|
}
|
|
250
252
|
continue;
|
|
251
253
|
}
|
|
@@ -292,103 +294,7 @@ class ASTVisitors {
|
|
|
292
294
|
else {
|
|
293
295
|
typeAnn = undefined;
|
|
294
296
|
}
|
|
295
|
-
|
|
296
|
-
const extractTypeName = (ta) => {
|
|
297
|
-
if (!ta)
|
|
298
|
-
return undefined;
|
|
299
|
-
// Identifier style: { type: 'Identifier', value: 'TFunction' } OR { name: 'TFunction' }
|
|
300
|
-
if (ta.typeName && (ta.typeName.type === 'Identifier'))
|
|
301
|
-
return ta.typeName.value ?? ta.typeName.name;
|
|
302
|
-
if (ta.typeName && ta.typeName.type === 'TsQualifiedName') {
|
|
303
|
-
// Qualified like Foo.TFunction -> try right side
|
|
304
|
-
const right = (ta.typeName.right ?? ta.typeName);
|
|
305
|
-
return right?.value ?? right?.name;
|
|
306
|
-
}
|
|
307
|
-
if (ta.typeName && typeof ta.typeName === 'string')
|
|
308
|
-
return ta.typeName;
|
|
309
|
-
if (ta.type === 'Identifier')
|
|
310
|
-
return ta.value ?? ta.name;
|
|
311
|
-
if (ta.id)
|
|
312
|
-
return ta.id?.value ?? ta.id?.name ?? ta.id;
|
|
313
|
-
return undefined;
|
|
314
|
-
};
|
|
315
|
-
const extractStringLiteralValue = (node) => {
|
|
316
|
-
if (!node)
|
|
317
|
-
return undefined;
|
|
318
|
-
// Handle: typeof SomeConst → TsTypeQuery { exprName: { value: 'SomeConst' } }
|
|
319
|
-
if (node?.type === 'TsTypeQuery') {
|
|
320
|
-
const name = node.exprName?.value ?? node.exprName?.name;
|
|
321
|
-
if (name)
|
|
322
|
-
return this.scopeManager.resolveSimpleStringIdentifier(name);
|
|
323
|
-
}
|
|
324
|
-
// shapes: TsLiteralType -> { literal: { type: 'StringLiteral', value: 'x' } }
|
|
325
|
-
if (node.type === 'TsLiteralType' && node.literal)
|
|
326
|
-
return node.literal.value ?? node.literal.raw;
|
|
327
|
-
if (node.type === 'StringLiteral' || node.type === 'Str' || node.type === 'Literal')
|
|
328
|
-
return node.value ?? node.raw ?? node.value;
|
|
329
|
-
if (node.literal && (node.literal.type === 'StringLiteral' || node.literal.type === 'Str'))
|
|
330
|
-
return node.literal.value;
|
|
331
|
-
// some SWC builds put the string directly on .value
|
|
332
|
-
if (typeof node.value === 'string')
|
|
333
|
-
return node.value;
|
|
334
|
-
// handle wrapped parameter like { params: [ ... ] } where a literal might be one level deeper
|
|
335
|
-
if (node.params && Array.isArray(node.params) && node.params[0])
|
|
336
|
-
return extractStringLiteralValue(node.params[0]);
|
|
337
|
-
if (node.typeArguments && Array.isArray(node.typeArguments) && node.typeArguments[0])
|
|
338
|
-
return extractStringLiteralValue(node.typeArguments[0]);
|
|
339
|
-
if (node.typeParameters && Array.isArray(node.typeParameters) && node.typeParameters[0])
|
|
340
|
-
return extractStringLiteralValue(node.typeParameters[0]);
|
|
341
|
-
if (node.typeParams && Array.isArray(node.typeParams) && node.typeParams[0])
|
|
342
|
-
return extractStringLiteralValue(node.typeParams[0]);
|
|
343
|
-
return undefined;
|
|
344
|
-
};
|
|
345
|
-
// Detect TsTypeReference like: TFunction<"my-custom-namespace">
|
|
346
|
-
if (typeAnn && (typeAnn.type === 'TsTypeReference' || typeAnn.type === 'TsTypeRef' || typeAnn.type === 'TsTypeReference')) {
|
|
347
|
-
const finalTypeName = extractTypeName(typeAnn);
|
|
348
|
-
if (finalTypeName === 'TFunction') {
|
|
349
|
-
// support multiple AST shapes for type parameters:
|
|
350
|
-
// - typeAnn.typeParameters?.params?.[0]
|
|
351
|
-
// - typeAnn.typeArguments?.params?.[0]
|
|
352
|
-
// - typeAnn.typeParams?.[0] / typeAnn.params?.[0]
|
|
353
|
-
const candidates = [
|
|
354
|
-
typeAnn.typeParameters?.params?.[0],
|
|
355
|
-
typeAnn.typeParameters?.[0],
|
|
356
|
-
typeAnn.typeArguments?.params?.[0],
|
|
357
|
-
typeAnn.typeArguments?.[0],
|
|
358
|
-
typeAnn.typeParams?.params?.[0],
|
|
359
|
-
typeAnn.typeParams?.[0],
|
|
360
|
-
typeAnn.params?.[0],
|
|
361
|
-
typeAnn.args?.[0],
|
|
362
|
-
typeAnn.typeParameters, // fallback if it's directly the literal
|
|
363
|
-
typeAnn.typeArguments,
|
|
364
|
-
typeAnn.typeParams,
|
|
365
|
-
];
|
|
366
|
-
let tp;
|
|
367
|
-
for (const c of candidates) {
|
|
368
|
-
if (c) {
|
|
369
|
-
tp = c;
|
|
370
|
-
break;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
const ns = extractStringLiteralValue(tp);
|
|
374
|
-
// Extract the second type parameter for KPrefix
|
|
375
|
-
// We need to find the second element from the same type parameter list
|
|
376
|
-
const typeParams = typeAnn.typeParameters?.params ??
|
|
377
|
-
typeAnn.typeArguments?.params ??
|
|
378
|
-
typeAnn.typeParams?.params ??
|
|
379
|
-
undefined;
|
|
380
|
-
let kpFromType;
|
|
381
|
-
if (typeParams && typeParams.length >= 2) {
|
|
382
|
-
kpFromType = extractStringLiteralValue(typeParams[1]);
|
|
383
|
-
}
|
|
384
|
-
if (ns || kpFromType) {
|
|
385
|
-
this.scopeManager.setVarInScope(paramKey, {
|
|
386
|
-
defaultNs: ns,
|
|
387
|
-
keyPrefix: kpFromType // honour TFunction<Ns, KPrefix>
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
297
|
+
this.bindTFunctionParam(paramKey, typeAnn);
|
|
392
298
|
// Capture parameter type annotations as temporary variables in the
|
|
393
299
|
// expression resolver so that dynamic bracket expressions like
|
|
394
300
|
// `t(($) => $.table.columns[field])` can resolve `field` to its
|
|
@@ -650,6 +556,151 @@ class ASTVisitors {
|
|
|
650
556
|
this.scopeManager.exitClassScope();
|
|
651
557
|
}
|
|
652
558
|
}
|
|
559
|
+
/**
|
|
560
|
+
* If `typeAnn` is a `TFunction<Ns, KPrefix>` type reference, register
|
|
561
|
+
* `paramKey` in the current scope with that namespace / keyPrefix.
|
|
562
|
+
*/
|
|
563
|
+
bindTFunctionParam(paramKey, typeAnn) {
|
|
564
|
+
// Small helpers to robustly extract the referenced type name and literal string
|
|
565
|
+
const extractTypeName = (ta) => {
|
|
566
|
+
if (!ta)
|
|
567
|
+
return undefined;
|
|
568
|
+
// Identifier style: { type: 'Identifier', value: 'TFunction' } OR { name: 'TFunction' }
|
|
569
|
+
if (ta.typeName && (ta.typeName.type === 'Identifier'))
|
|
570
|
+
return ta.typeName.value ?? ta.typeName.name;
|
|
571
|
+
if (ta.typeName && ta.typeName.type === 'TsQualifiedName') {
|
|
572
|
+
// Qualified like Foo.TFunction -> try right side
|
|
573
|
+
const right = (ta.typeName.right ?? ta.typeName);
|
|
574
|
+
return right?.value ?? right?.name;
|
|
575
|
+
}
|
|
576
|
+
if (ta.typeName && typeof ta.typeName === 'string')
|
|
577
|
+
return ta.typeName;
|
|
578
|
+
if (ta.type === 'Identifier')
|
|
579
|
+
return ta.value ?? ta.name;
|
|
580
|
+
if (ta.id)
|
|
581
|
+
return ta.id?.value ?? ta.id?.name ?? ta.id;
|
|
582
|
+
return undefined;
|
|
583
|
+
};
|
|
584
|
+
const extractStringLiteralValue = (node) => {
|
|
585
|
+
if (!node)
|
|
586
|
+
return undefined;
|
|
587
|
+
// Handle: typeof SomeConst → TsTypeQuery { exprName: { value: 'SomeConst' } }
|
|
588
|
+
if (node?.type === 'TsTypeQuery') {
|
|
589
|
+
const name = node.exprName?.value ?? node.exprName?.name;
|
|
590
|
+
if (name)
|
|
591
|
+
return this.scopeManager.resolveSimpleStringIdentifier(name);
|
|
592
|
+
}
|
|
593
|
+
// shapes: TsLiteralType -> { literal: { type: 'StringLiteral', value: 'x' } }
|
|
594
|
+
if (node.type === 'TsLiteralType' && node.literal)
|
|
595
|
+
return node.literal.value ?? node.literal.raw;
|
|
596
|
+
if (node.type === 'StringLiteral' || node.type === 'Str' || node.type === 'Literal')
|
|
597
|
+
return node.value ?? node.raw ?? node.value;
|
|
598
|
+
if (node.literal && (node.literal.type === 'StringLiteral' || node.literal.type === 'Str'))
|
|
599
|
+
return node.literal.value;
|
|
600
|
+
// some SWC builds put the string directly on .value
|
|
601
|
+
if (typeof node.value === 'string')
|
|
602
|
+
return node.value;
|
|
603
|
+
// handle wrapped parameter like { params: [ ... ] } where a literal might be one level deeper
|
|
604
|
+
if (node.params && Array.isArray(node.params) && node.params[0])
|
|
605
|
+
return extractStringLiteralValue(node.params[0]);
|
|
606
|
+
if (node.typeArguments && Array.isArray(node.typeArguments) && node.typeArguments[0])
|
|
607
|
+
return extractStringLiteralValue(node.typeArguments[0]);
|
|
608
|
+
if (node.typeParameters && Array.isArray(node.typeParameters) && node.typeParameters[0])
|
|
609
|
+
return extractStringLiteralValue(node.typeParameters[0]);
|
|
610
|
+
if (node.typeParams && Array.isArray(node.typeParams) && node.typeParams[0])
|
|
611
|
+
return extractStringLiteralValue(node.typeParams[0]);
|
|
612
|
+
return undefined;
|
|
613
|
+
};
|
|
614
|
+
// `ReturnType<typeof useTranslation<'ns', 'kp'>>['t']` is `TFunction<'ns', 'kp'>` spelled indirectly.
|
|
615
|
+
if (typeAnn?.type === 'TsIndexedAccessType' && extractStringLiteralValue(typeAnn.indexType) === 't') {
|
|
616
|
+
const obj = typeAnn.objectType;
|
|
617
|
+
const query = obj?.type === 'TsTypeReference' && extractTypeName(obj) === 'ReturnType'
|
|
618
|
+
? (obj.typeParams?.params?.[0] ?? obj.typeArguments?.params?.[0])
|
|
619
|
+
: undefined;
|
|
620
|
+
const hookName = query?.type === 'TsTypeQuery' ? (query.exprName?.value ?? query.exprName?.name) : undefined;
|
|
621
|
+
const hookNames = this.config.extract.useTranslationNames || ['useTranslation', 'getT', 'useT'];
|
|
622
|
+
if (hookName && hookNames.some(h => (typeof h === 'string' ? h : h.name) === hookName)) {
|
|
623
|
+
const params = query.typeArguments?.params ?? query.typeArgs?.params ?? [];
|
|
624
|
+
const ns = extractStringLiteralValue(params[0]);
|
|
625
|
+
const kp = extractStringLiteralValue(params[1]);
|
|
626
|
+
if (ns || kp)
|
|
627
|
+
this.scopeManager.setVarInScope(paramKey, { defaultNs: ns, keyPrefix: kp });
|
|
628
|
+
}
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
// Detect TsTypeReference like: TFunction<"my-custom-namespace">
|
|
632
|
+
if (typeAnn && (typeAnn.type === 'TsTypeReference' || typeAnn.type === 'TsTypeRef' || typeAnn.type === 'TsTypeReference')) {
|
|
633
|
+
const finalTypeName = extractTypeName(typeAnn);
|
|
634
|
+
if (finalTypeName === 'TFunction') {
|
|
635
|
+
// support multiple AST shapes for type parameters:
|
|
636
|
+
// - typeAnn.typeParameters?.params?.[0]
|
|
637
|
+
// - typeAnn.typeArguments?.params?.[0]
|
|
638
|
+
// - typeAnn.typeParams?.[0] / typeAnn.params?.[0]
|
|
639
|
+
const candidates = [
|
|
640
|
+
typeAnn.typeParameters?.params?.[0],
|
|
641
|
+
typeAnn.typeParameters?.[0],
|
|
642
|
+
typeAnn.typeArguments?.params?.[0],
|
|
643
|
+
typeAnn.typeArguments?.[0],
|
|
644
|
+
typeAnn.typeParams?.params?.[0],
|
|
645
|
+
typeAnn.typeParams?.[0],
|
|
646
|
+
typeAnn.params?.[0],
|
|
647
|
+
typeAnn.args?.[0],
|
|
648
|
+
typeAnn.typeParameters, // fallback if it's directly the literal
|
|
649
|
+
typeAnn.typeArguments,
|
|
650
|
+
typeAnn.typeParams,
|
|
651
|
+
];
|
|
652
|
+
let tp;
|
|
653
|
+
for (const c of candidates) {
|
|
654
|
+
if (c) {
|
|
655
|
+
tp = c;
|
|
656
|
+
break;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
const ns = extractStringLiteralValue(tp);
|
|
660
|
+
// Extract the second type parameter for KPrefix
|
|
661
|
+
// We need to find the second element from the same type parameter list
|
|
662
|
+
const typeParams = typeAnn.typeParameters?.params ??
|
|
663
|
+
typeAnn.typeArguments?.params ??
|
|
664
|
+
typeAnn.typeParams?.params ??
|
|
665
|
+
undefined;
|
|
666
|
+
let kpFromType;
|
|
667
|
+
if (typeParams && typeParams.length >= 2) {
|
|
668
|
+
kpFromType = extractStringLiteralValue(typeParams[1]);
|
|
669
|
+
}
|
|
670
|
+
if (ns || kpFromType) {
|
|
671
|
+
this.scopeManager.setVarInScope(paramKey, {
|
|
672
|
+
defaultNs: ns,
|
|
673
|
+
keyPrefix: kpFromType // honour TFunction<Ns, KPrefix>
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Find the raw type node of a named member on an object-shaped type
|
|
681
|
+
* annotation (inline `{ t: TFunction<'ns'> }` or a local interface / type
|
|
682
|
+
* alias name).
|
|
683
|
+
*/
|
|
684
|
+
getMemberTypeNode(tsType, memberName) {
|
|
685
|
+
if (!tsType)
|
|
686
|
+
return undefined;
|
|
687
|
+
let members;
|
|
688
|
+
if (tsType.type === 'TsTypeLiteral')
|
|
689
|
+
members = tsType.members;
|
|
690
|
+
else if (tsType.type === 'TsTypeReference' && tsType.typeName?.type === 'Identifier') {
|
|
691
|
+
members = this.expressionResolver.getObjectTypeMembersRaw(tsType.typeName.value);
|
|
692
|
+
}
|
|
693
|
+
if (!Array.isArray(members))
|
|
694
|
+
return undefined;
|
|
695
|
+
for (const m of members) {
|
|
696
|
+
if (m?.type !== 'TsPropertySignature')
|
|
697
|
+
continue;
|
|
698
|
+
const name = m.key?.type === 'Identifier' || m.key?.type === 'StringLiteral' ? m.key.value : undefined;
|
|
699
|
+
if (name === memberName)
|
|
700
|
+
return m.typeAnnotation?.typeAnnotation ?? m.typeAnnotation;
|
|
701
|
+
}
|
|
702
|
+
return undefined;
|
|
703
|
+
}
|
|
653
704
|
/**
|
|
654
705
|
* If `node` is a call like `ARRAY.map(param => ...)` where ARRAY is a known
|
|
655
706
|
* string-array constant, returns the callback's first parameter name and the
|
|
@@ -312,7 +312,9 @@ function collectCommentTexts(src) {
|
|
|
312
312
|
const commentRegex = /\/\/(.*)|\/\*([\s\S]*?)\*\//g;
|
|
313
313
|
let cmatch;
|
|
314
314
|
while ((cmatch = commentRegex.exec(src)) !== null) {
|
|
315
|
-
|
|
315
|
+
// Strip fenced code blocks (```…```) from doc comments: they are usage
|
|
316
|
+
// examples, not real call sites, and would otherwise pollute the default namespace.
|
|
317
|
+
const content = (cmatch[1] ?? cmatch[2]).replace(/```[\s\S]*?```/g, '');
|
|
316
318
|
const s = content.trim();
|
|
317
319
|
if (s && !seen.has(s)) {
|
|
318
320
|
seen.add(s);
|
|
@@ -30,6 +30,8 @@ class ExpressionResolver {
|
|
|
30
30
|
// type aliases. Maps typeName -> { memberName: possible string values }.
|
|
31
31
|
// e.g. `interface IProps { size: ChangeType }` -> { IProps: { size: ['all','next'] } }
|
|
32
32
|
objectTypeTable = new Map();
|
|
33
|
+
// Raw TS member nodes of local interfaces / object type aliases, keyed by type name.
|
|
34
|
+
objectTypeMembersRaw = new Map();
|
|
33
35
|
// Temporary per-scope bindings for identifiers holding an object-shaped type,
|
|
34
36
|
// e.g. `function f(props: IProps)` -> { props: { size: ['all','next'] } }.
|
|
35
37
|
temporaryObjectVariables = new Map();
|
|
@@ -236,6 +238,7 @@ class ExpressionResolver {
|
|
|
236
238
|
return;
|
|
237
239
|
// `type IProps = { size: ChangeType }` — object shape, not a string union.
|
|
238
240
|
if (tsType.type === 'TsTypeLiteral') {
|
|
241
|
+
this.objectTypeMembersRaw.set(name, tsType.members);
|
|
239
242
|
const members = this.collectObjectTypeMembers(tsType.members);
|
|
240
243
|
if (members)
|
|
241
244
|
this.objectTypeTable.set(name, members);
|
|
@@ -264,6 +267,8 @@ class ExpressionResolver {
|
|
|
264
267
|
const name = node?.id?.type === 'Identifier' ? node.id.value : undefined;
|
|
265
268
|
if (!name)
|
|
266
269
|
return;
|
|
270
|
+
if (Array.isArray(node?.body?.body))
|
|
271
|
+
this.objectTypeMembersRaw.set(name, node.body.body);
|
|
267
272
|
const members = this.collectObjectTypeMembers(node?.body?.body);
|
|
268
273
|
if (members)
|
|
269
274
|
this.objectTypeTable.set(name, members);
|
|
@@ -300,6 +305,9 @@ class ExpressionResolver {
|
|
|
300
305
|
* Resolve a type annotation that refers to an object shape (interface, object
|
|
301
306
|
* type alias, or inline type literal) to its member → string values map.
|
|
302
307
|
*/
|
|
308
|
+
getObjectTypeMembersRaw(name) {
|
|
309
|
+
return this.objectTypeMembersRaw.get(name);
|
|
310
|
+
}
|
|
303
311
|
resolveTypeMembers(tsType) {
|
|
304
312
|
try {
|
|
305
313
|
if (!tsType)
|
|
@@ -267,6 +267,17 @@ class ScopeManager {
|
|
|
267
267
|
}
|
|
268
268
|
// continue processing; still may be a useTranslation/getFixedT call below
|
|
269
269
|
}
|
|
270
|
+
// Handle: const t = useCallback((key, opts) => tLocal(key, opts), [...]) OR
|
|
271
|
+
// const t = (key, opts) => tLocal(key, opts)
|
|
272
|
+
// A wrapper that forwards its first parameter as the key to an already-scoped
|
|
273
|
+
// translation function inherits that function's scope.
|
|
274
|
+
if (node.id.type === 'Identifier') {
|
|
275
|
+
const wrapped = this.resolveDelegatingWrapperScope(init);
|
|
276
|
+
if (wrapped) {
|
|
277
|
+
this.setVarInScope(node.id.value, wrapped);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
270
281
|
// Handle: const { t } = this.#field OR const { t } = this.#field()
|
|
271
282
|
// Resolve the source `this.<field>` to its previously-registered ScopeInfo
|
|
272
283
|
// and propagate it onto the destructured variables.
|
|
@@ -550,6 +561,12 @@ class ScopeManager {
|
|
|
550
561
|
return { defaultNs: this.resolveSimpleStringIdentifier(nsNode.value) };
|
|
551
562
|
if (nsNode.type === 'MemberExpression')
|
|
552
563
|
return { defaultNs: this.resolveSimpleMemberExpression(nsNode) };
|
|
564
|
+
// `useTranslation(ns ?? 'fallback')` / `useTranslation(ns || 'fallback')`:
|
|
565
|
+
// prefer a statically resolvable left side, otherwise use the fallback.
|
|
566
|
+
if (nsNode.type === 'BinaryExpression' && (nsNode.operator === '??' || nsNode.operator === '||')) {
|
|
567
|
+
const left = this.resolveNsArg(nsNode.left);
|
|
568
|
+
return left.defaultNs !== undefined ? left : this.resolveNsArg(nsNode.right);
|
|
569
|
+
}
|
|
553
570
|
if (nsNode.type === 'ArrayExpression') {
|
|
554
571
|
const namespaces = [];
|
|
555
572
|
for (const el of nsNode.elements) {
|
|
@@ -573,6 +590,51 @@ class ScopeManager {
|
|
|
573
590
|
}
|
|
574
591
|
return {};
|
|
575
592
|
}
|
|
593
|
+
/**
|
|
594
|
+
* If `init` is a function (optionally wrapped in `useCallback(fn, deps)`) whose
|
|
595
|
+
* first parameter is passed as the first argument to a call of an already-scoped
|
|
596
|
+
* variable (e.g. `tLocal(key, opts)`), return that variable's ScopeInfo.
|
|
597
|
+
*/
|
|
598
|
+
resolveDelegatingWrapperScope(init) {
|
|
599
|
+
let fn = ScopeManager.unwrapTsExpression(init);
|
|
600
|
+
if (fn?.type === 'CallExpression' && fn.callee?.type === 'Identifier' && fn.callee.value === 'useCallback') {
|
|
601
|
+
fn = fn.arguments?.[0]?.expression;
|
|
602
|
+
}
|
|
603
|
+
if (fn?.type !== 'ArrowFunctionExpression' && fn?.type !== 'FunctionExpression')
|
|
604
|
+
return undefined;
|
|
605
|
+
const first = fn.params?.[0];
|
|
606
|
+
const pat = first?.pat ?? first;
|
|
607
|
+
const keyParam = pat?.type === 'Identifier' ? pat.value : undefined;
|
|
608
|
+
if (!keyParam)
|
|
609
|
+
return undefined;
|
|
610
|
+
let found;
|
|
611
|
+
const visit = (n) => {
|
|
612
|
+
if (found || !n || typeof n !== 'object')
|
|
613
|
+
return;
|
|
614
|
+
if (Array.isArray(n)) {
|
|
615
|
+
for (const c of n)
|
|
616
|
+
visit(c);
|
|
617
|
+
return;
|
|
618
|
+
}
|
|
619
|
+
if (n.type === 'CallExpression' &&
|
|
620
|
+
n.callee?.type === 'Identifier' &&
|
|
621
|
+
n.arguments?.[0]?.expression?.type === 'Identifier' &&
|
|
622
|
+
n.arguments[0].expression.value === keyParam) {
|
|
623
|
+
const scope = this.getVarFromScope(n.callee.value);
|
|
624
|
+
if (scope) {
|
|
625
|
+
found = scope;
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
for (const k of Object.keys(n)) {
|
|
630
|
+
if (k === 'span')
|
|
631
|
+
continue;
|
|
632
|
+
visit(n[k]);
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
visit(fn.body);
|
|
636
|
+
return found;
|
|
637
|
+
}
|
|
576
638
|
resolveStringArg(node) {
|
|
577
639
|
if (!node)
|
|
578
640
|
return undefined;
|
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.
|
|
34
|
+
.version('1.70.1'); // 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
|
|
@@ -228,22 +228,24 @@ class ASTVisitors {
|
|
|
228
228
|
if (pat.type === 'ObjectPattern') {
|
|
229
229
|
const patType = pat.typeAnnotation?.typeAnnotation ?? pat.typeAnnotation;
|
|
230
230
|
const members = this.expressionResolver.resolveTypeMembers(patType);
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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)
|
|
240
|
+
continue;
|
|
241
|
+
// `({ t }: { t: TFunction<'ns'> })` → bind `t` to that namespace
|
|
242
|
+
this.bindTFunctionParam(localName, this.getMemberTypeNode(patType, memberName));
|
|
243
|
+
if (!members?.[memberName])
|
|
244
|
+
continue;
|
|
245
|
+
this.expressionResolver.setTemporaryVariable(localName, members[memberName]);
|
|
246
|
+
if (!paramTemporaries)
|
|
247
|
+
paramTemporaries = [];
|
|
248
|
+
paramTemporaries.push(localName);
|
|
247
249
|
}
|
|
248
250
|
continue;
|
|
249
251
|
}
|
|
@@ -290,103 +292,7 @@ class ASTVisitors {
|
|
|
290
292
|
else {
|
|
291
293
|
typeAnn = undefined;
|
|
292
294
|
}
|
|
293
|
-
|
|
294
|
-
const extractTypeName = (ta) => {
|
|
295
|
-
if (!ta)
|
|
296
|
-
return undefined;
|
|
297
|
-
// Identifier style: { type: 'Identifier', value: 'TFunction' } OR { name: 'TFunction' }
|
|
298
|
-
if (ta.typeName && (ta.typeName.type === 'Identifier'))
|
|
299
|
-
return ta.typeName.value ?? ta.typeName.name;
|
|
300
|
-
if (ta.typeName && ta.typeName.type === 'TsQualifiedName') {
|
|
301
|
-
// Qualified like Foo.TFunction -> try right side
|
|
302
|
-
const right = (ta.typeName.right ?? ta.typeName);
|
|
303
|
-
return right?.value ?? right?.name;
|
|
304
|
-
}
|
|
305
|
-
if (ta.typeName && typeof ta.typeName === 'string')
|
|
306
|
-
return ta.typeName;
|
|
307
|
-
if (ta.type === 'Identifier')
|
|
308
|
-
return ta.value ?? ta.name;
|
|
309
|
-
if (ta.id)
|
|
310
|
-
return ta.id?.value ?? ta.id?.name ?? ta.id;
|
|
311
|
-
return undefined;
|
|
312
|
-
};
|
|
313
|
-
const extractStringLiteralValue = (node) => {
|
|
314
|
-
if (!node)
|
|
315
|
-
return undefined;
|
|
316
|
-
// Handle: typeof SomeConst → TsTypeQuery { exprName: { value: 'SomeConst' } }
|
|
317
|
-
if (node?.type === 'TsTypeQuery') {
|
|
318
|
-
const name = node.exprName?.value ?? node.exprName?.name;
|
|
319
|
-
if (name)
|
|
320
|
-
return this.scopeManager.resolveSimpleStringIdentifier(name);
|
|
321
|
-
}
|
|
322
|
-
// shapes: TsLiteralType -> { literal: { type: 'StringLiteral', value: 'x' } }
|
|
323
|
-
if (node.type === 'TsLiteralType' && node.literal)
|
|
324
|
-
return node.literal.value ?? node.literal.raw;
|
|
325
|
-
if (node.type === 'StringLiteral' || node.type === 'Str' || node.type === 'Literal')
|
|
326
|
-
return node.value ?? node.raw ?? node.value;
|
|
327
|
-
if (node.literal && (node.literal.type === 'StringLiteral' || node.literal.type === 'Str'))
|
|
328
|
-
return node.literal.value;
|
|
329
|
-
// some SWC builds put the string directly on .value
|
|
330
|
-
if (typeof node.value === 'string')
|
|
331
|
-
return node.value;
|
|
332
|
-
// handle wrapped parameter like { params: [ ... ] } where a literal might be one level deeper
|
|
333
|
-
if (node.params && Array.isArray(node.params) && node.params[0])
|
|
334
|
-
return extractStringLiteralValue(node.params[0]);
|
|
335
|
-
if (node.typeArguments && Array.isArray(node.typeArguments) && node.typeArguments[0])
|
|
336
|
-
return extractStringLiteralValue(node.typeArguments[0]);
|
|
337
|
-
if (node.typeParameters && Array.isArray(node.typeParameters) && node.typeParameters[0])
|
|
338
|
-
return extractStringLiteralValue(node.typeParameters[0]);
|
|
339
|
-
if (node.typeParams && Array.isArray(node.typeParams) && node.typeParams[0])
|
|
340
|
-
return extractStringLiteralValue(node.typeParams[0]);
|
|
341
|
-
return undefined;
|
|
342
|
-
};
|
|
343
|
-
// Detect TsTypeReference like: TFunction<"my-custom-namespace">
|
|
344
|
-
if (typeAnn && (typeAnn.type === 'TsTypeReference' || typeAnn.type === 'TsTypeRef' || typeAnn.type === 'TsTypeReference')) {
|
|
345
|
-
const finalTypeName = extractTypeName(typeAnn);
|
|
346
|
-
if (finalTypeName === 'TFunction') {
|
|
347
|
-
// support multiple AST shapes for type parameters:
|
|
348
|
-
// - typeAnn.typeParameters?.params?.[0]
|
|
349
|
-
// - typeAnn.typeArguments?.params?.[0]
|
|
350
|
-
// - typeAnn.typeParams?.[0] / typeAnn.params?.[0]
|
|
351
|
-
const candidates = [
|
|
352
|
-
typeAnn.typeParameters?.params?.[0],
|
|
353
|
-
typeAnn.typeParameters?.[0],
|
|
354
|
-
typeAnn.typeArguments?.params?.[0],
|
|
355
|
-
typeAnn.typeArguments?.[0],
|
|
356
|
-
typeAnn.typeParams?.params?.[0],
|
|
357
|
-
typeAnn.typeParams?.[0],
|
|
358
|
-
typeAnn.params?.[0],
|
|
359
|
-
typeAnn.args?.[0],
|
|
360
|
-
typeAnn.typeParameters, // fallback if it's directly the literal
|
|
361
|
-
typeAnn.typeArguments,
|
|
362
|
-
typeAnn.typeParams,
|
|
363
|
-
];
|
|
364
|
-
let tp;
|
|
365
|
-
for (const c of candidates) {
|
|
366
|
-
if (c) {
|
|
367
|
-
tp = c;
|
|
368
|
-
break;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
const ns = extractStringLiteralValue(tp);
|
|
372
|
-
// Extract the second type parameter for KPrefix
|
|
373
|
-
// We need to find the second element from the same type parameter list
|
|
374
|
-
const typeParams = typeAnn.typeParameters?.params ??
|
|
375
|
-
typeAnn.typeArguments?.params ??
|
|
376
|
-
typeAnn.typeParams?.params ??
|
|
377
|
-
undefined;
|
|
378
|
-
let kpFromType;
|
|
379
|
-
if (typeParams && typeParams.length >= 2) {
|
|
380
|
-
kpFromType = extractStringLiteralValue(typeParams[1]);
|
|
381
|
-
}
|
|
382
|
-
if (ns || kpFromType) {
|
|
383
|
-
this.scopeManager.setVarInScope(paramKey, {
|
|
384
|
-
defaultNs: ns,
|
|
385
|
-
keyPrefix: kpFromType // honour TFunction<Ns, KPrefix>
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
295
|
+
this.bindTFunctionParam(paramKey, typeAnn);
|
|
390
296
|
// Capture parameter type annotations as temporary variables in the
|
|
391
297
|
// expression resolver so that dynamic bracket expressions like
|
|
392
298
|
// `t(($) => $.table.columns[field])` can resolve `field` to its
|
|
@@ -648,6 +554,151 @@ class ASTVisitors {
|
|
|
648
554
|
this.scopeManager.exitClassScope();
|
|
649
555
|
}
|
|
650
556
|
}
|
|
557
|
+
/**
|
|
558
|
+
* If `typeAnn` is a `TFunction<Ns, KPrefix>` type reference, register
|
|
559
|
+
* `paramKey` in the current scope with that namespace / keyPrefix.
|
|
560
|
+
*/
|
|
561
|
+
bindTFunctionParam(paramKey, typeAnn) {
|
|
562
|
+
// Small helpers to robustly extract the referenced type name and literal string
|
|
563
|
+
const extractTypeName = (ta) => {
|
|
564
|
+
if (!ta)
|
|
565
|
+
return undefined;
|
|
566
|
+
// Identifier style: { type: 'Identifier', value: 'TFunction' } OR { name: 'TFunction' }
|
|
567
|
+
if (ta.typeName && (ta.typeName.type === 'Identifier'))
|
|
568
|
+
return ta.typeName.value ?? ta.typeName.name;
|
|
569
|
+
if (ta.typeName && ta.typeName.type === 'TsQualifiedName') {
|
|
570
|
+
// Qualified like Foo.TFunction -> try right side
|
|
571
|
+
const right = (ta.typeName.right ?? ta.typeName);
|
|
572
|
+
return right?.value ?? right?.name;
|
|
573
|
+
}
|
|
574
|
+
if (ta.typeName && typeof ta.typeName === 'string')
|
|
575
|
+
return ta.typeName;
|
|
576
|
+
if (ta.type === 'Identifier')
|
|
577
|
+
return ta.value ?? ta.name;
|
|
578
|
+
if (ta.id)
|
|
579
|
+
return ta.id?.value ?? ta.id?.name ?? ta.id;
|
|
580
|
+
return undefined;
|
|
581
|
+
};
|
|
582
|
+
const extractStringLiteralValue = (node) => {
|
|
583
|
+
if (!node)
|
|
584
|
+
return undefined;
|
|
585
|
+
// Handle: typeof SomeConst → TsTypeQuery { exprName: { value: 'SomeConst' } }
|
|
586
|
+
if (node?.type === 'TsTypeQuery') {
|
|
587
|
+
const name = node.exprName?.value ?? node.exprName?.name;
|
|
588
|
+
if (name)
|
|
589
|
+
return this.scopeManager.resolveSimpleStringIdentifier(name);
|
|
590
|
+
}
|
|
591
|
+
// shapes: TsLiteralType -> { literal: { type: 'StringLiteral', value: 'x' } }
|
|
592
|
+
if (node.type === 'TsLiteralType' && node.literal)
|
|
593
|
+
return node.literal.value ?? node.literal.raw;
|
|
594
|
+
if (node.type === 'StringLiteral' || node.type === 'Str' || node.type === 'Literal')
|
|
595
|
+
return node.value ?? node.raw ?? node.value;
|
|
596
|
+
if (node.literal && (node.literal.type === 'StringLiteral' || node.literal.type === 'Str'))
|
|
597
|
+
return node.literal.value;
|
|
598
|
+
// some SWC builds put the string directly on .value
|
|
599
|
+
if (typeof node.value === 'string')
|
|
600
|
+
return node.value;
|
|
601
|
+
// handle wrapped parameter like { params: [ ... ] } where a literal might be one level deeper
|
|
602
|
+
if (node.params && Array.isArray(node.params) && node.params[0])
|
|
603
|
+
return extractStringLiteralValue(node.params[0]);
|
|
604
|
+
if (node.typeArguments && Array.isArray(node.typeArguments) && node.typeArguments[0])
|
|
605
|
+
return extractStringLiteralValue(node.typeArguments[0]);
|
|
606
|
+
if (node.typeParameters && Array.isArray(node.typeParameters) && node.typeParameters[0])
|
|
607
|
+
return extractStringLiteralValue(node.typeParameters[0]);
|
|
608
|
+
if (node.typeParams && Array.isArray(node.typeParams) && node.typeParams[0])
|
|
609
|
+
return extractStringLiteralValue(node.typeParams[0]);
|
|
610
|
+
return undefined;
|
|
611
|
+
};
|
|
612
|
+
// `ReturnType<typeof useTranslation<'ns', 'kp'>>['t']` is `TFunction<'ns', 'kp'>` spelled indirectly.
|
|
613
|
+
if (typeAnn?.type === 'TsIndexedAccessType' && extractStringLiteralValue(typeAnn.indexType) === 't') {
|
|
614
|
+
const obj = typeAnn.objectType;
|
|
615
|
+
const query = obj?.type === 'TsTypeReference' && extractTypeName(obj) === 'ReturnType'
|
|
616
|
+
? (obj.typeParams?.params?.[0] ?? obj.typeArguments?.params?.[0])
|
|
617
|
+
: undefined;
|
|
618
|
+
const hookName = query?.type === 'TsTypeQuery' ? (query.exprName?.value ?? query.exprName?.name) : undefined;
|
|
619
|
+
const hookNames = this.config.extract.useTranslationNames || ['useTranslation', 'getT', 'useT'];
|
|
620
|
+
if (hookName && hookNames.some(h => (typeof h === 'string' ? h : h.name) === hookName)) {
|
|
621
|
+
const params = query.typeArguments?.params ?? query.typeArgs?.params ?? [];
|
|
622
|
+
const ns = extractStringLiteralValue(params[0]);
|
|
623
|
+
const kp = extractStringLiteralValue(params[1]);
|
|
624
|
+
if (ns || kp)
|
|
625
|
+
this.scopeManager.setVarInScope(paramKey, { defaultNs: ns, keyPrefix: kp });
|
|
626
|
+
}
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
// Detect TsTypeReference like: TFunction<"my-custom-namespace">
|
|
630
|
+
if (typeAnn && (typeAnn.type === 'TsTypeReference' || typeAnn.type === 'TsTypeRef' || typeAnn.type === 'TsTypeReference')) {
|
|
631
|
+
const finalTypeName = extractTypeName(typeAnn);
|
|
632
|
+
if (finalTypeName === 'TFunction') {
|
|
633
|
+
// support multiple AST shapes for type parameters:
|
|
634
|
+
// - typeAnn.typeParameters?.params?.[0]
|
|
635
|
+
// - typeAnn.typeArguments?.params?.[0]
|
|
636
|
+
// - typeAnn.typeParams?.[0] / typeAnn.params?.[0]
|
|
637
|
+
const candidates = [
|
|
638
|
+
typeAnn.typeParameters?.params?.[0],
|
|
639
|
+
typeAnn.typeParameters?.[0],
|
|
640
|
+
typeAnn.typeArguments?.params?.[0],
|
|
641
|
+
typeAnn.typeArguments?.[0],
|
|
642
|
+
typeAnn.typeParams?.params?.[0],
|
|
643
|
+
typeAnn.typeParams?.[0],
|
|
644
|
+
typeAnn.params?.[0],
|
|
645
|
+
typeAnn.args?.[0],
|
|
646
|
+
typeAnn.typeParameters, // fallback if it's directly the literal
|
|
647
|
+
typeAnn.typeArguments,
|
|
648
|
+
typeAnn.typeParams,
|
|
649
|
+
];
|
|
650
|
+
let tp;
|
|
651
|
+
for (const c of candidates) {
|
|
652
|
+
if (c) {
|
|
653
|
+
tp = c;
|
|
654
|
+
break;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
const ns = extractStringLiteralValue(tp);
|
|
658
|
+
// Extract the second type parameter for KPrefix
|
|
659
|
+
// We need to find the second element from the same type parameter list
|
|
660
|
+
const typeParams = typeAnn.typeParameters?.params ??
|
|
661
|
+
typeAnn.typeArguments?.params ??
|
|
662
|
+
typeAnn.typeParams?.params ??
|
|
663
|
+
undefined;
|
|
664
|
+
let kpFromType;
|
|
665
|
+
if (typeParams && typeParams.length >= 2) {
|
|
666
|
+
kpFromType = extractStringLiteralValue(typeParams[1]);
|
|
667
|
+
}
|
|
668
|
+
if (ns || kpFromType) {
|
|
669
|
+
this.scopeManager.setVarInScope(paramKey, {
|
|
670
|
+
defaultNs: ns,
|
|
671
|
+
keyPrefix: kpFromType // honour TFunction<Ns, KPrefix>
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Find the raw type node of a named member on an object-shaped type
|
|
679
|
+
* annotation (inline `{ t: TFunction<'ns'> }` or a local interface / type
|
|
680
|
+
* alias name).
|
|
681
|
+
*/
|
|
682
|
+
getMemberTypeNode(tsType, memberName) {
|
|
683
|
+
if (!tsType)
|
|
684
|
+
return undefined;
|
|
685
|
+
let members;
|
|
686
|
+
if (tsType.type === 'TsTypeLiteral')
|
|
687
|
+
members = tsType.members;
|
|
688
|
+
else if (tsType.type === 'TsTypeReference' && tsType.typeName?.type === 'Identifier') {
|
|
689
|
+
members = this.expressionResolver.getObjectTypeMembersRaw(tsType.typeName.value);
|
|
690
|
+
}
|
|
691
|
+
if (!Array.isArray(members))
|
|
692
|
+
return undefined;
|
|
693
|
+
for (const m of members) {
|
|
694
|
+
if (m?.type !== 'TsPropertySignature')
|
|
695
|
+
continue;
|
|
696
|
+
const name = m.key?.type === 'Identifier' || m.key?.type === 'StringLiteral' ? m.key.value : undefined;
|
|
697
|
+
if (name === memberName)
|
|
698
|
+
return m.typeAnnotation?.typeAnnotation ?? m.typeAnnotation;
|
|
699
|
+
}
|
|
700
|
+
return undefined;
|
|
701
|
+
}
|
|
651
702
|
/**
|
|
652
703
|
* If `node` is a call like `ARRAY.map(param => ...)` where ARRAY is a known
|
|
653
704
|
* string-array constant, returns the callback's first parameter name and the
|
|
@@ -310,7 +310,9 @@ function collectCommentTexts(src) {
|
|
|
310
310
|
const commentRegex = /\/\/(.*)|\/\*([\s\S]*?)\*\//g;
|
|
311
311
|
let cmatch;
|
|
312
312
|
while ((cmatch = commentRegex.exec(src)) !== null) {
|
|
313
|
-
|
|
313
|
+
// Strip fenced code blocks (```…```) from doc comments: they are usage
|
|
314
|
+
// examples, not real call sites, and would otherwise pollute the default namespace.
|
|
315
|
+
const content = (cmatch[1] ?? cmatch[2]).replace(/```[\s\S]*?```/g, '');
|
|
314
316
|
const s = content.trim();
|
|
315
317
|
if (s && !seen.has(s)) {
|
|
316
318
|
seen.add(s);
|
|
@@ -28,6 +28,8 @@ class ExpressionResolver {
|
|
|
28
28
|
// type aliases. Maps typeName -> { memberName: possible string values }.
|
|
29
29
|
// e.g. `interface IProps { size: ChangeType }` -> { IProps: { size: ['all','next'] } }
|
|
30
30
|
objectTypeTable = new Map();
|
|
31
|
+
// Raw TS member nodes of local interfaces / object type aliases, keyed by type name.
|
|
32
|
+
objectTypeMembersRaw = new Map();
|
|
31
33
|
// Temporary per-scope bindings for identifiers holding an object-shaped type,
|
|
32
34
|
// e.g. `function f(props: IProps)` -> { props: { size: ['all','next'] } }.
|
|
33
35
|
temporaryObjectVariables = new Map();
|
|
@@ -234,6 +236,7 @@ class ExpressionResolver {
|
|
|
234
236
|
return;
|
|
235
237
|
// `type IProps = { size: ChangeType }` — object shape, not a string union.
|
|
236
238
|
if (tsType.type === 'TsTypeLiteral') {
|
|
239
|
+
this.objectTypeMembersRaw.set(name, tsType.members);
|
|
237
240
|
const members = this.collectObjectTypeMembers(tsType.members);
|
|
238
241
|
if (members)
|
|
239
242
|
this.objectTypeTable.set(name, members);
|
|
@@ -262,6 +265,8 @@ class ExpressionResolver {
|
|
|
262
265
|
const name = node?.id?.type === 'Identifier' ? node.id.value : undefined;
|
|
263
266
|
if (!name)
|
|
264
267
|
return;
|
|
268
|
+
if (Array.isArray(node?.body?.body))
|
|
269
|
+
this.objectTypeMembersRaw.set(name, node.body.body);
|
|
265
270
|
const members = this.collectObjectTypeMembers(node?.body?.body);
|
|
266
271
|
if (members)
|
|
267
272
|
this.objectTypeTable.set(name, members);
|
|
@@ -298,6 +303,9 @@ class ExpressionResolver {
|
|
|
298
303
|
* Resolve a type annotation that refers to an object shape (interface, object
|
|
299
304
|
* type alias, or inline type literal) to its member → string values map.
|
|
300
305
|
*/
|
|
306
|
+
getObjectTypeMembersRaw(name) {
|
|
307
|
+
return this.objectTypeMembersRaw.get(name);
|
|
308
|
+
}
|
|
301
309
|
resolveTypeMembers(tsType) {
|
|
302
310
|
try {
|
|
303
311
|
if (!tsType)
|
|
@@ -265,6 +265,17 @@ class ScopeManager {
|
|
|
265
265
|
}
|
|
266
266
|
// continue processing; still may be a useTranslation/getFixedT call below
|
|
267
267
|
}
|
|
268
|
+
// Handle: const t = useCallback((key, opts) => tLocal(key, opts), [...]) OR
|
|
269
|
+
// const t = (key, opts) => tLocal(key, opts)
|
|
270
|
+
// A wrapper that forwards its first parameter as the key to an already-scoped
|
|
271
|
+
// translation function inherits that function's scope.
|
|
272
|
+
if (node.id.type === 'Identifier') {
|
|
273
|
+
const wrapped = this.resolveDelegatingWrapperScope(init);
|
|
274
|
+
if (wrapped) {
|
|
275
|
+
this.setVarInScope(node.id.value, wrapped);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
268
279
|
// Handle: const { t } = this.#field OR const { t } = this.#field()
|
|
269
280
|
// Resolve the source `this.<field>` to its previously-registered ScopeInfo
|
|
270
281
|
// and propagate it onto the destructured variables.
|
|
@@ -548,6 +559,12 @@ class ScopeManager {
|
|
|
548
559
|
return { defaultNs: this.resolveSimpleStringIdentifier(nsNode.value) };
|
|
549
560
|
if (nsNode.type === 'MemberExpression')
|
|
550
561
|
return { defaultNs: this.resolveSimpleMemberExpression(nsNode) };
|
|
562
|
+
// `useTranslation(ns ?? 'fallback')` / `useTranslation(ns || 'fallback')`:
|
|
563
|
+
// prefer a statically resolvable left side, otherwise use the fallback.
|
|
564
|
+
if (nsNode.type === 'BinaryExpression' && (nsNode.operator === '??' || nsNode.operator === '||')) {
|
|
565
|
+
const left = this.resolveNsArg(nsNode.left);
|
|
566
|
+
return left.defaultNs !== undefined ? left : this.resolveNsArg(nsNode.right);
|
|
567
|
+
}
|
|
551
568
|
if (nsNode.type === 'ArrayExpression') {
|
|
552
569
|
const namespaces = [];
|
|
553
570
|
for (const el of nsNode.elements) {
|
|
@@ -571,6 +588,51 @@ class ScopeManager {
|
|
|
571
588
|
}
|
|
572
589
|
return {};
|
|
573
590
|
}
|
|
591
|
+
/**
|
|
592
|
+
* If `init` is a function (optionally wrapped in `useCallback(fn, deps)`) whose
|
|
593
|
+
* first parameter is passed as the first argument to a call of an already-scoped
|
|
594
|
+
* variable (e.g. `tLocal(key, opts)`), return that variable's ScopeInfo.
|
|
595
|
+
*/
|
|
596
|
+
resolveDelegatingWrapperScope(init) {
|
|
597
|
+
let fn = ScopeManager.unwrapTsExpression(init);
|
|
598
|
+
if (fn?.type === 'CallExpression' && fn.callee?.type === 'Identifier' && fn.callee.value === 'useCallback') {
|
|
599
|
+
fn = fn.arguments?.[0]?.expression;
|
|
600
|
+
}
|
|
601
|
+
if (fn?.type !== 'ArrowFunctionExpression' && fn?.type !== 'FunctionExpression')
|
|
602
|
+
return undefined;
|
|
603
|
+
const first = fn.params?.[0];
|
|
604
|
+
const pat = first?.pat ?? first;
|
|
605
|
+
const keyParam = pat?.type === 'Identifier' ? pat.value : undefined;
|
|
606
|
+
if (!keyParam)
|
|
607
|
+
return undefined;
|
|
608
|
+
let found;
|
|
609
|
+
const visit = (n) => {
|
|
610
|
+
if (found || !n || typeof n !== 'object')
|
|
611
|
+
return;
|
|
612
|
+
if (Array.isArray(n)) {
|
|
613
|
+
for (const c of n)
|
|
614
|
+
visit(c);
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
if (n.type === 'CallExpression' &&
|
|
618
|
+
n.callee?.type === 'Identifier' &&
|
|
619
|
+
n.arguments?.[0]?.expression?.type === 'Identifier' &&
|
|
620
|
+
n.arguments[0].expression.value === keyParam) {
|
|
621
|
+
const scope = this.getVarFromScope(n.callee.value);
|
|
622
|
+
if (scope) {
|
|
623
|
+
found = scope;
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
for (const k of Object.keys(n)) {
|
|
628
|
+
if (k === 'span')
|
|
629
|
+
continue;
|
|
630
|
+
visit(n[k]);
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
visit(fn.body);
|
|
634
|
+
return found;
|
|
635
|
+
}
|
|
574
636
|
resolveStringArg(node) {
|
|
575
637
|
if (!node)
|
|
576
638
|
return undefined;
|
package/package.json
CHANGED
|
@@ -85,6 +85,17 @@ export declare class ASTVisitors {
|
|
|
85
85
|
* @private
|
|
86
86
|
*/
|
|
87
87
|
private walk;
|
|
88
|
+
/**
|
|
89
|
+
* If `typeAnn` is a `TFunction<Ns, KPrefix>` type reference, register
|
|
90
|
+
* `paramKey` in the current scope with that namespace / keyPrefix.
|
|
91
|
+
*/
|
|
92
|
+
private bindTFunctionParam;
|
|
93
|
+
/**
|
|
94
|
+
* Find the raw type node of a named member on an object-shaped type
|
|
95
|
+
* annotation (inline `{ t: TFunction<'ns'> }` or a local interface / type
|
|
96
|
+
* alias name).
|
|
97
|
+
*/
|
|
98
|
+
private getMemberTypeNode;
|
|
88
99
|
/**
|
|
89
100
|
* If `node` is a call like `ARRAY.map(param => ...)` where ARRAY is a known
|
|
90
101
|
* string-array constant, returns the callback's first parameter name and the
|
|
@@ -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;IAqDzB;;;;;OAKG;IACI,KAAK,CAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAUjC;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,IAAI;
|
|
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;IAoYZ;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAyG1B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAgBzB;;;;;;;;OAQG;IACH,OAAO,CAAC,gCAAgC;IAqDxC;;;;;;;;;OASG;IACH,OAAO,CAAC,0BAA0B;IA+ClC;;;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"}
|
|
@@ -10,6 +10,7 @@ export declare class ExpressionResolver {
|
|
|
10
10
|
private sharedFunctionReturnTable;
|
|
11
11
|
private temporaryVariables;
|
|
12
12
|
private objectTypeTable;
|
|
13
|
+
private objectTypeMembersRaw;
|
|
13
14
|
private temporaryObjectVariables;
|
|
14
15
|
private arrayElementMembers;
|
|
15
16
|
constructor(hooks: ASTVisitorHooks);
|
|
@@ -55,6 +56,7 @@ export declare class ExpressionResolver {
|
|
|
55
56
|
* Resolve a type annotation that refers to an object shape (interface, object
|
|
56
57
|
* type alias, or inline type literal) to its member → string values map.
|
|
57
58
|
*/
|
|
59
|
+
getObjectTypeMembersRaw(name: string): any[] | undefined;
|
|
58
60
|
resolveTypeMembers(tsType: any): Record<string, string[]> | undefined;
|
|
59
61
|
/**
|
|
60
62
|
* Resolve a type annotation for an array of an object shape (`IProps[]`,
|
|
@@ -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;IAK7D,OAAO,CAAC,eAAe,CAAmD;
|
|
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;IAE1E,OAAO,CAAC,oBAAoB,CAAgC;IAI5D,OAAO,CAAC,wBAAwB,CAAmD;IAKnF,OAAO,CAAC,mBAAmB,CAAmD;gBAEjE,KAAK,EAAE,eAAe;IAInC;;OAEG;IACI,gBAAgB,IAAK,IAAI;IAOhC;;;;;;;;;OASG;IACH,yBAAyB,CAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAmK3C;;;;;;;OAOG;IACH,2BAA2B,CAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAyB7C;;;;;;OAMG;IACH,2BAA2B,CAAE,IAAI,EAAE,GAAG,GAAG,IAAI;IAY7C;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAehC;;;OAGG;IACI,uBAAuB,CAAE,IAAI,EAAE,MAAM,GAAG,GAAG,EAAE,GAAG,SAAS;IAIzD,kBAAkB,CAAE,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS;IAa7E;;;;OAIG;IACI,0BAA0B,CAAE,MAAM,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS;IAgBrF;;;OAGG;IACI,sBAAsB,CAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI;IAI9E,sBAAsB,CAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS;IAI3E,yBAAyB,CAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIrD;;;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;IA8CzC;;;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"}
|
|
@@ -161,6 +161,12 @@ export declare class ScopeManager {
|
|
|
161
161
|
* either single form behaves identically downstream.
|
|
162
162
|
*/
|
|
163
163
|
private resolveNsArg;
|
|
164
|
+
/**
|
|
165
|
+
* If `init` is a function (optionally wrapped in `useCallback(fn, deps)`) whose
|
|
166
|
+
* first parameter is passed as the first argument to a call of an already-scoped
|
|
167
|
+
* variable (e.g. `tLocal(key, opts)`), return that variable's ScopeInfo.
|
|
168
|
+
*/
|
|
169
|
+
private resolveDelegatingWrapperScope;
|
|
164
170
|
private resolveStringArg;
|
|
165
171
|
/**
|
|
166
172
|
* Handles cases where a getFixedT-like function is a variable (from a custom hook)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope-manager.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/scope-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAEV,kBAAkB,EAMnB,MAAM,WAAW,CAAA;AAClB,OAAO,KAAK,EAAE,SAAS,EAA4B,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAG/F,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,KAAK,CAAqE;IAMlF,OAAO,CAAC,cAAc,CAAoC;IAG1D,OAAO,CAAC,eAAe,CAAiC;IAGxD,OAAO,CAAC,qBAAqB,CAAiD;IAI9E,OAAO,CAAC,eAAe,CAAiC;IACxD,OAAO,CAAC,qBAAqB,CAAiD;gBAEjE,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC;IAI1D;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAcjC;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,+BAA+B;IAgB9C;;;;;;OAMG;IACI,KAAK,IAAK,IAAI;IAQrB;;;;OAIG;IACH,eAAe,IAAK,IAAI;IAIxB;;;OAGG;IACH,cAAc,IAAK,IAAI;IAIvB;;;;;;;OAOG;IACH,YAAY,CAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAMvD;;;;;OAKG;IACH,YAAY,CAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IASvD;;;OAGG;IACH,UAAU,IAAK,IAAI;IAInB;;;OAGG;IACH,SAAS,IAAK,IAAI;IAIlB;;;;;;OAMG;IACH,aAAa,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAUnD;;;;;;OAMG;IACH,eAAe,CAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAkBrD,OAAO,CAAC,uBAAuB;IAoB/B;;OAEG;IACI,6BAA6B,CAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIvE;;;OAGG;IACH,OAAO,CAAC,6BAA6B;IAqBrC;;;;;;;;;;OAUG;IACH,wBAAwB,CAAE,IAAI,EAAE,kBAAkB,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"scope-manager.d.ts","sourceRoot":"","sources":["../../../src/extractor/parsers/scope-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAEV,kBAAkB,EAMnB,MAAM,WAAW,CAAA;AAClB,OAAO,KAAK,EAAE,SAAS,EAA4B,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAG/F,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,KAAK,CAAqE;IAMlF,OAAO,CAAC,cAAc,CAAoC;IAG1D,OAAO,CAAC,eAAe,CAAiC;IAGxD,OAAO,CAAC,qBAAqB,CAAiD;IAI9E,OAAO,CAAC,eAAe,CAAiC;IACxD,OAAO,CAAC,qBAAqB,CAAiD;gBAEjE,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC;IAI1D;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAcjC;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAC,+BAA+B;IAgB9C;;;;;;OAMG;IACI,KAAK,IAAK,IAAI;IAQrB;;;;OAIG;IACH,eAAe,IAAK,IAAI;IAIxB;;;OAGG;IACH,cAAc,IAAK,IAAI;IAIvB;;;;;;;OAOG;IACH,YAAY,CAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAMvD;;;;;OAKG;IACH,YAAY,CAAE,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IASvD;;;OAGG;IACH,UAAU,IAAK,IAAI;IAInB;;;OAGG;IACH,SAAS,IAAK,IAAI;IAIlB;;;;;;OAMG;IACH,aAAa,CAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAUnD;;;;;;OAMG;IACH,eAAe,CAAE,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAkBrD,OAAO,CAAC,uBAAuB;IAoB/B;;OAEG;IACI,6BAA6B,CAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIvE;;;OAGG;IACH,OAAO,CAAC,6BAA6B;IAqBrC;;;;;;;;;;OAUG;IACH,wBAAwB,CAAE,IAAI,EAAE,kBAAkB,GAAG,IAAI;IAkHzD;;;;;;;;OAQG;IACH,OAAO,CAAC,+BAA+B;IA8FvC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,8BAA8B;IA0EtC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,yBAAyB;IAiBjC;;;;;;OAMG;IACH;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,YAAY;IA8BpB;;;;OAIG;IACH,OAAO,CAAC,6BAA6B;IAiCrC,OAAO,CAAC,gBAAgB;IAexB;;;;;;;;;OASG;IACH,OAAO,CAAC,qCAAqC;IAqB7C;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAgBnC;;;OAGG;IACH,OAAO,CAAC,6BAA6B;IAyBrC;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI;IAwBlF;;;;;OAKG;IACH,OAAO,CAAC,4BAA4B;CA+DrC"}
|