@generaltranslation/vue-extractor 0.0.0 → 0.1.0-iris.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +18 -102
- package/dist/detect.d.ts +8 -0
- package/dist/detect.js +2 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +2 -1
- package/dist/inspect.d.ts +9 -0
- package/dist/inspect.js +2 -0
- package/dist/integration.d.ts +69 -0
- package/dist/integration.js +162 -0
- package/dist/integration.js.map +1 -0
- package/dist/internal/config/configFiles.d.ts +6 -0
- package/dist/internal/config/configFiles.js +34 -0
- package/dist/internal/config/configFiles.js.map +1 -0
- package/dist/internal/config/resolveVueCompilerOptions.d.ts +6 -0
- package/dist/internal/config/resolveVueCompilerOptions.js +74 -56
- package/dist/internal/config/resolveVueCompilerOptions.js.map +1 -1
- package/dist/internal/extractFromVueSource.d.ts +4 -3
- package/dist/internal/extractFromVueSource.js +255 -12
- package/dist/internal/extractFromVueSource.js.map +1 -1
- package/dist/internal/project/consumerUsage.d.ts +34 -0
- package/dist/internal/project/consumerUsage.js +1220 -0
- package/dist/internal/project/consumerUsage.js.map +1 -0
- package/dist/internal/project/detectVueProject.d.ts +13 -0
- package/dist/internal/project/detectVueProject.js +65 -0
- package/dist/internal/project/detectVueProject.js.map +1 -0
- package/dist/internal/project/extractFromVueProject.d.ts +10 -0
- package/dist/internal/project/extractFromVueProject.js +579 -0
- package/dist/internal/project/extractFromVueProject.js.map +1 -0
- package/dist/internal/project/inspectVueProject.d.ts +48 -0
- package/dist/internal/project/inspectVueProject.js +143 -0
- package/dist/internal/project/inspectVueProject.js.map +1 -0
- package/dist/internal/project/manifest.d.ts +64 -0
- package/dist/internal/project/manifest.js +270 -0
- package/dist/internal/project/manifest.js.map +1 -0
- package/dist/internal/project/mergeVueProjectExtraction.d.ts +18 -0
- package/dist/internal/project/mergeVueProjectExtraction.js +79 -0
- package/dist/internal/project/mergeVueProjectExtraction.js.map +1 -0
- package/dist/internal/project/moduleResolver.d.ts +18 -0
- package/dist/internal/project/moduleResolver.js +325 -0
- package/dist/internal/project/moduleResolver.js.map +1 -0
- package/dist/internal/project/scopes.d.ts +31 -0
- package/dist/internal/project/scopes.js +182 -0
- package/dist/internal/project/scopes.js.map +1 -0
- package/dist/internal/project/sourcePatterns.d.ts +4 -0
- package/dist/internal/project/sourcePatterns.js +32 -0
- package/dist/internal/project/sourcePatterns.js.map +1 -0
- package/dist/internal/project/viteAliases.d.ts +42 -0
- package/dist/internal/project/viteAliases.js +1020 -0
- package/dist/internal/project/viteAliases.js.map +1 -0
- package/dist/internal/project/vueSourceClassification.d.ts +13 -0
- package/dist/internal/project/vueSourceClassification.js +146 -0
- package/dist/internal/project/vueSourceClassification.js.map +1 -0
- package/dist/internal/project/workspaces.d.ts +31 -0
- package/dist/internal/project/workspaces.js +326 -0
- package/dist/internal/project/workspaces.js.map +1 -0
- package/dist/internal/project/wrapperProvenance.d.ts +21 -0
- package/dist/internal/project/wrapperProvenance.js +287 -0
- package/dist/internal/project/wrapperProvenance.js.map +1 -0
- package/dist/internal/script/analyze.js +252 -85
- package/dist/internal/script/analyze.js.map +1 -1
- package/dist/internal/script/jsx.d.ts +7 -4
- package/dist/internal/script/jsx.js +351 -79
- package/dist/internal/script/jsx.js.map +1 -1
- package/dist/internal/script/localModules.d.ts +23 -2
- package/dist/internal/script/localModules.js +533 -20
- package/dist/internal/script/localModules.js.map +1 -1
- package/dist/internal/script/model.d.ts +9 -2
- package/dist/internal/script/parser.js +2 -1
- package/dist/internal/script/parser.js.map +1 -1
- package/dist/internal/script/runtimeModules.d.ts +10 -0
- package/dist/internal/script/runtimeModules.js +27 -0
- package/dist/internal/script/runtimeModules.js.map +1 -0
- package/dist/internal/stringCalls.js +1 -1
- package/dist/internal/stringCalls.js.map +1 -1
- package/dist/internal/template.js +263 -141
- package/dist/internal/template.js.map +1 -1
- package/dist/internal/types.d.ts +4 -1
- package/dist/internal/utils.d.ts +14 -3
- package/dist/internal/utils.js +63 -3
- package/dist/internal/utils.js.map +1 -1
- package/dist/internal/vueCompiler.d.ts +9 -1
- package/dist/internal/vueCompiler.js +37 -14
- package/dist/internal/vueCompiler.js.map +1 -1
- package/dist/project.d.ts +11 -0
- package/dist/project.js +3 -0
- package/dist/types.d.ts +95 -4
- package/package.json +30 -4
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { parseScriptAst } from "./parser.js";
|
|
2
|
+
import { isKnownNonVueGTRuntime } from "./runtimeModules.js";
|
|
2
3
|
import fs from "node:fs";
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import traverseModule from "@babel/traverse";
|
|
6
|
+
import { initSync, parse } from "es-module-lexer";
|
|
5
7
|
//#region src/internal/script/localModules.ts
|
|
6
8
|
const traverse = traverseModule.default || traverseModule;
|
|
7
9
|
const SOURCE_EXTENSIONS = [
|
|
@@ -27,6 +29,13 @@ const GT_EXPORT_NAMES = [
|
|
|
27
29
|
"useGT",
|
|
28
30
|
"useMessages"
|
|
29
31
|
];
|
|
32
|
+
/** Complete public value surface currently exported by the gt-vue runtime. */
|
|
33
|
+
const GT_RUNTIME_EXPORT_NAMES = [
|
|
34
|
+
...GT_EXPORT_NAMES,
|
|
35
|
+
"createGT",
|
|
36
|
+
"useLocale",
|
|
37
|
+
"useSetLocale"
|
|
38
|
+
];
|
|
30
39
|
const VUE_EXPORT_NAMES = [
|
|
31
40
|
"Suspense",
|
|
32
41
|
"computed",
|
|
@@ -51,9 +60,14 @@ const VUE_EXPORT_NAMES = [
|
|
|
51
60
|
* The resolver reads and parses source text but never imports or executes it.
|
|
52
61
|
* Bare aliases are accepted only through the caller's explicit resolver hook.
|
|
53
62
|
*/
|
|
54
|
-
function createLocalModuleResolver(resolveModuleOption) {
|
|
63
|
+
function createLocalModuleResolver(resolveModuleOption, options = {}) {
|
|
55
64
|
const records = /* @__PURE__ */ new Map();
|
|
65
|
+
const recoveredRecords = /* @__PURE__ */ new Map();
|
|
56
66
|
const resolutions = /* @__PURE__ */ new Map();
|
|
67
|
+
const recordPaths = /* @__PURE__ */ new WeakMap();
|
|
68
|
+
const isProjectModule = (filePath) => {
|
|
69
|
+
return !readRealPath(path.resolve(filePath)).split(path.sep).includes("node_modules");
|
|
70
|
+
};
|
|
57
71
|
const resolveModule = (importer, specifier) => {
|
|
58
72
|
if (specifier === "gt-vue" || specifier === "vue") return void 0;
|
|
59
73
|
let requested;
|
|
@@ -66,6 +80,7 @@ function createLocalModuleResolver(resolveModuleOption) {
|
|
|
66
80
|
};
|
|
67
81
|
const getRecord = (filePath) => {
|
|
68
82
|
const normalized = path.resolve(filePath);
|
|
83
|
+
if (!isProjectModule(normalized)) return void 0;
|
|
69
84
|
const cached = records.get(normalized);
|
|
70
85
|
if (cached !== void 0) return cached ?? void 0;
|
|
71
86
|
records.set(normalized, null);
|
|
@@ -73,33 +88,375 @@ function createLocalModuleResolver(resolveModuleOption) {
|
|
|
73
88
|
records.set(normalized, parsed ?? null);
|
|
74
89
|
return parsed;
|
|
75
90
|
};
|
|
91
|
+
const getRecoveredRecord = (filePath) => {
|
|
92
|
+
const normalized = path.resolve(filePath);
|
|
93
|
+
if (!isProjectModule(normalized)) return void 0;
|
|
94
|
+
const cached = recoveredRecords.get(normalized);
|
|
95
|
+
if (cached !== void 0) return cached ?? void 0;
|
|
96
|
+
const recovered = recoverMalformedModuleExports(normalized);
|
|
97
|
+
recoveredRecords.set(normalized, recovered ?? null);
|
|
98
|
+
return recovered;
|
|
99
|
+
};
|
|
76
100
|
const resolveExportInternal = (filePath, exportName, seen) => {
|
|
77
101
|
const normalized = path.resolve(filePath);
|
|
102
|
+
if (!isProjectModule(normalized)) return {
|
|
103
|
+
status: "resolved",
|
|
104
|
+
target: {
|
|
105
|
+
originKey: `${normalized}#${exportName}`,
|
|
106
|
+
type: "ordinary-external"
|
|
107
|
+
}
|
|
108
|
+
};
|
|
78
109
|
const cycleKey = `${normalized}\0${exportName}`;
|
|
79
110
|
if (seen.has(cycleKey)) return { status: "absent" };
|
|
80
|
-
const record = getRecord(normalized);
|
|
81
|
-
if (!record) return { status: "invalid" };
|
|
82
111
|
const nextSeen = new Set(seen).add(cycleKey);
|
|
112
|
+
const record = getRecord(normalized);
|
|
113
|
+
if (!record) {
|
|
114
|
+
const recovered = getRecoveredRecord(normalized);
|
|
115
|
+
return recovered ? resolveRecoveredExport(recovered, exportName, nextSeen) : { status: "invalid" };
|
|
116
|
+
}
|
|
83
117
|
const explicit = record.explicitExports.get(exportName);
|
|
84
118
|
if (explicit === "ambiguous") return { status: "ambiguous" };
|
|
85
119
|
if (explicit) return resolveDeclaredExport(record, exportName, explicit, nextSeen);
|
|
86
120
|
if (exportName === "default") return { status: "absent" };
|
|
87
121
|
const candidates = [];
|
|
122
|
+
let ambiguous = false;
|
|
88
123
|
let invalid = false;
|
|
124
|
+
let invalidGTExportName;
|
|
125
|
+
let invalidGTSourceReference = false;
|
|
126
|
+
let recoveredTargets = [];
|
|
89
127
|
for (const source of record.starExports) {
|
|
90
128
|
const candidate = resolveFromSource(record, source, exportName, nextSeen);
|
|
91
|
-
if (candidate.status === "
|
|
92
|
-
|
|
93
|
-
|
|
129
|
+
if (candidate.status === "absent") continue;
|
|
130
|
+
const candidateGTExportName = readGTExportName(candidate, nextSeen);
|
|
131
|
+
invalidGTSourceReference ||= candidateGTExportName !== void 0;
|
|
132
|
+
invalidGTExportName ??= candidateGTExportName;
|
|
133
|
+
if (candidate.status === "resolved") {
|
|
134
|
+
candidates.push(candidate.target);
|
|
135
|
+
recoveredTargets?.push(candidate.target);
|
|
136
|
+
}
|
|
137
|
+
if (candidate.status === "ambiguous") {
|
|
138
|
+
ambiguous = true;
|
|
139
|
+
recoveredTargets = void 0;
|
|
140
|
+
}
|
|
141
|
+
if (candidate.status === "invalid") {
|
|
142
|
+
invalid = true;
|
|
143
|
+
invalidGTSourceReference ||= candidate.hasGTSourceReference === true;
|
|
144
|
+
invalidGTExportName ??= candidate.gtExportName;
|
|
145
|
+
if (recoveredTargets && candidate.recoveredTargets) recoveredTargets.push(...candidate.recoveredTargets);
|
|
146
|
+
else recoveredTargets = void 0;
|
|
147
|
+
}
|
|
94
148
|
}
|
|
95
|
-
if (candidates.
|
|
96
|
-
|
|
149
|
+
if (new Set(candidates.map(({ originKey }) => originKey)).size > 1) {
|
|
150
|
+
ambiguous = true;
|
|
151
|
+
recoveredTargets = void 0;
|
|
152
|
+
}
|
|
153
|
+
if (recoveredTargets && new Set(recoveredTargets.map(({ originKey }) => originKey)).size > 1) {
|
|
154
|
+
ambiguous = true;
|
|
155
|
+
recoveredTargets = void 0;
|
|
156
|
+
}
|
|
157
|
+
if (invalid) return {
|
|
158
|
+
...invalidGTSourceReference && { hasGTSourceReference: true },
|
|
159
|
+
...invalidGTExportName && { gtExportName: invalidGTExportName },
|
|
160
|
+
...recoveredTargets?.length && { recoveredTargets: uniqueRecoveredTargets(recoveredTargets) },
|
|
161
|
+
status: "invalid"
|
|
162
|
+
};
|
|
163
|
+
if (ambiguous) return { status: "ambiguous" };
|
|
164
|
+
return candidates.length === 0 ? { status: "absent" } : {
|
|
97
165
|
status: "resolved",
|
|
98
166
|
target: candidates[0]
|
|
99
|
-
}
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
const resolveRecoveredExport = (record, exportName, seen) => {
|
|
170
|
+
const explicit = record.explicitExports.get(exportName);
|
|
171
|
+
if (explicit === "ambiguous") return { status: "ambiguous" };
|
|
172
|
+
if (explicit) return invalidateRecoveredResolution(explicit.type === "reexport" ? resolveFromSource(record, explicit.source, explicit.importedName, seen) : resolveRecoveredNamespace(record, explicit.source), seen);
|
|
173
|
+
if (exportName === "default") return { status: "invalid" };
|
|
174
|
+
let gtExportName;
|
|
175
|
+
let recoveredTargets = [];
|
|
176
|
+
for (const source of record.starExports) {
|
|
177
|
+
const candidate = resolveFromSource(record, source, exportName, seen);
|
|
178
|
+
if (candidate.status === "absent") continue;
|
|
179
|
+
gtExportName ??= readGTExportName(candidate, seen);
|
|
180
|
+
if (recoveredTargets && candidate.status === "resolved") recoveredTargets.push(candidate.target);
|
|
181
|
+
else if (recoveredTargets && candidate.status === "invalid" && candidate.recoveredTargets) recoveredTargets.push(...candidate.recoveredTargets);
|
|
182
|
+
else recoveredTargets = void 0;
|
|
183
|
+
}
|
|
184
|
+
if (recoveredTargets && new Set(recoveredTargets.map(({ originKey }) => originKey)).size > 1) recoveredTargets = void 0;
|
|
185
|
+
return {
|
|
186
|
+
...gtExportName && {
|
|
187
|
+
gtExportName,
|
|
188
|
+
hasGTSourceReference: true
|
|
189
|
+
},
|
|
190
|
+
...recoveredTargets?.length && { recoveredTargets: uniqueRecoveredTargets(recoveredTargets) },
|
|
191
|
+
status: "invalid"
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
const resolveRecoveredNamespace = (record, source) => {
|
|
195
|
+
if (isKnownNonVueGTRuntime(source)) return {
|
|
196
|
+
status: "resolved",
|
|
197
|
+
target: {
|
|
198
|
+
originKey: `${source}#namespace`,
|
|
199
|
+
type: "ordinary-external"
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
if (isExternalModule(source)) return {
|
|
203
|
+
status: "resolved",
|
|
204
|
+
target: {
|
|
205
|
+
originKey: `${source}#namespace`,
|
|
206
|
+
source,
|
|
207
|
+
type: "external-namespace"
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
const modulePath = resolveModule(record.filePath, source);
|
|
211
|
+
if (!modulePath) return { status: "invalid" };
|
|
212
|
+
if (!isProjectModule(modulePath)) return {
|
|
213
|
+
status: "resolved",
|
|
214
|
+
target: {
|
|
215
|
+
originKey: `${modulePath}#namespace`,
|
|
216
|
+
type: "ordinary-external"
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
return {
|
|
220
|
+
status: "resolved",
|
|
221
|
+
target: {
|
|
222
|
+
modulePath,
|
|
223
|
+
originKey: `${modulePath}#namespace`,
|
|
224
|
+
type: "namespace"
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
};
|
|
228
|
+
const invalidateRecoveredResolution = (resolution, seen) => {
|
|
229
|
+
const gtExportName = readGTExportName(resolution, seen);
|
|
230
|
+
return {
|
|
231
|
+
...gtExportName && {
|
|
232
|
+
gtExportName,
|
|
233
|
+
hasGTSourceReference: true
|
|
234
|
+
},
|
|
235
|
+
...resolution.status === "resolved" ? { recoveredTargets: [resolution.target] } : resolution.status === "invalid" && resolution.recoveredTargets ? { recoveredTargets: resolution.recoveredTargets } : {},
|
|
236
|
+
status: "invalid"
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
const readGTExportName = (resolution, seen, allowNamespaceContainers = true) => {
|
|
240
|
+
if (resolution.status === "invalid") return allowNamespaceContainers || resolution.gtExportName !== "*" ? resolution.gtExportName : void 0;
|
|
241
|
+
if (resolution.status !== "resolved") return void 0;
|
|
242
|
+
const { target } = resolution;
|
|
243
|
+
if (target.type === "external") return target.source === "gt-vue" ? target.exportName : void 0;
|
|
244
|
+
if (target.type === "external-namespace") return allowNamespaceContainers && target.source === "gt-vue" ? "*" : void 0;
|
|
245
|
+
if (target.type === "namespace") {
|
|
246
|
+
if (!allowNamespaceContainers) return void 0;
|
|
247
|
+
return (options.recognizeAllGTRuntimeExports ? [...GT_RUNTIME_EXPORT_NAMES] : [...GT_EXPORT_NAMES]).some((name) => Boolean(readGTExportName(resolveExportInternal(target.modulePath, name, seen), seen, allowNamespaceContainers))) ? "*" : void 0;
|
|
248
|
+
}
|
|
249
|
+
if (target.type === "ordinary-external") return void 0;
|
|
250
|
+
const state = {
|
|
251
|
+
bindings: /* @__PURE__ */ new Set(),
|
|
252
|
+
nodes: /* @__PURE__ */ new Set(),
|
|
253
|
+
record: target.record,
|
|
254
|
+
resolutions: seen,
|
|
255
|
+
allowNamespaceContainers
|
|
256
|
+
};
|
|
257
|
+
if (target.type === "expression") return readDerivedGT(target.node, state);
|
|
258
|
+
const binding = target.record.programScope.getBinding(target.exportName);
|
|
259
|
+
return binding ? readDerivedGTBinding(binding, state) : void 0;
|
|
260
|
+
};
|
|
261
|
+
/** Lazily indexes lexical paths only when package provenance needs them. */
|
|
262
|
+
const readNodePath = (record, node) => {
|
|
263
|
+
let paths = recordPaths.get(record);
|
|
264
|
+
if (!paths) {
|
|
265
|
+
paths = /* @__PURE__ */ new WeakMap();
|
|
266
|
+
traverse(record.ast, { enter(nodePath) {
|
|
267
|
+
paths.set(nodePath.node, nodePath);
|
|
268
|
+
} });
|
|
269
|
+
recordPaths.set(record, paths);
|
|
270
|
+
}
|
|
271
|
+
return paths.get(node);
|
|
272
|
+
};
|
|
273
|
+
/** Rejects a namespace member whose value is overwritten in this module. */
|
|
274
|
+
const namespaceMemberIsWritten = (binding, exportName) => {
|
|
275
|
+
return binding.referencePaths.some((reference) => {
|
|
276
|
+
const member = reference.parentPath;
|
|
277
|
+
if (!member?.isMemberExpression() && !member?.isOptionalMemberExpression() || member.node.object !== reference.node || readStaticMemberName(member.node) !== exportName) return false;
|
|
278
|
+
const parent = member.parentPath?.node;
|
|
279
|
+
return Boolean(parent?.type === "AssignmentExpression" && parent.left === member.node || parent?.type === "UpdateExpression" && parent.argument === member.node || parent?.type === "UnaryExpression" && parent.operator === "delete" && parent.argument === member.node || (parent?.type === "ForInStatement" || parent?.type === "ForOfStatement") && parent.left === member.node);
|
|
280
|
+
});
|
|
281
|
+
};
|
|
282
|
+
/** Follows immutable aliases while rejecting mutation and lexical shadows. */
|
|
283
|
+
const readDerivedGTBinding = (binding, state) => {
|
|
284
|
+
if (!binding.constant || state.bindings.has(binding)) return void 0;
|
|
285
|
+
const next = {
|
|
286
|
+
...state,
|
|
287
|
+
bindings: new Set(state.bindings).add(binding)
|
|
288
|
+
};
|
|
289
|
+
if (binding.kind === "module") {
|
|
290
|
+
const imported = state.record.imports.get(binding.identifier.name);
|
|
291
|
+
if (!imported) return void 0;
|
|
292
|
+
if (imported.importedName === "*") return state.allowNamespaceContainers && imported.source === "gt-vue" ? "*" : void 0;
|
|
293
|
+
return readGTExportName(resolveFromSource(state.record, imported.source, imported.importedName, state.resolutions), state.resolutions, state.allowNamespaceContainers);
|
|
294
|
+
}
|
|
295
|
+
const declaration = binding.path.node;
|
|
296
|
+
if (declaration.type === "VariableDeclarator") {
|
|
297
|
+
if (declaration.id.type === "Identifier") return readDerivedGT(declaration.init, next);
|
|
298
|
+
return readDestructuredGTBinding(binding, declaration, next);
|
|
299
|
+
}
|
|
300
|
+
return declaration.type === "FunctionDeclaration" ? readDerivedGT(declaration, next) : void 0;
|
|
301
|
+
};
|
|
302
|
+
/** Resolves one exact leaf destructured from a direct gt-vue namespace. */
|
|
303
|
+
const readDestructuredGTBinding = (binding, declaration, state) => {
|
|
304
|
+
if (declaration.id.type !== "ObjectPattern" || declaration.id.properties.some((property) => property.type === "RestElement")) return;
|
|
305
|
+
const property = declaration.id.properties.find((candidate) => candidate.type === "ObjectProperty" && !candidate.computed && candidate.value.type === "Identifier" && candidate.value === binding.identifier);
|
|
306
|
+
const exportName = property ? readStaticObjectKey(property) : void 0;
|
|
307
|
+
if (!exportName || !knownExternalExport("gt-vue", exportName, options.recognizeAllGTRuntimeExports === true)) return;
|
|
308
|
+
const namespace = unwrapLocalExpression(declaration.init);
|
|
309
|
+
if (!namespace || namespace.type !== "Identifier") return void 0;
|
|
310
|
+
const namespaceBinding = readNodePath(state.record, namespace)?.scope.getBinding(namespace.name);
|
|
311
|
+
const imported = namespaceBinding ? state.record.imports.get(namespaceBinding.identifier.name) : void 0;
|
|
312
|
+
return namespaceBinding?.kind === "module" && namespaceBinding.constant && imported?.source === "gt-vue" && imported.importedName === "*" && !namespaceMemberIsWritten(namespaceBinding, exportName) ? exportName : void 0;
|
|
313
|
+
};
|
|
314
|
+
/** Resolves a direct gt-vue value, including immutable local aliases. */
|
|
315
|
+
const readDirectGT = (node, state) => {
|
|
316
|
+
const expression = unwrapLocalExpression(node);
|
|
317
|
+
if (!expression || state.nodes.has(expression)) return void 0;
|
|
318
|
+
const next = {
|
|
319
|
+
...state,
|
|
320
|
+
nodes: new Set(state.nodes).add(expression)
|
|
321
|
+
};
|
|
322
|
+
if (expression.type === "Identifier") {
|
|
323
|
+
const binding = readNodePath(state.record, expression)?.scope.getBinding(expression.name);
|
|
324
|
+
return binding ? readDerivedGTBinding(binding, next) : void 0;
|
|
325
|
+
}
|
|
326
|
+
if (expression.type !== "MemberExpression" && expression.type !== "OptionalMemberExpression") return;
|
|
327
|
+
const property = readStaticMemberName(expression);
|
|
328
|
+
const object = unwrapLocalExpression(expression.object);
|
|
329
|
+
if (!property || object?.type !== "Identifier") return void 0;
|
|
330
|
+
const binding = readNodePath(state.record, object)?.scope.getBinding(object.name);
|
|
331
|
+
if (!binding || binding.kind !== "module" || !binding.constant) return;
|
|
332
|
+
const imported = state.record.imports.get(binding.identifier.name);
|
|
333
|
+
if (!imported || imported.importedName !== "*") return void 0;
|
|
334
|
+
if (namespaceMemberIsWritten(binding, property)) return void 0;
|
|
335
|
+
if (imported.source === "gt-vue") return knownExternalExport(imported.source, property, options.recognizeAllGTRuntimeExports === true) ? property : void 0;
|
|
336
|
+
const modulePath = resolveModule(state.record.filePath, imported.source);
|
|
337
|
+
return modulePath && isProjectModule(modulePath) ? readGTExportName(resolveExportInternal(modulePath, property, state.resolutions), state.resolutions, state.allowNamespaceContainers) : void 0;
|
|
338
|
+
};
|
|
339
|
+
/** Recognizes only explicit aliases and Vue component wrapper forms. */
|
|
340
|
+
const readDerivedGT = (node, state) => {
|
|
341
|
+
const direct = readDirectGT(node, state);
|
|
342
|
+
if (direct) return direct;
|
|
343
|
+
const expression = unwrapLocalExpression(node);
|
|
344
|
+
if (!expression || state.nodes.has(expression)) return void 0;
|
|
345
|
+
const next = {
|
|
346
|
+
...state,
|
|
347
|
+
nodes: new Set(state.nodes).add(expression)
|
|
348
|
+
};
|
|
349
|
+
if (expression.type === "ArrowFunctionExpression" || expression.type === "FunctionExpression" || expression.type === "FunctionDeclaration" || expression.type === "ObjectMethod") return readFunctionRenderedGT(expression, next);
|
|
350
|
+
if (expression.type === "ObjectExpression") return readComponentObjectGT(expression, next);
|
|
351
|
+
if ((expression.type === "CallExpression" || expression.type === "OptionalCallExpression") && isVueHelper(expression.callee, state, "defineComponent")) {
|
|
352
|
+
const component = expression.arguments[0];
|
|
353
|
+
return component && component.type !== "SpreadElement" && component.type !== "ArgumentPlaceholder" ? readDerivedGT(component, next) : void 0;
|
|
354
|
+
}
|
|
355
|
+
return readRenderedGT(expression, state);
|
|
356
|
+
};
|
|
357
|
+
/** Checks only return values owned by the wrapper function itself. */
|
|
358
|
+
const readFunctionRenderedGT = (fn, state) => {
|
|
359
|
+
if (fn.type === "ArrowFunctionExpression" && fn.body.type !== "BlockStatement") return readRenderedGT(fn.body, state);
|
|
360
|
+
const functionPath = readNodePath(state.record, fn);
|
|
361
|
+
if (!functionPath) return void 0;
|
|
362
|
+
let result;
|
|
363
|
+
functionPath.traverse({ ReturnStatement(returnPath) {
|
|
364
|
+
if (result || returnPath.getFunctionParent()?.node !== fn) return;
|
|
365
|
+
result = readRenderedGT(returnPath.node.argument, state);
|
|
366
|
+
} });
|
|
367
|
+
return result;
|
|
368
|
+
};
|
|
369
|
+
/** Checks the two component options that can directly produce rendered output. */
|
|
370
|
+
const readComponentObjectGT = (object, state) => {
|
|
371
|
+
for (const property of object.properties) {
|
|
372
|
+
if (property.type === "SpreadElement") continue;
|
|
373
|
+
const name = readStaticObjectKey(property);
|
|
374
|
+
if (name !== "render" && name !== "setup") continue;
|
|
375
|
+
const result = readDerivedGT(property.type === "ObjectProperty" ? property.value : property, state);
|
|
376
|
+
if (result) return result;
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
/** Recognizes GT only in returned JSX or the h/createVNode component slot. */
|
|
380
|
+
const readRenderedGT = (node, state) => {
|
|
381
|
+
const expression = unwrapLocalExpression(node);
|
|
382
|
+
if (!expression || state.nodes.has(expression)) return void 0;
|
|
383
|
+
const next = {
|
|
384
|
+
...state,
|
|
385
|
+
nodes: new Set(state.nodes).add(expression)
|
|
386
|
+
};
|
|
387
|
+
if (expression.type === "ArrowFunctionExpression" || expression.type === "FunctionExpression") return readFunctionRenderedGT(expression, next);
|
|
388
|
+
if (expression.type === "JSXElement") {
|
|
389
|
+
const component = readJSXComponentGT(expression.openingElement.name, next);
|
|
390
|
+
if (component) return component;
|
|
391
|
+
for (const child of expression.children) {
|
|
392
|
+
const result = readRenderedGT(child.type === "JSXExpressionContainer" ? child.expression.type === "JSXEmptyExpression" ? void 0 : child.expression : child, next);
|
|
393
|
+
if (result) return result;
|
|
394
|
+
}
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
if (expression.type === "JSXFragment") {
|
|
398
|
+
for (const child of expression.children) {
|
|
399
|
+
const result = readRenderedGT(child.type === "JSXExpressionContainer" ? child.expression.type === "JSXEmptyExpression" ? void 0 : child.expression : child, next);
|
|
400
|
+
if (result) return result;
|
|
401
|
+
}
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (expression.type === "ConditionalExpression") return readRenderedGT(expression.consequent, next) ?? readRenderedGT(expression.alternate, next);
|
|
405
|
+
if (expression.type === "LogicalExpression") return readRenderedGT(expression.left, next) ?? readRenderedGT(expression.right, next);
|
|
406
|
+
if (expression.type !== "CallExpression" && expression.type !== "OptionalCallExpression" || !isVueHelper(expression.callee, state, "h") && !isVueHelper(expression.callee, state, "createVNode")) return;
|
|
407
|
+
const component = expression.arguments[0];
|
|
408
|
+
return component && component.type !== "SpreadElement" && component.type !== "ArgumentPlaceholder" ? readDirectGT(component, next) : void 0;
|
|
409
|
+
};
|
|
410
|
+
/** Resolves an imported GT component used as a JSX element name. */
|
|
411
|
+
const readJSXComponentGT = (name, state) => {
|
|
412
|
+
if (name.type === "JSXMemberExpression") {
|
|
413
|
+
if (name.object.type !== "JSXIdentifier") return void 0;
|
|
414
|
+
const binding = readNodePath(state.record, name.object)?.scope.getBinding(name.object.name);
|
|
415
|
+
if (!binding || binding.kind !== "module" || !binding.constant) return;
|
|
416
|
+
const imported = state.record.imports.get(binding.identifier.name);
|
|
417
|
+
if (!imported || imported.importedName !== "*") return void 0;
|
|
418
|
+
const property = name.property.name;
|
|
419
|
+
if (namespaceMemberIsWritten(binding, property)) return void 0;
|
|
420
|
+
if (imported.source === "gt-vue") return knownExternalExport(imported.source, property, options.recognizeAllGTRuntimeExports === true) ? property : void 0;
|
|
421
|
+
const modulePath = resolveModule(state.record.filePath, imported.source);
|
|
422
|
+
return modulePath && isProjectModule(modulePath) ? readGTExportName(resolveExportInternal(modulePath, property, state.resolutions), state.resolutions, state.allowNamespaceContainers) : void 0;
|
|
423
|
+
}
|
|
424
|
+
if (name.type !== "JSXIdentifier" || /^[a-z]/.test(name.name)) return;
|
|
425
|
+
const binding = readNodePath(state.record, name)?.scope.getBinding(name.name);
|
|
426
|
+
return binding ? readDerivedGTBinding(binding, state) : void 0;
|
|
427
|
+
};
|
|
428
|
+
/** Matches a direct or namespace ESM import from Vue without evaluating calls. */
|
|
429
|
+
const isVueHelper = (node, state, exportName) => {
|
|
430
|
+
const expression = unwrapLocalExpression(node);
|
|
431
|
+
if (!expression) return false;
|
|
432
|
+
const identifier = expression.type === "Identifier" ? expression : (expression.type === "MemberExpression" || expression.type === "OptionalMemberExpression") && readStaticMemberName(expression) === exportName ? unwrapLocalExpression(expression.object) : void 0;
|
|
433
|
+
if (!identifier || identifier.type !== "Identifier") return false;
|
|
434
|
+
const binding = readNodePath(state.record, identifier)?.scope.getBinding(identifier.name);
|
|
435
|
+
const imported = binding?.kind === "module" ? state.record.imports.get(binding.identifier.name) : void 0;
|
|
436
|
+
const expectedImport = expression.type === "Identifier" ? exportName : "*";
|
|
437
|
+
return binding?.constant === true && imported?.source === "vue" && imported.importedName === expectedImport && (expectedImport !== "*" || !namespaceMemberIsWritten(binding, exportName));
|
|
438
|
+
};
|
|
439
|
+
const readStaticMemberName = (member) => {
|
|
440
|
+
if (!member.computed && member.property.type === "Identifier") return member.property.name;
|
|
441
|
+
return member.computed && member.property.type === "StringLiteral" ? member.property.value : void 0;
|
|
442
|
+
};
|
|
443
|
+
const readStaticObjectKey = (property) => {
|
|
444
|
+
if (!property.key) return void 0;
|
|
445
|
+
if (!property.computed && property.key.type === "Identifier") return property.key.name;
|
|
446
|
+
return property.key.type === "StringLiteral" ? property.key.value : void 0;
|
|
447
|
+
};
|
|
448
|
+
const resolutionReferencesGT = (resolution, seen) => {
|
|
449
|
+
return readGTExportName(resolution, seen) !== void 0;
|
|
100
450
|
};
|
|
101
451
|
const resolveFromSource = (record, source, exportName, seen) => {
|
|
102
|
-
if (
|
|
452
|
+
if (isKnownNonVueGTRuntime(source)) return {
|
|
453
|
+
status: "resolved",
|
|
454
|
+
target: {
|
|
455
|
+
originKey: `${source}#${exportName}`,
|
|
456
|
+
type: "ordinary-external"
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
if (isExternalModule(source)) return knownExternalExport(source, exportName, options.recognizeAllGTRuntimeExports === true) ? {
|
|
103
460
|
status: "resolved",
|
|
104
461
|
target: {
|
|
105
462
|
exportName,
|
|
@@ -109,11 +466,26 @@ function createLocalModuleResolver(resolveModuleOption) {
|
|
|
109
466
|
}
|
|
110
467
|
} : { status: "absent" };
|
|
111
468
|
const modulePath = resolveModule(record.filePath, source);
|
|
112
|
-
|
|
469
|
+
if (!modulePath) return { status: "invalid" };
|
|
470
|
+
if (!isProjectModule(modulePath)) return {
|
|
471
|
+
status: "resolved",
|
|
472
|
+
target: {
|
|
473
|
+
originKey: `${modulePath}#${exportName}`,
|
|
474
|
+
type: "ordinary-external"
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
return resolveExportInternal(modulePath, exportName, seen);
|
|
113
478
|
};
|
|
114
479
|
const resolveDeclaredExport = (record, exportName, declared, seen) => {
|
|
115
480
|
if (declared.type === "reexport") return resolveFromSource(record, declared.source, declared.importedName, seen);
|
|
116
481
|
if (declared.type === "namespace") {
|
|
482
|
+
if (isKnownNonVueGTRuntime(declared.source)) return {
|
|
483
|
+
status: "resolved",
|
|
484
|
+
target: {
|
|
485
|
+
originKey: `${declared.source}#namespace`,
|
|
486
|
+
type: "ordinary-external"
|
|
487
|
+
}
|
|
488
|
+
};
|
|
117
489
|
if (isExternalModule(declared.source)) return {
|
|
118
490
|
status: "resolved",
|
|
119
491
|
target: {
|
|
@@ -123,6 +495,13 @@ function createLocalModuleResolver(resolveModuleOption) {
|
|
|
123
495
|
}
|
|
124
496
|
};
|
|
125
497
|
const modulePath = resolveModule(record.filePath, declared.source);
|
|
498
|
+
if (modulePath && !isProjectModule(modulePath)) return {
|
|
499
|
+
status: "resolved",
|
|
500
|
+
target: {
|
|
501
|
+
originKey: `${modulePath}#namespace`,
|
|
502
|
+
type: "ordinary-external"
|
|
503
|
+
}
|
|
504
|
+
};
|
|
126
505
|
return modulePath ? {
|
|
127
506
|
status: "resolved",
|
|
128
507
|
target: {
|
|
@@ -136,6 +515,13 @@ function createLocalModuleResolver(resolveModuleOption) {
|
|
|
136
515
|
const imported = record.imports.get(declared.name);
|
|
137
516
|
if (imported) {
|
|
138
517
|
if (imported.importedName === "*") {
|
|
518
|
+
if (isKnownNonVueGTRuntime(imported.source)) return {
|
|
519
|
+
status: "resolved",
|
|
520
|
+
target: {
|
|
521
|
+
originKey: `${imported.source}#namespace`,
|
|
522
|
+
type: "ordinary-external"
|
|
523
|
+
}
|
|
524
|
+
};
|
|
139
525
|
if (isExternalModule(imported.source)) return {
|
|
140
526
|
status: "resolved",
|
|
141
527
|
target: {
|
|
@@ -145,6 +531,13 @@ function createLocalModuleResolver(resolveModuleOption) {
|
|
|
145
531
|
}
|
|
146
532
|
};
|
|
147
533
|
const modulePath = resolveModule(record.filePath, imported.source);
|
|
534
|
+
if (modulePath && !isProjectModule(modulePath)) return {
|
|
535
|
+
status: "resolved",
|
|
536
|
+
target: {
|
|
537
|
+
originKey: `${modulePath}#namespace`,
|
|
538
|
+
type: "ordinary-external"
|
|
539
|
+
}
|
|
540
|
+
};
|
|
148
541
|
return modulePath ? {
|
|
149
542
|
status: "resolved",
|
|
150
543
|
target: {
|
|
@@ -191,26 +584,49 @@ function createLocalModuleResolver(resolveModuleOption) {
|
|
|
191
584
|
const normalized = path.resolve(filePath);
|
|
192
585
|
if (seen.has(normalized)) return /* @__PURE__ */ new Set();
|
|
193
586
|
const record = getRecord(normalized);
|
|
194
|
-
|
|
587
|
+
const recovered = record ? void 0 : getRecoveredRecord(normalized);
|
|
588
|
+
if (!record && !recovered) return /* @__PURE__ */ new Set();
|
|
589
|
+
const moduleRecord = record ?? recovered;
|
|
195
590
|
const nextSeen = new Set(seen).add(normalized);
|
|
196
|
-
const names = new Set(
|
|
197
|
-
for (const source of
|
|
591
|
+
const names = new Set(moduleRecord.explicitExports.keys());
|
|
592
|
+
for (const source of moduleRecord.starExports) if (source === "gt-vue") for (const name of GT_EXPORT_NAMES) names.add(name);
|
|
198
593
|
else if (source === "vue") for (const name of VUE_EXPORT_NAMES) names.add(name);
|
|
594
|
+
else if (isKnownNonVueGTRuntime(source)) continue;
|
|
199
595
|
else {
|
|
200
|
-
const modulePath = resolveModule(
|
|
201
|
-
if (!modulePath) continue;
|
|
596
|
+
const modulePath = resolveModule(moduleRecord.filePath, source);
|
|
597
|
+
if (!modulePath || !isProjectModule(modulePath)) continue;
|
|
202
598
|
for (const name of collectExportNames(modulePath, nextSeen)) if (name !== "default") names.add(name);
|
|
203
599
|
}
|
|
204
600
|
return names;
|
|
205
601
|
};
|
|
602
|
+
const hasGTExportReference = (filePath, exportName) => {
|
|
603
|
+
return resolutionReferencesGT(resolveExportInternal(filePath, exportName, /* @__PURE__ */ new Set()), /* @__PURE__ */ new Set());
|
|
604
|
+
};
|
|
605
|
+
const getGTExportName = (filePath, exportName) => {
|
|
606
|
+
const resolution = resolveExportInternal(filePath, exportName, /* @__PURE__ */ new Set());
|
|
607
|
+
return resolution.status === "resolved" ? readGTExportName(resolution, /* @__PURE__ */ new Set(), false) : void 0;
|
|
608
|
+
};
|
|
206
609
|
return {
|
|
207
610
|
getRecord,
|
|
611
|
+
getGTExportName,
|
|
208
612
|
hasCustomResolver: resolveModuleOption !== void 0,
|
|
613
|
+
hasGTExportReference,
|
|
614
|
+
isProjectModule,
|
|
209
615
|
listExportNames,
|
|
210
616
|
resolveExport,
|
|
211
617
|
resolveModule
|
|
212
618
|
};
|
|
213
619
|
}
|
|
620
|
+
/** Removes syntax-only wrappers without importing the compiler-facing utilities. */
|
|
621
|
+
function unwrapLocalExpression(input) {
|
|
622
|
+
let current = input ?? void 0;
|
|
623
|
+
while (current && (current.type === "TSAsExpression" || current.type === "TSTypeAssertion" || current.type === "TSNonNullExpression" || current.type === "TSSatisfiesExpression" || current.type === "TSInstantiationExpression" || current.type === "TypeCastExpression" || current.type === "ParenthesizedExpression")) current = current.expression;
|
|
624
|
+
return current;
|
|
625
|
+
}
|
|
626
|
+
/** Deduplicates recovered graph targets without discarding their identities. */
|
|
627
|
+
function uniqueRecoveredTargets(targets) {
|
|
628
|
+
return [...new Map(targets.map((target) => [target.originKey, target])).values()];
|
|
629
|
+
}
|
|
214
630
|
function resolveSourceFile(requested) {
|
|
215
631
|
const candidates = [requested];
|
|
216
632
|
const extension = path.extname(requested).toLowerCase();
|
|
@@ -234,6 +650,14 @@ function isReadableFile(filePath) {
|
|
|
234
650
|
return false;
|
|
235
651
|
}
|
|
236
652
|
}
|
|
653
|
+
/** Resolves symlinks when possible while retaining missing-path diagnostics. */
|
|
654
|
+
function readRealPath(filePath) {
|
|
655
|
+
try {
|
|
656
|
+
return fs.realpathSync.native(filePath);
|
|
657
|
+
} catch {
|
|
658
|
+
return filePath;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
237
661
|
function parseLocalModule(filePath) {
|
|
238
662
|
let source;
|
|
239
663
|
try {
|
|
@@ -276,11 +700,95 @@ function parseLocalModule(filePath) {
|
|
|
276
700
|
collectExports(record);
|
|
277
701
|
return record;
|
|
278
702
|
}
|
|
703
|
+
let moduleLexerInitialized = false;
|
|
704
|
+
/**
|
|
705
|
+
* Recovers only source-bound runtime exports from an otherwise invalid module.
|
|
706
|
+
*
|
|
707
|
+
* The recovered declarations establish provenance, but never become executable
|
|
708
|
+
* analyzer input. Their resolutions remain invalid so consumers fail closed
|
|
709
|
+
* while type-only and unrelated module references stay invisible.
|
|
710
|
+
*/
|
|
711
|
+
function recoverMalformedModuleExports(filePath) {
|
|
712
|
+
const extension = path.extname(filePath).toLowerCase();
|
|
713
|
+
if (extension === ".cjs" || extension === ".cts" || extension === ".vue") return;
|
|
714
|
+
let source;
|
|
715
|
+
try {
|
|
716
|
+
source = fs.readFileSync(filePath, "utf8");
|
|
717
|
+
} catch {
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
if (!moduleLexerInitialized) {
|
|
721
|
+
initSync();
|
|
722
|
+
moduleLexerInitialized = true;
|
|
723
|
+
}
|
|
724
|
+
let moduleImports;
|
|
725
|
+
try {
|
|
726
|
+
[moduleImports] = parse(source);
|
|
727
|
+
} catch {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
const record = {
|
|
731
|
+
explicitExports: /* @__PURE__ */ new Map(),
|
|
732
|
+
filePath,
|
|
733
|
+
starExports: []
|
|
734
|
+
};
|
|
735
|
+
const statements = /* @__PURE__ */ new Set();
|
|
736
|
+
for (const moduleImport of moduleImports) {
|
|
737
|
+
if (moduleImport.d !== -1 || moduleImport.ss < 0 || moduleImport.se <= moduleImport.ss) continue;
|
|
738
|
+
statements.add(source.slice(moduleImport.ss, moduleImport.se));
|
|
739
|
+
}
|
|
740
|
+
for (const statementSource of statements) {
|
|
741
|
+
const statement = parseRecoveredModuleStatement(statementSource, extension);
|
|
742
|
+
if (!statement) continue;
|
|
743
|
+
collectRecoveredExport(record, statement);
|
|
744
|
+
}
|
|
745
|
+
return record.explicitExports.size > 0 || record.starExports.length > 0 ? record : void 0;
|
|
746
|
+
}
|
|
747
|
+
/** Parses one lexed declaration under the source file's supported grammars. */
|
|
748
|
+
function parseRecoveredModuleStatement(source, extension) {
|
|
749
|
+
const declaredLanguage = extension === ".mjs" ? "js" : extension === ".mts" ? "ts" : extension.slice(1);
|
|
750
|
+
const languages = new Set([declaredLanguage]);
|
|
751
|
+
if (declaredLanguage === "js" || declaredLanguage === "jsx") languages.add("flow");
|
|
752
|
+
languages.add("tsx");
|
|
753
|
+
for (const language of languages) try {
|
|
754
|
+
const ast = parseScriptAst(source, language);
|
|
755
|
+
if (ast.program.body.length === 1) return ast.program.body[0];
|
|
756
|
+
} catch {}
|
|
757
|
+
}
|
|
758
|
+
/** Adds runtime re-exports without trusting declarations around the syntax error. */
|
|
759
|
+
function collectRecoveredExport(record, statement) {
|
|
760
|
+
if (statement.type === "ExportAllDeclaration") {
|
|
761
|
+
if (statement.exportKind !== "type") record.starExports.push(statement.source.value);
|
|
762
|
+
return;
|
|
763
|
+
}
|
|
764
|
+
if (statement.type !== "ExportNamedDeclaration" || statement.exportKind === "type" || !statement.source) return;
|
|
765
|
+
for (const specifier of statement.specifiers) {
|
|
766
|
+
if (specifier.type === "ExportSpecifier" && specifier.exportKind === "type") continue;
|
|
767
|
+
const exportedName = specifier.exported.type === "Identifier" ? specifier.exported.name : specifier.exported.value;
|
|
768
|
+
if (specifier.type === "ExportNamespaceSpecifier") {
|
|
769
|
+
addRecoveredExplicitExport(record, exportedName, {
|
|
770
|
+
source: statement.source.value,
|
|
771
|
+
type: "namespace"
|
|
772
|
+
});
|
|
773
|
+
continue;
|
|
774
|
+
}
|
|
775
|
+
if (specifier.type !== "ExportSpecifier") continue;
|
|
776
|
+
addRecoveredExplicitExport(record, exportedName, {
|
|
777
|
+
importedName: specifier.local.name,
|
|
778
|
+
source: statement.source.value,
|
|
779
|
+
type: "reexport"
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
/** Preserves ambiguity instead of selecting an arbitrary recovered identity. */
|
|
784
|
+
function addRecoveredExplicitExport(record, name, value) {
|
|
785
|
+
record.explicitExports.set(name, record.explicitExports.has(name) ? "ambiguous" : value);
|
|
786
|
+
}
|
|
279
787
|
function collectImportedBindings(ast) {
|
|
280
788
|
const imports = /* @__PURE__ */ new Map();
|
|
281
789
|
for (const statement of ast.program.body) {
|
|
282
|
-
if (statement.type !== "ImportDeclaration" || statement.importKind
|
|
283
|
-
for (const specifier of statement.specifiers) if (specifier.type === "ImportSpecifier" && specifier.importKind
|
|
790
|
+
if (statement.type !== "ImportDeclaration" || isTypeOnlyImportKind(statement.importKind)) continue;
|
|
791
|
+
for (const specifier of statement.specifiers) if (specifier.type === "ImportSpecifier" && !isTypeOnlyImportKind(specifier.importKind)) imports.set(specifier.local.name, {
|
|
284
792
|
importedName: specifier.imported.type === "Identifier" ? specifier.imported.name : specifier.imported.value,
|
|
285
793
|
source: statement.source.value
|
|
286
794
|
});
|
|
@@ -295,6 +803,10 @@ function collectImportedBindings(ast) {
|
|
|
295
803
|
}
|
|
296
804
|
return imports;
|
|
297
805
|
}
|
|
806
|
+
/** Returns whether Babel classified an ESM binding as type-only. */
|
|
807
|
+
function isTypeOnlyImportKind(kind) {
|
|
808
|
+
return kind === "type" || kind === "typeof";
|
|
809
|
+
}
|
|
298
810
|
function collectExports(record) {
|
|
299
811
|
for (const statement of record.ast.program.body) {
|
|
300
812
|
if (statement.type === "ExportAllDeclaration") {
|
|
@@ -355,8 +867,9 @@ function patternNames(pattern) {
|
|
|
355
867
|
function isExternalModule(source) {
|
|
356
868
|
return source === "gt-vue" || source === "vue";
|
|
357
869
|
}
|
|
358
|
-
function knownExternalExport(source, exportName) {
|
|
359
|
-
|
|
870
|
+
function knownExternalExport(source, exportName, recognizeAllGTRuntimeExports) {
|
|
871
|
+
if (source === "vue") return VUE_EXPORT_NAMES.includes(exportName);
|
|
872
|
+
return (recognizeAllGTRuntimeExports ? GT_RUNTIME_EXPORT_NAMES : GT_EXPORT_NAMES).includes(exportName);
|
|
360
873
|
}
|
|
361
874
|
//#endregion
|
|
362
875
|
export { createLocalModuleResolver };
|