fimo 0.7.0-experimental.10 → 0.7.0-experimental.11
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/cli/bundle.json +1 -1
- package/dist/cli/index.js +93 -12
- package/dist/scripts/extract-translations.js +4 -4
- package/dist/scripts/extract-translations.test.js +38 -0
- package/dist/scripts/i18n-namespace.d.ts +9 -7
- package/dist/scripts/i18n-namespace.js +115 -13
- package/dist/scripts/scan-wrappable.js +7 -2
- package/package.json +1 -1
- package/templates/react-router/package.json +1 -1
package/dist/cli/bundle.json
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -46647,6 +46647,60 @@ var init_staged_labels = __esm({
|
|
|
46647
46647
|
});
|
|
46648
46648
|
|
|
46649
46649
|
// src/scripts/i18n-namespace.ts
|
|
46650
|
+
function translationCallNamespace(node) {
|
|
46651
|
+
if (node?.type !== "CallExpression" || node.callee?.type !== "Identifier") {
|
|
46652
|
+
return null;
|
|
46653
|
+
}
|
|
46654
|
+
if (node.callee.name !== "useTranslations" && node.callee.name !== "getTranslations") {
|
|
46655
|
+
return null;
|
|
46656
|
+
}
|
|
46657
|
+
const arg = node.arguments?.[0];
|
|
46658
|
+
if (!arg) {
|
|
46659
|
+
return "";
|
|
46660
|
+
}
|
|
46661
|
+
if (arg.type === "Literal" && typeof arg.value === "string") {
|
|
46662
|
+
return arg.value;
|
|
46663
|
+
}
|
|
46664
|
+
if (arg.type === "ObjectExpression") {
|
|
46665
|
+
for (const prop2 of arg.properties ?? []) {
|
|
46666
|
+
const keyName = prop2?.key?.name ?? prop2?.key?.value;
|
|
46667
|
+
if (keyName === "namespace" && prop2.value?.type === "Literal" && typeof prop2.value.value === "string") {
|
|
46668
|
+
return prop2.value.value;
|
|
46669
|
+
}
|
|
46670
|
+
}
|
|
46671
|
+
}
|
|
46672
|
+
return "";
|
|
46673
|
+
}
|
|
46674
|
+
function markParamBindings(node, bindings) {
|
|
46675
|
+
if (!node) {
|
|
46676
|
+
return;
|
|
46677
|
+
}
|
|
46678
|
+
switch (node.type) {
|
|
46679
|
+
case "Identifier":
|
|
46680
|
+
if (!bindings.has(node.name)) {
|
|
46681
|
+
bindings.set(node.name, null);
|
|
46682
|
+
}
|
|
46683
|
+
break;
|
|
46684
|
+
case "AssignmentPattern":
|
|
46685
|
+
markParamBindings(node.left, bindings);
|
|
46686
|
+
break;
|
|
46687
|
+
case "RestElement":
|
|
46688
|
+
markParamBindings(node.argument, bindings);
|
|
46689
|
+
break;
|
|
46690
|
+
case "ArrayPattern":
|
|
46691
|
+
for (const element of node.elements ?? []) {
|
|
46692
|
+
markParamBindings(element, bindings);
|
|
46693
|
+
}
|
|
46694
|
+
break;
|
|
46695
|
+
case "ObjectPattern":
|
|
46696
|
+
for (const prop2 of node.properties ?? []) {
|
|
46697
|
+
markParamBindings(prop2.type === "RestElement" ? prop2.argument : prop2.value, bindings);
|
|
46698
|
+
}
|
|
46699
|
+
break;
|
|
46700
|
+
default:
|
|
46701
|
+
break;
|
|
46702
|
+
}
|
|
46703
|
+
}
|
|
46650
46704
|
function collectScopedBindings(fnNode) {
|
|
46651
46705
|
const bindings = /* @__PURE__ */ new Map();
|
|
46652
46706
|
const body = fnNode.body;
|
|
@@ -46656,32 +46710,56 @@ function collectScopedBindings(fnNode) {
|
|
|
46656
46710
|
continue;
|
|
46657
46711
|
}
|
|
46658
46712
|
for (const decl of stmt.declarations ?? []) {
|
|
46659
|
-
|
|
46713
|
+
const init = unwrapAwait(decl?.init);
|
|
46714
|
+
if (decl?.id?.type === "Identifier") {
|
|
46715
|
+
const namespace = translationCallNamespace(init);
|
|
46716
|
+
if (namespace !== null) {
|
|
46717
|
+
bindings.set(decl.id.name, namespace);
|
|
46718
|
+
}
|
|
46660
46719
|
continue;
|
|
46661
46720
|
}
|
|
46662
|
-
|
|
46663
|
-
|
|
46664
|
-
const
|
|
46665
|
-
const
|
|
46666
|
-
|
|
46721
|
+
if (decl?.id?.type === "ArrayPattern") {
|
|
46722
|
+
const source = init?.type === "CallExpression" && init.callee?.type === "Identifier" && init.callee.name === "use" ? unwrapAwait(init.arguments?.[0]) : init;
|
|
46723
|
+
const promiseAll = source?.type === "CallExpression" && source.callee?.type === "MemberExpression" && source.callee.object?.name === "Promise" && source.callee.property?.name === "all";
|
|
46724
|
+
const elements = promiseAll ? source.arguments?.[0]?.type === "ArrayExpression" ? source.arguments[0].elements : null : source?.type === "ArrayExpression" ? source.elements : null;
|
|
46725
|
+
if (elements) {
|
|
46726
|
+
decl.id.elements?.forEach((el, index2) => {
|
|
46727
|
+
if (el?.type !== "Identifier") {
|
|
46728
|
+
return;
|
|
46729
|
+
}
|
|
46730
|
+
const namespace = translationCallNamespace(unwrapAwait(elements[index2]));
|
|
46731
|
+
if (namespace !== null) {
|
|
46732
|
+
bindings.set(el.name, namespace);
|
|
46733
|
+
}
|
|
46734
|
+
});
|
|
46735
|
+
}
|
|
46667
46736
|
}
|
|
46668
46737
|
}
|
|
46669
46738
|
}
|
|
46739
|
+
for (const param of fnNode.params ?? []) {
|
|
46740
|
+
markParamBindings(param, bindings);
|
|
46741
|
+
}
|
|
46670
46742
|
return bindings;
|
|
46671
46743
|
}
|
|
46672
46744
|
function resolveScopedKey(calleeName, leafKey, scopes) {
|
|
46673
46745
|
for (let i = scopes.length - 1; i >= 0; i -= 1) {
|
|
46674
46746
|
if (scopes[i].has(calleeName)) {
|
|
46675
46747
|
const namespace = scopes[i].get(calleeName);
|
|
46676
|
-
|
|
46748
|
+
if (namespace === null || namespace === void 0) {
|
|
46749
|
+
return { key: leafKey, scoped: false, unresolvable: true };
|
|
46750
|
+
}
|
|
46751
|
+
return { key: namespace ? `${namespace}.${leafKey}` : leafKey, scoped: true, unresolvable: false };
|
|
46677
46752
|
}
|
|
46678
46753
|
}
|
|
46679
|
-
return { key: leafKey, scoped: false };
|
|
46754
|
+
return { key: leafKey, scoped: false, unresolvable: false };
|
|
46680
46755
|
}
|
|
46681
|
-
var isFunctionLike;
|
|
46756
|
+
var isFunctionLike, unwrapAwait;
|
|
46682
46757
|
var init_i18n_namespace = __esm({
|
|
46683
46758
|
"src/scripts/i18n-namespace.ts"() {
|
|
46684
46759
|
isFunctionLike = /* @__PURE__ */ __name((node) => node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression", "isFunctionLike");
|
|
46760
|
+
unwrapAwait = /* @__PURE__ */ __name((node) => node?.type === "AwaitExpression" ? node.argument : node, "unwrapAwait");
|
|
46761
|
+
__name(translationCallNamespace, "translationCallNamespace");
|
|
46762
|
+
__name(markParamBindings, "markParamBindings");
|
|
46685
46763
|
__name(collectScopedBindings, "collectScopedBindings");
|
|
46686
46764
|
__name(resolveScopedKey, "resolveScopedKey");
|
|
46687
46765
|
}
|
|
@@ -49534,7 +49612,10 @@ function scanWrappableFile(filePath, code2, relPath, opts = {}) {
|
|
|
49534
49612
|
wrapped += 1;
|
|
49535
49613
|
const firstArg = node.arguments?.[0];
|
|
49536
49614
|
if (firstArg?.type === "Literal" && typeof firstArg.value === "string") {
|
|
49537
|
-
|
|
49615
|
+
const resolved = resolveScopedKey(node.callee.name, firstArg.value, childScopes);
|
|
49616
|
+
if (!resolved.unresolvable) {
|
|
49617
|
+
wrappedIds.labels.push(resolved.key);
|
|
49618
|
+
}
|
|
49538
49619
|
}
|
|
49539
49620
|
}
|
|
49540
49621
|
}
|
|
@@ -106835,8 +106916,8 @@ function extractFromFile(filePath) {
|
|
|
106835
106916
|
const name = node.callee.name;
|
|
106836
106917
|
const firstArg = (node.arguments ?? [])[0];
|
|
106837
106918
|
if (firstArg?.type === "Literal" && typeof firstArg.value === "string") {
|
|
106838
|
-
const { key, scoped } = resolveScopedKey(name, firstArg.value, childScopes);
|
|
106839
|
-
if (scoped || name === "t") {
|
|
106919
|
+
const { key, scoped, unresolvable } = resolveScopedKey(name, firstArg.value, childScopes);
|
|
106920
|
+
if (!unresolvable && (scoped || name === "t")) {
|
|
106840
106921
|
declarations.push({ key, file: filePath });
|
|
106841
106922
|
}
|
|
106842
106923
|
}
|
|
@@ -46,10 +46,10 @@ function extractFromFile(filePath) {
|
|
|
46
46
|
const name = node.callee.name;
|
|
47
47
|
const firstArg = (node.arguments ?? [])[0];
|
|
48
48
|
if (firstArg?.type === 'Literal' && typeof firstArg.value === 'string') {
|
|
49
|
-
const { key, scoped } = resolveScopedKey(name, firstArg.value, childScopes);
|
|
50
|
-
// A namespace-scoped var (any name) OR a bare Fimo `t(...)
|
|
51
|
-
//
|
|
52
|
-
if (scoped || name === 't') {
|
|
49
|
+
const { key, scoped, unresolvable } = resolveScopedKey(name, firstArg.value, childScopes);
|
|
50
|
+
// A namespace-scoped var (any name) OR a bare Fimo `t(...)`. A passed-in
|
|
51
|
+
// param `t` is unresolvable (the caller owns the namespace) — skip it.
|
|
52
|
+
if (!unresolvable && (scoped || name === 't')) {
|
|
53
53
|
declarations.push({ key, file: filePath });
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -63,4 +63,42 @@ export default async function Page() {
|
|
|
63
63
|
});
|
|
64
64
|
expect(keysOf(cwd)).toEqual(['home.title']);
|
|
65
65
|
});
|
|
66
|
+
it('resolves the object-arg namespace: getTranslations({ namespace })', () => {
|
|
67
|
+
const cwd = project({
|
|
68
|
+
'src/meta.tsx': `import { getTranslations } from 'next-intl/server';
|
|
69
|
+
export async function generateMetadata({ params }) {
|
|
70
|
+
const t = await getTranslations({ locale: params.locale, namespace: 'seo' });
|
|
71
|
+
return { title: t('metaTitle'), keywords: t('keywords') };
|
|
72
|
+
}`,
|
|
73
|
+
});
|
|
74
|
+
expect(keysOf(cwd)).toEqual(['seo.keywords', 'seo.metaTitle']);
|
|
75
|
+
});
|
|
76
|
+
it('resolves a t destructured from Promise.all (with or without a use() wrapper)', () => {
|
|
77
|
+
const cwd = project({
|
|
78
|
+
'src/a.tsx': `import { getTranslations } from 'next-intl/server';
|
|
79
|
+
export async function A() {
|
|
80
|
+
const [data, t] = await Promise.all([fetchData(), getTranslations('cms')]);
|
|
81
|
+
return <p>{t('compare')}</p>;
|
|
82
|
+
}`,
|
|
83
|
+
'src/b.tsx': `import { use } from 'react';
|
|
84
|
+
import { getTranslations } from 'next-intl/server';
|
|
85
|
+
export function B() {
|
|
86
|
+
const [data, t] = use(Promise.all([fetchData(), getTranslations('cms')]));
|
|
87
|
+
return <p>{t('disclaimer')}</p>;
|
|
88
|
+
}`,
|
|
89
|
+
});
|
|
90
|
+
expect(keysOf(cwd)).toEqual(['cms.compare', 'cms.disclaimer']);
|
|
91
|
+
});
|
|
92
|
+
it('skips a t passed in as a parameter — plain or destructured (caller owns the namespace)', () => {
|
|
93
|
+
const cwd = project({
|
|
94
|
+
'src/defaults.tsx': `export function getDefaults(siteUrl, t) {
|
|
95
|
+
return { title: t('metaTitle'), keywords: t('keywords') };
|
|
96
|
+
}`,
|
|
97
|
+
'src/grid.tsx': `export function Grid({ t, items }) {
|
|
98
|
+
return <button>{t('loadMore')}</button>;
|
|
99
|
+
}`,
|
|
100
|
+
});
|
|
101
|
+
// Unresolvable param keys are dropped, not recorded as bare leaves.
|
|
102
|
+
expect(keysOf(cwd)).toEqual([]);
|
|
103
|
+
});
|
|
66
104
|
});
|
|
@@ -10,16 +10,18 @@
|
|
|
10
10
|
* with no binding (Fimo's own label call) keeps its key unchanged.
|
|
11
11
|
*/
|
|
12
12
|
export declare const isFunctionLike: (node: any) => boolean;
|
|
13
|
-
|
|
14
|
-
* direct body: variable name → namespace (`""` for root scope). */
|
|
15
|
-
export declare function collectScopedBindings(fnNode: any): Map<string, string>;
|
|
13
|
+
export declare function collectScopedBindings(fnNode: any): Map<string, string | null>;
|
|
16
14
|
/**
|
|
17
15
|
* Resolve a `<name>("leaf")` call to its full key given the scope stack
|
|
18
|
-
* (innermost first).
|
|
19
|
-
* is a resolved `useTranslations` binding
|
|
20
|
-
*
|
|
16
|
+
* (innermost first).
|
|
17
|
+
* - `scoped`: the callee is a resolved `useTranslations` binding — namespace
|
|
18
|
+
* prepended (unless root `""`).
|
|
19
|
+
* - `unresolvable`: the callee is a passed-in parameter — its namespace lives in
|
|
20
|
+
* the caller and cannot be known here, so the caller should count the call as
|
|
21
|
+
* covered but NOT demand the (bare) key.
|
|
21
22
|
*/
|
|
22
|
-
export declare function resolveScopedKey(calleeName: string, leafKey: string, scopes: Array<Map<string, string>>): {
|
|
23
|
+
export declare function resolveScopedKey(calleeName: string, leafKey: string, scopes: Array<Map<string, string | null>>): {
|
|
23
24
|
key: string;
|
|
24
25
|
scoped: boolean;
|
|
26
|
+
unresolvable: boolean;
|
|
25
27
|
};
|
|
@@ -12,6 +12,69 @@
|
|
|
12
12
|
export const isFunctionLike = (node) => node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression';
|
|
13
13
|
/** Collect `useTranslations`/`getTranslations` bindings declared in a function's
|
|
14
14
|
* direct body: variable name → namespace (`""` for root scope). */
|
|
15
|
+
const unwrapAwait = (node) => (node?.type === 'AwaitExpression' ? node.argument : node);
|
|
16
|
+
/**
|
|
17
|
+
* The namespace of a `useTranslations`/`getTranslations` call, or null if the
|
|
18
|
+
* node is not such a call. Handles the string arg (`getTranslations("seo")`),
|
|
19
|
+
* the object arg (`getTranslations({ locale, namespace: "seo" })`), and no arg
|
|
20
|
+
* (root scope → `""`). A dynamic namespace resolves to `""` (best effort).
|
|
21
|
+
*/
|
|
22
|
+
function translationCallNamespace(node) {
|
|
23
|
+
if (node?.type !== 'CallExpression' || node.callee?.type !== 'Identifier') {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
if (node.callee.name !== 'useTranslations' && node.callee.name !== 'getTranslations') {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const arg = node.arguments?.[0];
|
|
30
|
+
if (!arg) {
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
if (arg.type === 'Literal' && typeof arg.value === 'string') {
|
|
34
|
+
return arg.value;
|
|
35
|
+
}
|
|
36
|
+
if (arg.type === 'ObjectExpression') {
|
|
37
|
+
for (const prop of arg.properties ?? []) {
|
|
38
|
+
const keyName = prop?.key?.name ?? prop?.key?.value;
|
|
39
|
+
if (keyName === 'namespace' && prop.value?.type === 'Literal' && typeof prop.value.value === 'string') {
|
|
40
|
+
return prop.value.value;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return '';
|
|
45
|
+
}
|
|
46
|
+
/** Mark every identifier bound by a parameter pattern (plain, defaulted, or
|
|
47
|
+
* destructured — `t`, `t = x`, `{ t }`, `[t]`) as unresolvable (null). */
|
|
48
|
+
function markParamBindings(node, bindings) {
|
|
49
|
+
if (!node) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
switch (node.type) {
|
|
53
|
+
case 'Identifier':
|
|
54
|
+
if (!bindings.has(node.name)) {
|
|
55
|
+
bindings.set(node.name, null);
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
case 'AssignmentPattern':
|
|
59
|
+
markParamBindings(node.left, bindings);
|
|
60
|
+
break;
|
|
61
|
+
case 'RestElement':
|
|
62
|
+
markParamBindings(node.argument, bindings);
|
|
63
|
+
break;
|
|
64
|
+
case 'ArrayPattern':
|
|
65
|
+
for (const element of node.elements ?? []) {
|
|
66
|
+
markParamBindings(element, bindings);
|
|
67
|
+
}
|
|
68
|
+
break;
|
|
69
|
+
case 'ObjectPattern':
|
|
70
|
+
for (const prop of node.properties ?? []) {
|
|
71
|
+
markParamBindings(prop.type === 'RestElement' ? prop.argument : prop.value, bindings);
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
15
78
|
export function collectScopedBindings(fnNode) {
|
|
16
79
|
const bindings = new Map();
|
|
17
80
|
const body = fnNode.body;
|
|
@@ -21,33 +84,72 @@ export function collectScopedBindings(fnNode) {
|
|
|
21
84
|
continue;
|
|
22
85
|
}
|
|
23
86
|
for (const decl of stmt.declarations ?? []) {
|
|
24
|
-
|
|
87
|
+
const init = unwrapAwait(decl?.init);
|
|
88
|
+
// `const t = [await] useTranslations/getTranslations(...)`
|
|
89
|
+
if (decl?.id?.type === 'Identifier') {
|
|
90
|
+
const namespace = translationCallNamespace(init);
|
|
91
|
+
if (namespace !== null) {
|
|
92
|
+
bindings.set(decl.id.name, namespace);
|
|
93
|
+
}
|
|
25
94
|
continue;
|
|
26
95
|
}
|
|
27
|
-
const
|
|
28
|
-
if (
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
96
|
+
// `const [a, t] = await Promise.all([...])` or `= use(Promise.all([...]))`
|
|
97
|
+
if (decl?.id?.type === 'ArrayPattern') {
|
|
98
|
+
// Unwrap React's `use()` wrapper around the promise.
|
|
99
|
+
const source = init?.type === 'CallExpression' && init.callee?.type === 'Identifier' && init.callee.name === 'use'
|
|
100
|
+
? unwrapAwait(init.arguments?.[0])
|
|
101
|
+
: init;
|
|
102
|
+
const promiseAll = source?.type === 'CallExpression' &&
|
|
103
|
+
source.callee?.type === 'MemberExpression' &&
|
|
104
|
+
source.callee.object?.name === 'Promise' &&
|
|
105
|
+
source.callee.property?.name === 'all';
|
|
106
|
+
const elements = promiseAll
|
|
107
|
+
? source.arguments?.[0]?.type === 'ArrayExpression'
|
|
108
|
+
? source.arguments[0].elements
|
|
109
|
+
: null
|
|
110
|
+
: source?.type === 'ArrayExpression'
|
|
111
|
+
? source.elements
|
|
112
|
+
: null;
|
|
113
|
+
if (elements) {
|
|
114
|
+
decl.id.elements?.forEach((el, index) => {
|
|
115
|
+
if (el?.type !== 'Identifier') {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const namespace = translationCallNamespace(unwrapAwait(elements[index]));
|
|
119
|
+
if (namespace !== null) {
|
|
120
|
+
bindings.set(el.name, namespace);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
34
124
|
}
|
|
35
125
|
}
|
|
36
126
|
}
|
|
127
|
+
// Function parameters are bound by the CALLER: a `t` passed in carries the
|
|
128
|
+
// caller's namespace, unknowable here. Mark them null so their t() calls are
|
|
129
|
+
// counted as covered but never demanded by the seeding gate as a bare leaf.
|
|
130
|
+
for (const param of fnNode.params ?? []) {
|
|
131
|
+
markParamBindings(param, bindings);
|
|
132
|
+
}
|
|
37
133
|
return bindings;
|
|
38
134
|
}
|
|
39
135
|
/**
|
|
40
136
|
* Resolve a `<name>("leaf")` call to its full key given the scope stack
|
|
41
|
-
* (innermost first).
|
|
42
|
-
* is a resolved `useTranslations` binding
|
|
43
|
-
*
|
|
137
|
+
* (innermost first).
|
|
138
|
+
* - `scoped`: the callee is a resolved `useTranslations` binding — namespace
|
|
139
|
+
* prepended (unless root `""`).
|
|
140
|
+
* - `unresolvable`: the callee is a passed-in parameter — its namespace lives in
|
|
141
|
+
* the caller and cannot be known here, so the caller should count the call as
|
|
142
|
+
* covered but NOT demand the (bare) key.
|
|
44
143
|
*/
|
|
45
144
|
export function resolveScopedKey(calleeName, leafKey, scopes) {
|
|
46
145
|
for (let i = scopes.length - 1; i >= 0; i -= 1) {
|
|
47
146
|
if (scopes[i].has(calleeName)) {
|
|
48
147
|
const namespace = scopes[i].get(calleeName);
|
|
49
|
-
|
|
148
|
+
if (namespace === null || namespace === undefined) {
|
|
149
|
+
return { key: leafKey, scoped: false, unresolvable: true };
|
|
150
|
+
}
|
|
151
|
+
return { key: namespace ? `${namespace}.${leafKey}` : leafKey, scoped: true, unresolvable: false };
|
|
50
152
|
}
|
|
51
153
|
}
|
|
52
|
-
return { key: leafKey, scoped: false };
|
|
154
|
+
return { key: leafKey, scoped: false, unresolvable: false };
|
|
53
155
|
}
|
|
@@ -578,8 +578,13 @@ export function scanWrappableFile(filePath, code, relPath, opts = {}) {
|
|
|
578
578
|
const firstArg = node.arguments?.[0];
|
|
579
579
|
if (firstArg?.type === 'Literal' && typeof firstArg.value === 'string') {
|
|
580
580
|
// Resolve the next-intl namespace so the recorded key matches the
|
|
581
|
-
// ingested (namespaced) label in the DB
|
|
582
|
-
|
|
581
|
+
// ingested (namespaced) label in the DB. A passed-in param `t` is
|
|
582
|
+
// unresolvable (the caller owns the namespace) — the call still counts
|
|
583
|
+
// as wrapped, but we do not demand its bare key from the seeding gate.
|
|
584
|
+
const resolved = resolveScopedKey(node.callee.name, firstArg.value, childScopes);
|
|
585
|
+
if (!resolved.unresolvable) {
|
|
586
|
+
wrappedIds.labels.push(resolved.key);
|
|
587
|
+
}
|
|
583
588
|
}
|
|
584
589
|
}
|
|
585
590
|
}
|
package/package.json
CHANGED