@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
package/dist/internal/types.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { VueExtractionResult } from '../types.js';
|
|
2
|
+
import type { StaticPrimitive } from './utils.js';
|
|
2
3
|
import type { ImplicitSlotWhitespace } from './vueCompiler.js';
|
|
3
4
|
export type GTComponentName = 'T' | 'Var' | 'Num' | 'DateTime' | 'Currency' | 'Plural' | 'Branch';
|
|
4
5
|
/** Vue builtins whose runtime identity changes rich-content traversal. */
|
|
@@ -23,7 +24,7 @@ export type TemplateBindings = {
|
|
|
23
24
|
registeredComponents: Map<string, GTComponentName>;
|
|
24
25
|
/** Vue builtin identities registered through an Options API object. */
|
|
25
26
|
registeredVueBuiltins: Map<string, VueBuiltinName>;
|
|
26
|
-
staticValues: Map<string,
|
|
27
|
+
staticValues: Map<string, StaticPrimitive>;
|
|
27
28
|
/** Vue identity helpers such as `markRaw`. */
|
|
28
29
|
identityFunctions: Set<string>;
|
|
29
30
|
/** Statically visible string alternatives for non-singleton expressions. */
|
|
@@ -63,6 +64,8 @@ export type VueExtractionContext = {
|
|
|
63
64
|
results: VueExtractionResult[];
|
|
64
65
|
source: string;
|
|
65
66
|
surroundingLineCount: number;
|
|
67
|
+
/** Whether the consumer compiler implements Vue 3.3's valued `v-is`. */
|
|
68
|
+
valuedVIsReplacesElement: boolean;
|
|
66
69
|
/** Variable component nodes whose public shape was already validated. */
|
|
67
70
|
validatedVariableComponents: WeakSet<object>;
|
|
68
71
|
warnings: Set<string>;
|
package/dist/internal/utils.d.ts
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
import type * as t from '@babel/types';
|
|
2
|
-
import type { VueExtractionResult } from '../types.js';
|
|
2
|
+
import type { VueExtractionMetadata, VueExtractionResult } from '../types.js';
|
|
3
3
|
import type { ExtractionLocation, VueExtractionContext } from './types.js';
|
|
4
4
|
export declare function createVueExtractionContext(file: string, source: string, projectRoot: string, includeSourceCodeContext: boolean, surroundingLineCount: number, results: VueExtractionResult[], errors: string[], warnings: Set<string>): VueExtractionContext;
|
|
5
5
|
export declare function addVueError(context: VueExtractionContext, location: ExtractionLocation | undefined, whatHappened: string, fix?: string): void;
|
|
6
6
|
export declare function babelLocation(location: t.SourceLocation | null | undefined): ExtractionLocation | undefined;
|
|
7
|
-
export declare function createInlineMetadata(context: VueExtractionContext, location: ExtractionLocation | undefined,
|
|
8
|
-
export type
|
|
7
|
+
export declare function createInlineMetadata(context: VueExtractionContext, location: ExtractionLocation | undefined, translationMetadata?: ExtractedTMetadata): VueExtractionResult['metadata'];
|
|
8
|
+
export type TMetadataKey = 'context' | 'id' | 'maxChars' | 'requiresReview';
|
|
9
|
+
export type ExtractedTMetadata = Pick<VueExtractionMetadata, TMetadataKey>;
|
|
10
|
+
/** Maps React-compatible sugar props onto their canonical metadata key. */
|
|
11
|
+
export declare function normalizeTMetadataKey(name: string, allowTemplateCase?: boolean): TMetadataKey | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Applies one statically evaluated T metadata value using React's validation
|
|
14
|
+
* and normalization rules. Invalid values leave metadata untouched.
|
|
15
|
+
*/
|
|
16
|
+
export declare function applyStaticTMetadataValue(metadata: ExtractedTMetadata, key: TMetadataKey, value: StaticPrimitive): boolean;
|
|
17
|
+
export type StaticPrimitive = string | number | bigint | boolean | null | undefined;
|
|
9
18
|
export type StaticPrimitiveResult = {
|
|
10
19
|
ok: true;
|
|
11
20
|
value: StaticPrimitive;
|
|
@@ -13,6 +22,8 @@ export type StaticPrimitiveResult = {
|
|
|
13
22
|
ok: false;
|
|
14
23
|
};
|
|
15
24
|
export type StaticIdentifierResolver = (identifier: t.Identifier) => StaticPrimitiveResult;
|
|
25
|
+
/** Resolves immutable ECMAScript primitive globals without executing code. */
|
|
26
|
+
export declare function readStaticGlobalPrimitive(name: string): StaticPrimitiveResult;
|
|
16
27
|
/** Removes syntax-only TypeScript, Flow, and parenthesis wrappers. */
|
|
17
28
|
export declare function unwrapExpression(input: t.Node | null | undefined): t.Node | undefined;
|
|
18
29
|
/** Evaluates the side-effect-free primitive subset supported by extraction. */
|
package/dist/internal/utils.js
CHANGED
|
@@ -11,6 +11,7 @@ function createVueExtractionContext(file, source, projectRoot, includeSourceCode
|
|
|
11
11
|
results,
|
|
12
12
|
source,
|
|
13
13
|
surroundingLineCount,
|
|
14
|
+
valuedVIsReplacesElement: false,
|
|
14
15
|
validatedVariableComponents: /* @__PURE__ */ new WeakSet(),
|
|
15
16
|
warnings
|
|
16
17
|
};
|
|
@@ -37,9 +38,9 @@ function babelLocation(location) {
|
|
|
37
38
|
}
|
|
38
39
|
};
|
|
39
40
|
}
|
|
40
|
-
function createInlineMetadata(context, location,
|
|
41
|
+
function createInlineMetadata(context, location, translationMetadata = {}) {
|
|
41
42
|
const metadata = {
|
|
42
|
-
...
|
|
43
|
+
...translationMetadata,
|
|
43
44
|
...context.relativeFile && { filePaths: [context.relativeFile] }
|
|
44
45
|
};
|
|
45
46
|
if (context.includeSourceCodeContext && context.relativeFile && location?.start.line && location.end.line) {
|
|
@@ -48,6 +49,45 @@ function createInlineMetadata(context, location, translationContext) {
|
|
|
48
49
|
}
|
|
49
50
|
return metadata;
|
|
50
51
|
}
|
|
52
|
+
const T_METADATA_KEYS = {
|
|
53
|
+
context: "context",
|
|
54
|
+
$context: "context",
|
|
55
|
+
id: "id",
|
|
56
|
+
$id: "id",
|
|
57
|
+
maxChars: "maxChars",
|
|
58
|
+
$maxChars: "maxChars",
|
|
59
|
+
requiresReview: "requiresReview",
|
|
60
|
+
$requiresReview: "requiresReview"
|
|
61
|
+
};
|
|
62
|
+
const TEMPLATE_T_METADATA_KEYS = {
|
|
63
|
+
"max-chars": "maxChars",
|
|
64
|
+
"$max-chars": "maxChars",
|
|
65
|
+
"requires-review": "requiresReview",
|
|
66
|
+
"$requires-review": "requiresReview"
|
|
67
|
+
};
|
|
68
|
+
/** Maps React-compatible sugar props onto their canonical metadata key. */
|
|
69
|
+
function normalizeTMetadataKey(name, allowTemplateCase = false) {
|
|
70
|
+
return T_METADATA_KEYS[name] || (allowTemplateCase ? TEMPLATE_T_METADATA_KEYS[name] : void 0);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Applies one statically evaluated T metadata value using React's validation
|
|
74
|
+
* and normalization rules. Invalid values leave metadata untouched.
|
|
75
|
+
*/
|
|
76
|
+
function applyStaticTMetadataValue(metadata, key, value) {
|
|
77
|
+
if (key === "context" || key === "id") {
|
|
78
|
+
if (typeof value !== "string") return false;
|
|
79
|
+
metadata[key] = value;
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
if (key === "maxChars") {
|
|
83
|
+
if (typeof value !== "number" || !Number.isFinite(value) || !Number.isInteger(value)) return false;
|
|
84
|
+
metadata.maxChars = Math.abs(value);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
if (typeof value !== "boolean") return false;
|
|
88
|
+
metadata.requiresReview = value;
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
51
91
|
/** Extracts source lines around a 1-based line range. */
|
|
52
92
|
function extractSourceCode(source, startLine, endLine, surroundingLineCount) {
|
|
53
93
|
const lines = source.split("\n");
|
|
@@ -61,6 +101,22 @@ function extractSourceCode(source, startLine, endLine, surroundingLineCount) {
|
|
|
61
101
|
after: lines.slice(targetEnd + 1, targetEnd + 1 + surroundingLineCount).join("\n")
|
|
62
102
|
};
|
|
63
103
|
}
|
|
104
|
+
/** Resolves immutable ECMAScript primitive globals without executing code. */
|
|
105
|
+
function readStaticGlobalPrimitive(name) {
|
|
106
|
+
if (name === "undefined") return {
|
|
107
|
+
ok: true,
|
|
108
|
+
value: void 0
|
|
109
|
+
};
|
|
110
|
+
if (name === "NaN") return {
|
|
111
|
+
ok: true,
|
|
112
|
+
value: NaN
|
|
113
|
+
};
|
|
114
|
+
if (name === "Infinity") return {
|
|
115
|
+
ok: true,
|
|
116
|
+
value: Number.POSITIVE_INFINITY
|
|
117
|
+
};
|
|
118
|
+
return { ok: false };
|
|
119
|
+
}
|
|
64
120
|
/** Removes syntax-only TypeScript, Flow, and parenthesis wrappers. */
|
|
65
121
|
function unwrapExpression(input) {
|
|
66
122
|
let current = input ?? void 0;
|
|
@@ -140,10 +196,14 @@ function readStaticPrimitive(input, resolveIdentifier) {
|
|
|
140
196
|
ok: true,
|
|
141
197
|
value: -argument.value
|
|
142
198
|
} : { ok: false };
|
|
199
|
+
if (argument.ok && argument.value === void 0) return {
|
|
200
|
+
ok: true,
|
|
201
|
+
value: NaN
|
|
202
|
+
};
|
|
143
203
|
}
|
|
144
204
|
return { ok: false };
|
|
145
205
|
}
|
|
146
206
|
//#endregion
|
|
147
|
-
export { addVueError, babelLocation, createInlineMetadata, createVueExtractionContext, readStaticPrimitive, unwrapExpression };
|
|
207
|
+
export { addVueError, applyStaticTMetadataValue, babelLocation, createInlineMetadata, createVueExtractionContext, normalizeTMetadataKey, readStaticGlobalPrimitive, readStaticPrimitive, unwrapExpression };
|
|
148
208
|
|
|
149
209
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":[],"sources":["../../src/internal/utils.ts"],"sourcesContent":["import path from 'node:path';\nimport type * as t from '@babel/types';\nimport { createDiagnosticMessage } from 'generaltranslation/internal';\nimport type { VueExtractionResult, VueSourceCode } from '../types.js';\nimport type { ExtractionLocation, VueExtractionContext } from './types.js';\n\nexport function createVueExtractionContext(\n file: string,\n source: string,\n projectRoot: string,\n includeSourceCodeContext: boolean,\n surroundingLineCount: number,\n results: VueExtractionResult[],\n errors: string[],\n warnings: Set<string>\n): VueExtractionContext {\n return {\n errors,\n file,\n // Script-only extraction never reads this field. Vue SFC extraction\n // replaces it with the resolved consumer compiler's behavior before\n // traversing the template.\n implicitSlotWhitespace: 'ecmascript',\n includeSourceCodeContext,\n relativeFile: path.relative(projectRoot, file),\n results,\n source,\n surroundingLineCount,\n validatedVariableComponents: new WeakSet(),\n warnings,\n };\n}\n\nexport function addVueError(\n context: VueExtractionContext,\n location: ExtractionLocation | undefined,\n whatHappened: string,\n fix?: string\n): void {\n const position = location\n ? ` (${location.start.line}:${location.start.column})`\n : '';\n context.errors.push(\n `${context.file}${position}: ${createDiagnosticMessage({ whatHappened, fix })}`\n );\n}\n\nexport function babelLocation(\n location: t.SourceLocation | null | undefined\n): ExtractionLocation | undefined {\n if (!location) return undefined;\n return {\n start: {\n line: location.start.line,\n column: location.start.column + 1,\n offset: location.start.index ?? 0,\n },\n end: {\n line: location.end.line,\n column: location.end.column + 1,\n offset: location.end.index ?? 0,\n },\n };\n}\n\nexport function createInlineMetadata(\n context: VueExtractionContext,\n location: ExtractionLocation | undefined,\n translationContext?: string\n): VueExtractionResult['metadata'] {\n const metadata: VueExtractionResult['metadata'] = {\n ...(translationContext !== undefined && { context: translationContext }),\n ...(context.relativeFile && { filePaths: [context.relativeFile] }),\n };\n\n if (\n context.includeSourceCodeContext &&\n context.relativeFile &&\n location?.start.line &&\n location.end.line\n ) {\n const sourceCode = extractSourceCode(\n context.source,\n location.start.line,\n location.end.line,\n context.surroundingLineCount\n );\n if (sourceCode) {\n metadata.sourceCode = { [context.relativeFile]: [sourceCode] };\n }\n }\n\n return metadata;\n}\n\n/** Extracts source lines around a 1-based line range. */\nfunction extractSourceCode(\n source: string,\n startLine: number,\n endLine: number,\n surroundingLineCount: number\n): VueSourceCode | undefined {\n const lines = source.split('\\n');\n if (lines.length === 0) return undefined;\n\n const targetStart = Math.max(0, startLine - 1);\n const targetEnd = Math.min(lines.length - 1, endLine - 1);\n if (targetStart > targetEnd) return undefined;\n\n return {\n before: lines\n .slice(Math.max(0, targetStart - surroundingLineCount), targetStart)\n .join('\\n'),\n target: lines.slice(targetStart, targetEnd + 1).join('\\n'),\n after: lines\n .slice(targetEnd + 1, targetEnd + 1 + surroundingLineCount)\n .join('\\n'),\n };\n}\n\nexport type StaticPrimitive = string | number | bigint | boolean | null;\nexport type StaticPrimitiveResult =\n | { ok: true; value: StaticPrimitive }\n | { ok: false };\nexport type StaticIdentifierResolver = (\n identifier: t.Identifier\n) => StaticPrimitiveResult;\n\n/** Removes syntax-only TypeScript, Flow, and parenthesis wrappers. */\nexport function unwrapExpression(\n input: t.Node | null | undefined\n): t.Node | undefined {\n let current = input ?? undefined;\n while (\n current &&\n (current.type === 'TSAsExpression' ||\n current.type === 'TSTypeAssertion' ||\n current.type === 'TSNonNullExpression' ||\n current.type === 'TSSatisfiesExpression' ||\n current.type === 'TSInstantiationExpression' ||\n current.type === 'TypeCastExpression' ||\n current.type === 'ParenthesizedExpression')\n ) {\n current = current.expression;\n }\n return current;\n}\n\n/** Evaluates the side-effect-free primitive subset supported by extraction. */\nexport function readStaticPrimitive(\n input: t.Node | null | undefined,\n resolveIdentifier?: StaticIdentifierResolver\n): StaticPrimitiveResult {\n const expression = unwrapExpression(input);\n if (!expression) return { ok: false };\n if (expression.type === 'Identifier' && resolveIdentifier) {\n return resolveIdentifier(expression);\n }\n if (expression.type === 'StringLiteral') {\n return { ok: true, value: expression.value };\n }\n if (expression.type === 'NumericLiteral') {\n return { ok: true, value: expression.value };\n }\n if (expression.type === 'BigIntLiteral') {\n try {\n return { ok: true, value: BigInt(expression.value) };\n } catch {\n return { ok: false };\n }\n }\n if (expression.type === 'BooleanLiteral') {\n return { ok: true, value: expression.value };\n }\n if (expression.type === 'NullLiteral') {\n return { ok: true, value: null };\n }\n if (expression.type === 'TemplateLiteral') {\n const firstQuasi = expression.quasis[0]?.value.cooked;\n // Executable, untagged template literals always have cooked values.\n // Missing cooked data belongs to malformed or tagged-template ASTs and\n // must fail closed instead of being interpreted with different raw-text\n // semantics.\n if (firstQuasi == null) return { ok: false };\n let value = firstQuasi;\n for (let index = 0; index < expression.expressions.length; index += 1) {\n const interpolation = readStaticPrimitive(\n expression.expressions[index],\n resolveIdentifier\n );\n if (!interpolation.ok) return { ok: false };\n value += String(interpolation.value);\n const quasi = expression.quasis[index + 1]?.value.cooked;\n if (quasi == null) return { ok: false };\n value += quasi;\n }\n return { ok: true, value };\n }\n if (expression.type === 'BinaryExpression' && expression.operator === '+') {\n const left = readStaticPrimitive(expression.left, resolveIdentifier);\n const right = readStaticPrimitive(expression.right, resolveIdentifier);\n if (!left.ok || !right.ok) return { ok: false };\n if (typeof left.value === 'string' || typeof right.value === 'string') {\n return { ok: true, value: String(left.value) + String(right.value) };\n }\n if (typeof left.value === 'bigint' || typeof right.value === 'bigint') {\n return typeof left.value === 'bigint' && typeof right.value === 'bigint'\n ? { ok: true, value: left.value + right.value }\n : { ok: false };\n }\n return { ok: true, value: Number(left.value) + Number(right.value) };\n }\n if (\n expression.type === 'UnaryExpression' &&\n (expression.operator === '+' || expression.operator === '-')\n ) {\n const argument = readStaticPrimitive(\n expression.argument,\n resolveIdentifier\n );\n if (argument.ok && typeof argument.value === 'number') {\n return {\n ok: true,\n value: expression.operator === '-' ? -argument.value : argument.value,\n };\n }\n if (argument.ok && typeof argument.value === 'bigint') {\n return expression.operator === '-'\n ? { ok: true, value: -argument.value }\n : { ok: false };\n }\n }\n return { ok: false };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../src/internal/utils.ts"],"sourcesContent":["import path from 'node:path';\nimport type * as t from '@babel/types';\nimport { createDiagnosticMessage } from 'generaltranslation/internal';\nimport type {\n VueExtractionMetadata,\n VueExtractionResult,\n VueSourceCode,\n} from '../types.js';\nimport type { ExtractionLocation, VueExtractionContext } from './types.js';\n\nexport function createVueExtractionContext(\n file: string,\n source: string,\n projectRoot: string,\n includeSourceCodeContext: boolean,\n surroundingLineCount: number,\n results: VueExtractionResult[],\n errors: string[],\n warnings: Set<string>\n): VueExtractionContext {\n return {\n errors,\n file,\n // Script-only extraction never reads this field. Vue SFC extraction\n // replaces it with the resolved consumer compiler's behavior before\n // traversing the template.\n implicitSlotWhitespace: 'ecmascript',\n includeSourceCodeContext,\n relativeFile: path.relative(projectRoot, file),\n results,\n source,\n surroundingLineCount,\n valuedVIsReplacesElement: false,\n validatedVariableComponents: new WeakSet(),\n warnings,\n };\n}\n\nexport function addVueError(\n context: VueExtractionContext,\n location: ExtractionLocation | undefined,\n whatHappened: string,\n fix?: string\n): void {\n const position = location\n ? ` (${location.start.line}:${location.start.column})`\n : '';\n context.errors.push(\n `${context.file}${position}: ${createDiagnosticMessage({ whatHappened, fix })}`\n );\n}\n\nexport function babelLocation(\n location: t.SourceLocation | null | undefined\n): ExtractionLocation | undefined {\n if (!location) return undefined;\n return {\n start: {\n line: location.start.line,\n column: location.start.column + 1,\n offset: location.start.index ?? 0,\n },\n end: {\n line: location.end.line,\n column: location.end.column + 1,\n offset: location.end.index ?? 0,\n },\n };\n}\n\nexport function createInlineMetadata(\n context: VueExtractionContext,\n location: ExtractionLocation | undefined,\n translationMetadata: ExtractedTMetadata = {}\n): VueExtractionResult['metadata'] {\n const metadata: VueExtractionResult['metadata'] = {\n ...translationMetadata,\n ...(context.relativeFile && { filePaths: [context.relativeFile] }),\n };\n\n if (\n context.includeSourceCodeContext &&\n context.relativeFile &&\n location?.start.line &&\n location.end.line\n ) {\n const sourceCode = extractSourceCode(\n context.source,\n location.start.line,\n location.end.line,\n context.surroundingLineCount\n );\n if (sourceCode) {\n metadata.sourceCode = { [context.relativeFile]: [sourceCode] };\n }\n }\n\n return metadata;\n}\n\nexport type TMetadataKey = 'context' | 'id' | 'maxChars' | 'requiresReview';\n\nexport type ExtractedTMetadata = Pick<VueExtractionMetadata, TMetadataKey>;\n\nconst T_METADATA_KEYS: Readonly<Record<string, TMetadataKey>> = {\n context: 'context',\n $context: 'context',\n id: 'id',\n $id: 'id',\n maxChars: 'maxChars',\n $maxChars: 'maxChars',\n requiresReview: 'requiresReview',\n $requiresReview: 'requiresReview',\n};\n\nconst TEMPLATE_T_METADATA_KEYS: Readonly<Record<string, TMetadataKey>> = {\n 'max-chars': 'maxChars',\n '$max-chars': 'maxChars',\n 'requires-review': 'requiresReview',\n '$requires-review': 'requiresReview',\n};\n\n/** Maps React-compatible sugar props onto their canonical metadata key. */\nexport function normalizeTMetadataKey(\n name: string,\n allowTemplateCase = false\n): TMetadataKey | undefined {\n return (\n T_METADATA_KEYS[name] ||\n (allowTemplateCase ? TEMPLATE_T_METADATA_KEYS[name] : undefined)\n );\n}\n\n/**\n * Applies one statically evaluated T metadata value using React's validation\n * and normalization rules. Invalid values leave metadata untouched.\n */\nexport function applyStaticTMetadataValue(\n metadata: ExtractedTMetadata,\n key: TMetadataKey,\n value: StaticPrimitive\n): boolean {\n if (key === 'context' || key === 'id') {\n if (typeof value !== 'string') return false;\n metadata[key] = value;\n return true;\n }\n if (key === 'maxChars') {\n if (\n typeof value !== 'number' ||\n !Number.isFinite(value) ||\n !Number.isInteger(value)\n ) {\n return false;\n }\n metadata.maxChars = Math.abs(value);\n return true;\n }\n if (typeof value !== 'boolean') return false;\n metadata.requiresReview = value;\n return true;\n}\n\n/** Extracts source lines around a 1-based line range. */\nfunction extractSourceCode(\n source: string,\n startLine: number,\n endLine: number,\n surroundingLineCount: number\n): VueSourceCode | undefined {\n const lines = source.split('\\n');\n if (lines.length === 0) return undefined;\n\n const targetStart = Math.max(0, startLine - 1);\n const targetEnd = Math.min(lines.length - 1, endLine - 1);\n if (targetStart > targetEnd) return undefined;\n\n return {\n before: lines\n .slice(Math.max(0, targetStart - surroundingLineCount), targetStart)\n .join('\\n'),\n target: lines.slice(targetStart, targetEnd + 1).join('\\n'),\n after: lines\n .slice(targetEnd + 1, targetEnd + 1 + surroundingLineCount)\n .join('\\n'),\n };\n}\n\nexport type StaticPrimitive =\n | string\n | number\n | bigint\n | boolean\n | null\n | undefined;\nexport type StaticPrimitiveResult =\n | { ok: true; value: StaticPrimitive }\n | { ok: false };\nexport type StaticIdentifierResolver = (\n identifier: t.Identifier\n) => StaticPrimitiveResult;\n\n/** Resolves immutable ECMAScript primitive globals without executing code. */\nexport function readStaticGlobalPrimitive(name: string): StaticPrimitiveResult {\n if (name === 'undefined') return { ok: true, value: undefined };\n if (name === 'NaN') return { ok: true, value: Number.NaN };\n if (name === 'Infinity') {\n return { ok: true, value: Number.POSITIVE_INFINITY };\n }\n return { ok: false };\n}\n\n/** Removes syntax-only TypeScript, Flow, and parenthesis wrappers. */\nexport function unwrapExpression(\n input: t.Node | null | undefined\n): t.Node | undefined {\n let current = input ?? undefined;\n while (\n current &&\n (current.type === 'TSAsExpression' ||\n current.type === 'TSTypeAssertion' ||\n current.type === 'TSNonNullExpression' ||\n current.type === 'TSSatisfiesExpression' ||\n current.type === 'TSInstantiationExpression' ||\n current.type === 'TypeCastExpression' ||\n current.type === 'ParenthesizedExpression')\n ) {\n current = current.expression;\n }\n return current;\n}\n\n/** Evaluates the side-effect-free primitive subset supported by extraction. */\nexport function readStaticPrimitive(\n input: t.Node | null | undefined,\n resolveIdentifier?: StaticIdentifierResolver\n): StaticPrimitiveResult {\n const expression = unwrapExpression(input);\n if (!expression) return { ok: false };\n if (expression.type === 'Identifier' && resolveIdentifier) {\n return resolveIdentifier(expression);\n }\n if (expression.type === 'StringLiteral') {\n return { ok: true, value: expression.value };\n }\n if (expression.type === 'NumericLiteral') {\n return { ok: true, value: expression.value };\n }\n if (expression.type === 'BigIntLiteral') {\n try {\n return { ok: true, value: BigInt(expression.value) };\n } catch {\n return { ok: false };\n }\n }\n if (expression.type === 'BooleanLiteral') {\n return { ok: true, value: expression.value };\n }\n if (expression.type === 'NullLiteral') {\n return { ok: true, value: null };\n }\n if (expression.type === 'TemplateLiteral') {\n const firstQuasi = expression.quasis[0]?.value.cooked;\n // Executable, untagged template literals always have cooked values.\n // Missing cooked data belongs to malformed or tagged-template ASTs and\n // must fail closed instead of being interpreted with different raw-text\n // semantics.\n if (firstQuasi == null) return { ok: false };\n let value = firstQuasi;\n for (let index = 0; index < expression.expressions.length; index += 1) {\n const interpolation = readStaticPrimitive(\n expression.expressions[index],\n resolveIdentifier\n );\n if (!interpolation.ok) return { ok: false };\n value += String(interpolation.value);\n const quasi = expression.quasis[index + 1]?.value.cooked;\n if (quasi == null) return { ok: false };\n value += quasi;\n }\n return { ok: true, value };\n }\n if (expression.type === 'BinaryExpression' && expression.operator === '+') {\n const left = readStaticPrimitive(expression.left, resolveIdentifier);\n const right = readStaticPrimitive(expression.right, resolveIdentifier);\n if (!left.ok || !right.ok) return { ok: false };\n if (typeof left.value === 'string' || typeof right.value === 'string') {\n return { ok: true, value: String(left.value) + String(right.value) };\n }\n if (typeof left.value === 'bigint' || typeof right.value === 'bigint') {\n return typeof left.value === 'bigint' && typeof right.value === 'bigint'\n ? { ok: true, value: left.value + right.value }\n : { ok: false };\n }\n return { ok: true, value: Number(left.value) + Number(right.value) };\n }\n if (\n expression.type === 'UnaryExpression' &&\n (expression.operator === '+' || expression.operator === '-')\n ) {\n const argument = readStaticPrimitive(\n expression.argument,\n resolveIdentifier\n );\n if (argument.ok && typeof argument.value === 'number') {\n return {\n ok: true,\n value: expression.operator === '-' ? -argument.value : argument.value,\n };\n }\n if (argument.ok && typeof argument.value === 'bigint') {\n return expression.operator === '-'\n ? { ok: true, value: -argument.value }\n : { ok: false };\n }\n // ECMAScript coerces undefined through unary +/- to NaN. Retaining this\n // narrow case lets immutable global expressions match Vue without\n // widening extraction to arbitrary coercions.\n if (argument.ok && argument.value === undefined) {\n return { ok: true, value: Number.NaN };\n }\n }\n return { ok: false };\n}\n"],"mappings":"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"}
|
|
@@ -10,6 +10,8 @@ export type ResolvedVueCompiler = {
|
|
|
10
10
|
parseTemplate?: typeof parseVueTemplate;
|
|
11
11
|
templateCompiler?: TemplateCompiler;
|
|
12
12
|
templateParseOptionsSupported: boolean;
|
|
13
|
+
/** Whether a valued `v-is` replaces its source element at runtime. */
|
|
14
|
+
valuedVIsReplacesElement: boolean;
|
|
13
15
|
version: string;
|
|
14
16
|
};
|
|
15
17
|
type CompilerResolution = {
|
|
@@ -19,8 +21,14 @@ type CompilerResolution = {
|
|
|
19
21
|
ok: false;
|
|
20
22
|
details: string;
|
|
21
23
|
};
|
|
22
|
-
type ExactVueCompiler = Pick<typeof VueCompilerModule, 'compileTemplate' | '
|
|
24
|
+
type ExactVueCompiler = Pick<typeof VueCompilerModule, 'compileTemplate' | 'version'> & {
|
|
25
|
+
/** Newer SFC parser options accepted at runtime but absent in Vue 3.3 types. */
|
|
26
|
+
parse: (source: string, options?: NonNullable<Parameters<typeof VueCompilerModule.parse>[1]> & {
|
|
27
|
+
templateParseOptions?: Record<string, unknown>;
|
|
28
|
+
}) => ReturnType<typeof VueCompilerModule.parse>;
|
|
23
29
|
parseTemplate?: typeof parseVueTemplate;
|
|
30
|
+
/** Adjacent compiler-dom surface used to apply legacy parser options. */
|
|
31
|
+
templateCompiler?: TemplateCompiler;
|
|
24
32
|
};
|
|
25
33
|
/**
|
|
26
34
|
* Resolves the exact Vue compiler selected by the consuming source file.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { DecodingMode, decodeHTML } from "entities/decode";
|
|
4
5
|
//#region src/internal/vueCompiler.ts
|
|
5
6
|
const resolvedCompilers = /* @__PURE__ */ new Map();
|
|
6
7
|
const inspectedCompilers = /* @__PURE__ */ new WeakMap();
|
|
@@ -60,7 +61,7 @@ function inspectVueCompiler(compiler) {
|
|
|
60
61
|
const cached = inspectedCompilers.get(compiler);
|
|
61
62
|
if (cached) return cached;
|
|
62
63
|
const exactCompiler = compiler;
|
|
63
|
-
const resolution = isVueCompiler(compiler) ? inspectCompiler(exactCompiler, exactCompiler.parseTemplate) : {
|
|
64
|
+
const resolution = isVueCompiler(compiler) ? inspectCompiler(exactCompiler, exactCompiler.parseTemplate, exactCompiler.templateCompiler) : {
|
|
64
65
|
ok: false,
|
|
65
66
|
details: "The supplied object does not expose the Vue compiler-sfc API."
|
|
66
67
|
};
|
|
@@ -154,10 +155,8 @@ function loadBunCompiler(requireFromConsumer, vueManifestPath, vueVersion) {
|
|
|
154
155
|
ok: false,
|
|
155
156
|
details: `The template compiler at ${compilerDomPath} does not expose compile().`
|
|
156
157
|
};
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
parse: compilerDom.parse
|
|
160
|
-
});
|
|
158
|
+
const templateCompiler = createHeadlessBrowserTemplateCompiler(compilerDom.parse, compilerDom.compile);
|
|
159
|
+
return inspectCompiler(compiler, templateCompiler.parse, templateCompiler);
|
|
161
160
|
} catch (error) {
|
|
162
161
|
return {
|
|
163
162
|
ok: false,
|
|
@@ -165,6 +164,22 @@ function loadBunCompiler(requireFromConsumer, vueManifestPath, vueVersion) {
|
|
|
165
164
|
};
|
|
166
165
|
}
|
|
167
166
|
}
|
|
167
|
+
/** Replaces compiler-dom's browser-only DOM entity decoder. */
|
|
168
|
+
function createHeadlessBrowserTemplateCompiler(browserParse, browserCompile) {
|
|
169
|
+
const decodeEntities = (raw, asAttribute = false) => decodeHTML(raw, asAttribute ? DecodingMode.Attribute : DecodingMode.Legacy);
|
|
170
|
+
const parse = (source, options) => browserParse(source, {
|
|
171
|
+
...options,
|
|
172
|
+
decodeEntities
|
|
173
|
+
});
|
|
174
|
+
const compile = (source, options) => browserCompile(source, {
|
|
175
|
+
...options,
|
|
176
|
+
decodeEntities
|
|
177
|
+
});
|
|
178
|
+
return {
|
|
179
|
+
compile,
|
|
180
|
+
parse
|
|
181
|
+
};
|
|
182
|
+
}
|
|
168
183
|
/** Finds one dependency relative to the physical Vue installation on disk. */
|
|
169
184
|
function findInstalledPackageRoot(vueManifestPath, packageName) {
|
|
170
185
|
const packageSegments = packageName.split("/");
|
|
@@ -236,14 +251,16 @@ function inspectCompiler(compiler, parseTemplate, templateCompiler) {
|
|
|
236
251
|
ok: false,
|
|
237
252
|
details: "The supplied compiler does not expose exact template parser options. Let the extractor resolve vue/compiler-sfc from the consuming app instead."
|
|
238
253
|
};
|
|
254
|
+
const compilerBehavior = detectTemplateCompilerBehavior(compiler);
|
|
239
255
|
return {
|
|
240
256
|
ok: true,
|
|
241
257
|
value: {
|
|
242
258
|
compiler,
|
|
243
|
-
implicitSlotWhitespace:
|
|
259
|
+
implicitSlotWhitespace: compilerBehavior.implicitSlotWhitespace,
|
|
244
260
|
parseTemplate,
|
|
245
261
|
templateCompiler,
|
|
246
262
|
templateParseOptionsSupported,
|
|
263
|
+
valuedVIsReplacesElement: compilerBehavior.valuedVIsReplacesElement,
|
|
247
264
|
version
|
|
248
265
|
}
|
|
249
266
|
};
|
|
@@ -270,16 +287,17 @@ function collectText(value) {
|
|
|
270
287
|
return output;
|
|
271
288
|
}
|
|
272
289
|
/**
|
|
273
|
-
* Detects
|
|
274
|
-
*
|
|
275
|
-
* the HTML parser's ASCII
|
|
276
|
-
*
|
|
290
|
+
* Detects version-sensitive template semantics instead of inferring them from
|
|
291
|
+
* a semver range. Vue 3.3/3.4 use ECMAScript `trim()` for slot whitespace,
|
|
292
|
+
* while Vue 3.5 uses the HTML parser's ASCII set. Vue 3.3 also compiles valued
|
|
293
|
+
* `v-is` as a dynamic selector, while newer Vue releases retain the source
|
|
294
|
+
* element. One behavior probe remains exact if either behavior is backported.
|
|
277
295
|
*/
|
|
278
|
-
function
|
|
296
|
+
function detectTemplateCompilerBehavior(compiler) {
|
|
279
297
|
const result = compiler.compileTemplate({
|
|
280
298
|
filename: "gt-vue-compiler-probe.vue",
|
|
281
299
|
id: "gt-vue-compiler-probe",
|
|
282
|
-
source: "<Probe><template #named>x</template> </Probe
|
|
300
|
+
source: "<Probe><template #named>x</template> </Probe><div v-is=\"Probe\" />"
|
|
283
301
|
});
|
|
284
302
|
if (result.errors.length > 0) throw new Error(`The Vue compiler compatibility probe failed: ${result.errors.map(String).join("; ")}`);
|
|
285
303
|
const component = result.ast?.children.find((node) => typeof node === "object" && node !== null && "tag" in node && node.tag === "Probe");
|
|
@@ -287,11 +305,16 @@ function detectImplicitSlotWhitespace(compiler) {
|
|
|
287
305
|
const children = codegen && typeof codegen === "object" && "children" in codegen && codegen.children && typeof codegen.children === "object" ? codegen.children : void 0;
|
|
288
306
|
const properties = children && "properties" in children && Array.isArray(children.properties) ? children.properties : void 0;
|
|
289
307
|
if (!properties) throw new Error("The Vue compiler compatibility probe returned an unknown slot AST.");
|
|
290
|
-
|
|
308
|
+
const hasImplicitDefault = properties.some((property) => {
|
|
291
309
|
if (!property || typeof property !== "object" || !("key" in property)) return false;
|
|
292
310
|
const key = property.key;
|
|
293
311
|
return key != null && typeof key === "object" && "content" in key && key.content === "default";
|
|
294
|
-
})
|
|
312
|
+
});
|
|
313
|
+
const vIsElement = result.ast?.children.find((node) => typeof node === "object" && node !== null && "tag" in node && node.tag === "div");
|
|
314
|
+
return {
|
|
315
|
+
implicitSlotWhitespace: hasImplicitDefault ? "html" : "ecmascript",
|
|
316
|
+
valuedVIsReplacesElement: Boolean(vIsElement && "tagType" in vIsElement && vIsElement.tagType === 1)
|
|
317
|
+
};
|
|
295
318
|
}
|
|
296
319
|
function isVueCompiler(value) {
|
|
297
320
|
if (!value || typeof value !== "object") return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vueCompiler.js","names":[],"sources":["../../src/internal/vueCompiler.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { parse as parseVueTemplate } from '@vue/compiler-dom';\nimport type * as VueCompilerModule from '@vue/compiler-sfc';\nimport type { TemplateCompiler } from '@vue/compiler-sfc';\nimport type { VueCompiler } from '../types.js';\n\n/** Whitespace test used by Vue when it constructs an implicit default slot. */\nexport type ImplicitSlotWhitespace = 'ecmascript' | 'html';\n\nexport type ResolvedVueCompiler = {\n compiler: ExactVueCompiler;\n implicitSlotWhitespace: ImplicitSlotWhitespace;\n parseTemplate?: typeof parseVueTemplate;\n templateCompiler?: TemplateCompiler;\n templateParseOptionsSupported: boolean;\n version: string;\n};\n\ntype CompilerResolution =\n | { ok: true; value: ResolvedVueCompiler }\n | { ok: false; details: string };\n\nconst resolvedCompilers = new Map<string, CompilerResolution>();\nconst inspectedCompilers = new WeakMap<object, CompilerResolution>();\n\ntype ExactVueCompiler = Pick<\n typeof VueCompilerModule,\n 'compileTemplate' | 'parse' | 'version'\n> & {\n parseTemplate?: typeof parseVueTemplate;\n};\n\n/**\n * Resolves the exact Vue compiler selected by the consuming source file.\n *\n * The `vue/compiler-sfc` export is version-locked to that installation's Vue\n * runtime. Resolving from the SFC first is important in workspaces where apps\n * intentionally use different Vue versions.\n */\nexport function resolveVueCompiler(\n file: string,\n projectRoot: string\n): CompilerResolution {\n const absoluteFile = path.isAbsolute(file)\n ? file\n : path.resolve(projectRoot, file);\n const anchors = [absoluteFile, path.join(projectRoot, 'package.json')];\n\n for (const anchor of anchors) {\n const requireFromConsumer = createRequire(anchor);\n let vueManifestPath: string;\n try {\n vueManifestPath = requireFromConsumer.resolve('vue/package.json');\n } catch (error) {\n if (isMissingModule(error)) continue;\n return {\n ok: false,\n details: formatResolutionError(error),\n };\n }\n\n let compilerPath: string;\n try {\n compilerPath = requireFromConsumer.resolve('vue/compiler-sfc');\n } catch (error) {\n return {\n ok: false,\n details: `Resolved the app's Vue package at ${vueManifestPath}, but its compiler-sfc export could not be loaded: ${formatResolutionError(error)}`,\n };\n }\n\n const cached = resolvedCompilers.get(compilerPath);\n if (cached) return cached;\n\n const resolution = loadCompiler(\n requireFromConsumer,\n compilerPath,\n vueManifestPath,\n readVueVersion(requireFromConsumer, vueManifestPath)\n );\n resolvedCompilers.set(compilerPath, resolution);\n return resolution;\n }\n\n const declaredVersion = findDeclaredVueVersion(absoluteFile, projectRoot);\n if (declaredVersion) {\n return {\n ok: false,\n details: `The project declares Vue ${JSON.stringify(declaredVersion)} but vue/compiler-sfc could not be resolved from ${absoluteFile}.`,\n };\n }\n\n return {\n ok: false,\n details: `Could not resolve vue/compiler-sfc from ${absoluteFile}.`,\n };\n}\n\n/** Validates an explicitly supplied compiler before extraction uses it. */\nexport function inspectVueCompiler(compiler: VueCompiler): CompilerResolution {\n if (!compiler || typeof compiler !== 'object') {\n return {\n ok: false,\n details: 'The supplied Vue compiler is not an object.',\n };\n }\n const cached = inspectedCompilers.get(compiler);\n if (cached) return cached;\n const exactCompiler = compiler as ExactVueCompiler;\n const resolution = isVueCompiler(compiler)\n ? inspectCompiler(exactCompiler, exactCompiler.parseTemplate)\n : {\n ok: false as const,\n details:\n 'The supplied object does not expose the Vue compiler-sfc API.',\n };\n inspectedCompilers.set(compiler, resolution);\n return resolution;\n}\n\nfunction loadCompiler(\n requireFromConsumer: NodeRequire,\n compilerPath: string,\n vueManifestPath: string,\n vueVersion: string | undefined\n): CompilerResolution {\n try {\n const loaded = requireFromConsumer(compilerPath) as unknown;\n const defaultExport = readDefaultExport(loaded);\n const compiler = isVueCompiler(loaded)\n ? (loaded as ExactVueCompiler)\n : isVueCompiler(defaultExport)\n ? (defaultExport as ExactVueCompiler)\n : undefined;\n if (!compiler) {\n return {\n ok: false,\n details: `The module at ${compilerPath} does not expose the Vue compiler-sfc API.`,\n };\n }\n if (vueVersion && compiler.version !== vueVersion) {\n return {\n ok: false,\n details: `The app resolves Vue ${vueVersion} but vue/compiler-sfc ${compiler.version}. Install one matching Vue package version.`,\n };\n }\n if (!isSupportedVueVersion(compiler.version)) {\n return {\n ok: false,\n details: `Resolved Vue compiler version ${JSON.stringify(compiler.version)}; gt-vue supports Vue 3.3 through Vue 3.x.`,\n };\n }\n const requireFromCompiler = createRequire(compilerPath);\n const compilerDomPath = requireFromCompiler.resolve('@vue/compiler-dom');\n const compilerDom = requireFromCompiler(compilerDomPath) as {\n compile?: TemplateCompiler['compile'];\n parse?: typeof parseVueTemplate;\n };\n const compilerDomVersion = readVueVersion(\n requireFromCompiler,\n requireFromCompiler.resolve('@vue/compiler-dom/package.json')\n );\n if (compilerDomVersion !== compiler.version) {\n return {\n ok: false,\n details: `vue/compiler-sfc ${compiler.version} resolves @vue/compiler-dom ${String(compilerDomVersion)}. Install matching Vue compiler packages.`,\n };\n }\n if (typeof compilerDom.parse !== 'function') {\n return {\n ok: false,\n details: `The template compiler at ${compilerDomPath} does not expose parse().`,\n };\n }\n if (typeof compilerDom.compile !== 'function') {\n return {\n ok: false,\n details: `The template compiler at ${compilerDomPath} does not expose compile().`,\n };\n }\n return inspectCompiler(compiler, compilerDom.parse, {\n compile: compilerDom.compile,\n parse: compilerDom.parse,\n });\n } catch (error) {\n const bunResolution = loadBunCompiler(\n requireFromConsumer,\n vueManifestPath,\n vueVersion\n );\n if (bunResolution) return bunResolution;\n return { ok: false, details: formatResolutionError(error) };\n }\n}\n\n/** Loads exact, self-contained Vue browser compilers in a compiled Bun CLI. */\nfunction loadBunCompiler(\n requireFromConsumer: NodeRequire,\n vueManifestPath: string,\n vueVersion: string | undefined\n): CompilerResolution | undefined {\n if (typeof process.versions.bun !== 'string') return undefined;\n\n try {\n const compilerSfcRoot = findInstalledPackageRoot(\n vueManifestPath,\n '@vue/compiler-sfc'\n );\n const compilerDomRoot = findInstalledPackageRoot(\n vueManifestPath,\n '@vue/compiler-dom'\n );\n if (!compilerSfcRoot || !compilerDomRoot) {\n return {\n ok: false,\n details:\n 'The Vue installation does not contain its compiler-sfc and compiler-dom dependencies.',\n };\n }\n\n const compilerPath = path.join(\n compilerSfcRoot,\n 'dist/compiler-sfc.esm-browser.js'\n );\n const compilerDomPath = path.join(\n compilerDomRoot,\n 'dist/compiler-dom.esm-browser.js'\n );\n const loaded = requireFromConsumer(compilerPath) as unknown;\n const defaultExport = readDefaultExport(loaded);\n const compiler = isVueCompiler(loaded)\n ? (loaded as ExactVueCompiler)\n : isVueCompiler(defaultExport)\n ? (defaultExport as ExactVueCompiler)\n : undefined;\n if (!compiler) {\n return {\n ok: false,\n details: `The module at ${compilerPath} does not expose the Vue compiler-sfc API.`,\n };\n }\n if (vueVersion && compiler.version !== vueVersion) {\n return {\n ok: false,\n details: `The app resolves Vue ${vueVersion} but vue/compiler-sfc ${compiler.version}. Install one matching Vue package version.`,\n };\n }\n if (!isSupportedVueVersion(compiler.version)) {\n return {\n ok: false,\n details: `Resolved Vue compiler version ${JSON.stringify(compiler.version)}; gt-vue supports Vue 3.3 through Vue 3.x.`,\n };\n }\n\n const compilerDom = requireFromConsumer(compilerDomPath) as {\n compile?: TemplateCompiler['compile'];\n parse?: typeof parseVueTemplate;\n };\n const compilerDomVersion = readPackageVersion(compilerDomRoot);\n if (compilerDomVersion !== compiler.version) {\n return {\n ok: false,\n details: `vue/compiler-sfc ${compiler.version} resolves @vue/compiler-dom ${String(compilerDomVersion)}. Install matching Vue compiler packages.`,\n };\n }\n if (typeof compilerDom.parse !== 'function') {\n return {\n ok: false,\n details: `The template compiler at ${compilerDomPath} does not expose parse().`,\n };\n }\n if (typeof compilerDom.compile !== 'function') {\n return {\n ok: false,\n details: `The template compiler at ${compilerDomPath} does not expose compile().`,\n };\n }\n return inspectCompiler(compiler, compilerDom.parse, {\n compile: compilerDom.compile,\n parse: compilerDom.parse,\n });\n } catch (error) {\n return { ok: false, details: formatResolutionError(error) };\n }\n}\n\n/** Finds one dependency relative to the physical Vue installation on disk. */\nfunction findInstalledPackageRoot(\n vueManifestPath: string,\n packageName: string\n): string | undefined {\n const packageSegments = packageName.split('/');\n let directory = path.dirname(vueManifestPath);\n while (true) {\n const candidate =\n path.basename(directory) === 'node_modules'\n ? path.join(directory, ...packageSegments)\n : path.join(directory, 'node_modules', ...packageSegments);\n if (fs.existsSync(path.join(candidate, 'package.json'))) return candidate;\n const parent = path.dirname(directory);\n if (parent === directory) return undefined;\n directory = parent;\n }\n}\n\nfunction readPackageVersion(packageRoot: string): string | undefined {\n try {\n const manifest = JSON.parse(\n fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8')\n ) as { version?: unknown };\n return typeof manifest.version === 'string' ? manifest.version : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction readVueVersion(\n requireFromConsumer: NodeRequire,\n manifestPath: string\n): string | undefined {\n try {\n const manifest = requireFromConsumer(manifestPath) as { version?: unknown };\n return typeof manifest.version === 'string' ? manifest.version : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Finds an installed-but-missing declaration that bundled fallback could hide. */\nfunction findDeclaredVueVersion(\n absoluteFile: string,\n projectRoot: string\n): string | undefined {\n const stop = path.resolve(projectRoot);\n let directory = path.dirname(absoluteFile);\n while (true) {\n const version = readDeclaredVueVersion(\n path.join(directory, 'package.json')\n );\n if (version) return version;\n if (directory === stop || directory === path.dirname(directory)) break;\n directory = path.dirname(directory);\n }\n return readDeclaredVueVersion(path.join(stop, 'package.json'));\n}\n\nfunction readDeclaredVueVersion(manifestPath: string): string | undefined {\n try {\n const manifest = JSON.parse(\n fs.readFileSync(manifestPath, 'utf8')\n ) as Record<string, unknown>;\n for (const section of [\n 'dependencies',\n 'devDependencies',\n 'peerDependencies',\n 'optionalDependencies',\n ]) {\n const dependencies = manifest[section];\n if (\n dependencies &&\n typeof dependencies === 'object' &&\n 'vue' in dependencies\n ) {\n const version = (dependencies as Record<string, unknown>).vue;\n return typeof version === 'string' ? version : 'an unknown version';\n }\n }\n } catch (error) {\n if (\n !error ||\n typeof error !== 'object' ||\n !('code' in error) ||\n error.code !== 'ENOENT'\n ) {\n throw error;\n }\n }\n return undefined;\n}\n\nfunction inspectCompiler(\n compiler: ExactVueCompiler,\n parseTemplate?: typeof parseVueTemplate,\n templateCompiler?: TemplateCompiler\n): CompilerResolution {\n const version = compiler.version;\n if (!isSupportedVueVersion(version)) {\n return {\n ok: false,\n details: `Resolved Vue compiler version ${JSON.stringify(version)}; gt-vue supports Vue 3.3 through Vue 3.x.`,\n };\n }\n\n try {\n const templateParseOptionsSupported =\n supportsTemplateParseOptions(compiler);\n if (!parseTemplate && !templateParseOptionsSupported) {\n return {\n ok: false,\n details:\n 'The supplied compiler does not expose exact template parser options. Let the extractor resolve vue/compiler-sfc from the consuming app instead.',\n };\n }\n return {\n ok: true,\n value: {\n compiler,\n implicitSlotWhitespace: detectImplicitSlotWhitespace(compiler),\n parseTemplate,\n templateCompiler,\n templateParseOptionsSupported,\n version,\n },\n };\n } catch (error) {\n return { ok: false, details: formatResolutionError(error) };\n }\n}\n\n/** Detects the SFC parser option added after Vue 3.4. */\nfunction supportsTemplateParseOptions(compiler: ExactVueCompiler): boolean {\n const source = '<template><Probe>First\\n second</Probe></template>';\n const parseText = (whitespace: 'condense' | 'preserve') => {\n const result = compiler.parse(source, {\n templateParseOptions: { whitespace },\n });\n return collectText(result.descriptor.template?.ast);\n };\n return parseText('condense') !== parseText('preserve');\n}\n\nfunction collectText(value: unknown): string {\n if (!value || typeof value !== 'object') return '';\n let output = '';\n if ('type' in value && value.type === 2 && 'content' in value) {\n output += String(value.content);\n }\n if ('children' in value && Array.isArray(value.children)) {\n for (const child of value.children) output += collectText(child);\n }\n return output;\n}\n\n/**\n * Detects the compiler's slot-whitespace semantics instead of inferring them\n * from a semver range. Vue 3.3/3.4 use ECMAScript `trim()`, while Vue 3.5 uses\n * the HTML parser's ASCII whitespace set. A behavior probe remains exact if a\n * later Vue 3.x release backports or revises that implementation.\n */\nfunction detectImplicitSlotWhitespace(\n compiler: ExactVueCompiler\n): ImplicitSlotWhitespace {\n const result = compiler.compileTemplate({\n filename: 'gt-vue-compiler-probe.vue',\n id: 'gt-vue-compiler-probe',\n source: '<Probe><template #named>x</template> </Probe>',\n });\n if (result.errors.length > 0) {\n throw new Error(\n `The Vue compiler compatibility probe failed: ${result.errors.map(String).join('; ')}`\n );\n }\n\n const component = result.ast?.children.find(\n (node) =>\n typeof node === 'object' &&\n node !== null &&\n 'tag' in node &&\n node.tag === 'Probe'\n );\n const codegen =\n component && 'codegenNode' in component ? component.codegenNode : undefined;\n const children =\n codegen &&\n typeof codegen === 'object' &&\n 'children' in codegen &&\n codegen.children &&\n typeof codegen.children === 'object'\n ? codegen.children\n : undefined;\n const properties =\n children && 'properties' in children && Array.isArray(children.properties)\n ? children.properties\n : undefined;\n if (!properties) {\n throw new Error(\n 'The Vue compiler compatibility probe returned an unknown slot AST.'\n );\n }\n\n const hasImplicitDefault = properties.some((property) => {\n if (!property || typeof property !== 'object' || !('key' in property)) {\n return false;\n }\n const key = property.key;\n return (\n key != null &&\n typeof key === 'object' &&\n 'content' in key &&\n key.content === 'default'\n );\n });\n return hasImplicitDefault ? 'html' : 'ecmascript';\n}\n\nfunction isVueCompiler(value: unknown): value is VueCompiler {\n if (!value || typeof value !== 'object') return false;\n return (\n 'compileTemplate' in value &&\n typeof value.compileTemplate === 'function' &&\n 'parse' in value &&\n typeof value.parse === 'function' &&\n 'version' in value &&\n typeof value.version === 'string'\n );\n}\n\n/** Reads a possible CommonJS-interoperability default export. */\nfunction readDefaultExport(value: unknown): unknown {\n return value && typeof value === 'object' && 'default' in value\n ? value.default\n : undefined;\n}\n\nfunction isSupportedVueVersion(version: string): boolean {\n const match = /^(\\d+)\\.(\\d+)(?:\\.|$)/.exec(version);\n if (!match) return false;\n const major = Number(match[1]);\n const minor = Number(match[2]);\n return major === 3 && minor >= 3;\n}\n\nfunction isMissingModule(error: unknown): boolean {\n return (\n !!error &&\n typeof error === 'object' &&\n 'code' in error &&\n error.code === 'MODULE_NOT_FOUND'\n );\n}\n\nfunction formatResolutionError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vueCompiler.js","names":[],"sources":["../../src/internal/vueCompiler.ts"],"sourcesContent":["import { createRequire } from 'node:module';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport type { parse as parseVueTemplate } from '@vue/compiler-dom';\nimport type * as VueCompilerModule from '@vue/compiler-sfc';\nimport type { TemplateCompiler } from '@vue/compiler-sfc';\nimport { DecodingMode, decodeHTML } from 'entities/decode';\nimport type { VueCompiler } from '../types.js';\n\n/** Whitespace test used by Vue when it constructs an implicit default slot. */\nexport type ImplicitSlotWhitespace = 'ecmascript' | 'html';\n\nexport type ResolvedVueCompiler = {\n compiler: ExactVueCompiler;\n implicitSlotWhitespace: ImplicitSlotWhitespace;\n parseTemplate?: typeof parseVueTemplate;\n templateCompiler?: TemplateCompiler;\n templateParseOptionsSupported: boolean;\n /** Whether a valued `v-is` replaces its source element at runtime. */\n valuedVIsReplacesElement: boolean;\n version: string;\n};\n\ntype CompilerResolution =\n | { ok: true; value: ResolvedVueCompiler }\n | { ok: false; details: string };\n\nconst resolvedCompilers = new Map<string, CompilerResolution>();\nconst inspectedCompilers = new WeakMap<object, CompilerResolution>();\n\ntype ExactVueCompiler = Pick<\n typeof VueCompilerModule,\n 'compileTemplate' | 'version'\n> & {\n /** Newer SFC parser options accepted at runtime but absent in Vue 3.3 types. */\n parse: (\n source: string,\n options?: NonNullable<Parameters<typeof VueCompilerModule.parse>[1]> & {\n templateParseOptions?: Record<string, unknown>;\n }\n ) => ReturnType<typeof VueCompilerModule.parse>;\n parseTemplate?: typeof parseVueTemplate;\n /** Adjacent compiler-dom surface used to apply legacy parser options. */\n templateCompiler?: TemplateCompiler;\n};\n\n/**\n * Resolves the exact Vue compiler selected by the consuming source file.\n *\n * The `vue/compiler-sfc` export is version-locked to that installation's Vue\n * runtime. Resolving from the SFC first is important in workspaces where apps\n * intentionally use different Vue versions.\n */\nexport function resolveVueCompiler(\n file: string,\n projectRoot: string\n): CompilerResolution {\n const absoluteFile = path.isAbsolute(file)\n ? file\n : path.resolve(projectRoot, file);\n const anchors = [absoluteFile, path.join(projectRoot, 'package.json')];\n\n for (const anchor of anchors) {\n const requireFromConsumer = createRequire(anchor);\n let vueManifestPath: string;\n try {\n vueManifestPath = requireFromConsumer.resolve('vue/package.json');\n } catch (error) {\n if (isMissingModule(error)) continue;\n return {\n ok: false,\n details: formatResolutionError(error),\n };\n }\n\n let compilerPath: string;\n try {\n compilerPath = requireFromConsumer.resolve('vue/compiler-sfc');\n } catch (error) {\n return {\n ok: false,\n details: `Resolved the app's Vue package at ${vueManifestPath}, but its compiler-sfc export could not be loaded: ${formatResolutionError(error)}`,\n };\n }\n\n const cached = resolvedCompilers.get(compilerPath);\n if (cached) return cached;\n\n const resolution = loadCompiler(\n requireFromConsumer,\n compilerPath,\n vueManifestPath,\n readVueVersion(requireFromConsumer, vueManifestPath)\n );\n resolvedCompilers.set(compilerPath, resolution);\n return resolution;\n }\n\n const declaredVersion = findDeclaredVueVersion(absoluteFile, projectRoot);\n if (declaredVersion) {\n return {\n ok: false,\n details: `The project declares Vue ${JSON.stringify(declaredVersion)} but vue/compiler-sfc could not be resolved from ${absoluteFile}.`,\n };\n }\n\n return {\n ok: false,\n details: `Could not resolve vue/compiler-sfc from ${absoluteFile}.`,\n };\n}\n\n/** Validates an explicitly supplied compiler before extraction uses it. */\nexport function inspectVueCompiler(compiler: VueCompiler): CompilerResolution {\n if (!compiler || typeof compiler !== 'object') {\n return {\n ok: false,\n details: 'The supplied Vue compiler is not an object.',\n };\n }\n const cached = inspectedCompilers.get(compiler);\n if (cached) return cached;\n const exactCompiler = compiler as ExactVueCompiler;\n const resolution = isVueCompiler(compiler)\n ? inspectCompiler(\n exactCompiler,\n exactCompiler.parseTemplate,\n exactCompiler.templateCompiler\n )\n : {\n ok: false as const,\n details:\n 'The supplied object does not expose the Vue compiler-sfc API.',\n };\n inspectedCompilers.set(compiler, resolution);\n return resolution;\n}\n\nfunction loadCompiler(\n requireFromConsumer: NodeRequire,\n compilerPath: string,\n vueManifestPath: string,\n vueVersion: string | undefined\n): CompilerResolution {\n try {\n const loaded = requireFromConsumer(compilerPath) as unknown;\n const defaultExport = readDefaultExport(loaded);\n const compiler = isVueCompiler(loaded)\n ? (loaded as ExactVueCompiler)\n : isVueCompiler(defaultExport)\n ? (defaultExport as ExactVueCompiler)\n : undefined;\n if (!compiler) {\n return {\n ok: false,\n details: `The module at ${compilerPath} does not expose the Vue compiler-sfc API.`,\n };\n }\n if (vueVersion && compiler.version !== vueVersion) {\n return {\n ok: false,\n details: `The app resolves Vue ${vueVersion} but vue/compiler-sfc ${compiler.version}. Install one matching Vue package version.`,\n };\n }\n if (!isSupportedVueVersion(compiler.version)) {\n return {\n ok: false,\n details: `Resolved Vue compiler version ${JSON.stringify(compiler.version)}; gt-vue supports Vue 3.3 through Vue 3.x.`,\n };\n }\n const requireFromCompiler = createRequire(compilerPath);\n const compilerDomPath = requireFromCompiler.resolve('@vue/compiler-dom');\n const compilerDom = requireFromCompiler(compilerDomPath) as {\n compile?: TemplateCompiler['compile'];\n parse?: typeof parseVueTemplate;\n };\n const compilerDomVersion = readVueVersion(\n requireFromCompiler,\n requireFromCompiler.resolve('@vue/compiler-dom/package.json')\n );\n if (compilerDomVersion !== compiler.version) {\n return {\n ok: false,\n details: `vue/compiler-sfc ${compiler.version} resolves @vue/compiler-dom ${String(compilerDomVersion)}. Install matching Vue compiler packages.`,\n };\n }\n if (typeof compilerDom.parse !== 'function') {\n return {\n ok: false,\n details: `The template compiler at ${compilerDomPath} does not expose parse().`,\n };\n }\n if (typeof compilerDom.compile !== 'function') {\n return {\n ok: false,\n details: `The template compiler at ${compilerDomPath} does not expose compile().`,\n };\n }\n return inspectCompiler(compiler, compilerDom.parse, {\n compile: compilerDom.compile,\n parse: compilerDom.parse,\n });\n } catch (error) {\n const bunResolution = loadBunCompiler(\n requireFromConsumer,\n vueManifestPath,\n vueVersion\n );\n if (bunResolution) return bunResolution;\n return { ok: false, details: formatResolutionError(error) };\n }\n}\n\n/** Loads exact, self-contained Vue browser compilers in a compiled Bun CLI. */\nfunction loadBunCompiler(\n requireFromConsumer: NodeRequire,\n vueManifestPath: string,\n vueVersion: string | undefined\n): CompilerResolution | undefined {\n if (typeof process.versions.bun !== 'string') return undefined;\n\n try {\n const compilerSfcRoot = findInstalledPackageRoot(\n vueManifestPath,\n '@vue/compiler-sfc'\n );\n const compilerDomRoot = findInstalledPackageRoot(\n vueManifestPath,\n '@vue/compiler-dom'\n );\n if (!compilerSfcRoot || !compilerDomRoot) {\n return {\n ok: false,\n details:\n 'The Vue installation does not contain its compiler-sfc and compiler-dom dependencies.',\n };\n }\n\n const compilerPath = path.join(\n compilerSfcRoot,\n 'dist/compiler-sfc.esm-browser.js'\n );\n const compilerDomPath = path.join(\n compilerDomRoot,\n 'dist/compiler-dom.esm-browser.js'\n );\n const loaded = requireFromConsumer(compilerPath) as unknown;\n const defaultExport = readDefaultExport(loaded);\n const compiler = isVueCompiler(loaded)\n ? (loaded as ExactVueCompiler)\n : isVueCompiler(defaultExport)\n ? (defaultExport as ExactVueCompiler)\n : undefined;\n if (!compiler) {\n return {\n ok: false,\n details: `The module at ${compilerPath} does not expose the Vue compiler-sfc API.`,\n };\n }\n if (vueVersion && compiler.version !== vueVersion) {\n return {\n ok: false,\n details: `The app resolves Vue ${vueVersion} but vue/compiler-sfc ${compiler.version}. Install one matching Vue package version.`,\n };\n }\n if (!isSupportedVueVersion(compiler.version)) {\n return {\n ok: false,\n details: `Resolved Vue compiler version ${JSON.stringify(compiler.version)}; gt-vue supports Vue 3.3 through Vue 3.x.`,\n };\n }\n\n const compilerDom = requireFromConsumer(compilerDomPath) as {\n compile?: TemplateCompiler['compile'];\n parse?: typeof parseVueTemplate;\n };\n const compilerDomVersion = readPackageVersion(compilerDomRoot);\n if (compilerDomVersion !== compiler.version) {\n return {\n ok: false,\n details: `vue/compiler-sfc ${compiler.version} resolves @vue/compiler-dom ${String(compilerDomVersion)}. Install matching Vue compiler packages.`,\n };\n }\n if (typeof compilerDom.parse !== 'function') {\n return {\n ok: false,\n details: `The template compiler at ${compilerDomPath} does not expose parse().`,\n };\n }\n if (typeof compilerDom.compile !== 'function') {\n return {\n ok: false,\n details: `The template compiler at ${compilerDomPath} does not expose compile().`,\n };\n }\n const templateCompiler = createHeadlessBrowserTemplateCompiler(\n compilerDom.parse,\n compilerDom.compile\n );\n return inspectCompiler(compiler, templateCompiler.parse, templateCompiler);\n } catch (error) {\n return { ok: false, details: formatResolutionError(error) };\n }\n}\n\n/** Replaces compiler-dom's browser-only DOM entity decoder. */\nfunction createHeadlessBrowserTemplateCompiler(\n browserParse: typeof parseVueTemplate,\n browserCompile: TemplateCompiler['compile']\n): TemplateCompiler & { parse: typeof parseVueTemplate } {\n const decodeEntities = (raw: string, asAttribute = false) =>\n decodeHTML(raw, asAttribute ? DecodingMode.Attribute : DecodingMode.Legacy);\n const parse: typeof parseVueTemplate = (source, options) =>\n browserParse(source, {\n ...options,\n decodeEntities,\n } as NonNullable<Parameters<typeof browserParse>[1]>);\n const compile: TemplateCompiler['compile'] = (source, options) =>\n browserCompile(source, {\n ...options,\n decodeEntities,\n } as NonNullable<Parameters<typeof browserCompile>[1]>);\n return { compile, parse };\n}\n\n/** Finds one dependency relative to the physical Vue installation on disk. */\nfunction findInstalledPackageRoot(\n vueManifestPath: string,\n packageName: string\n): string | undefined {\n const packageSegments = packageName.split('/');\n let directory = path.dirname(vueManifestPath);\n while (true) {\n const candidate =\n path.basename(directory) === 'node_modules'\n ? path.join(directory, ...packageSegments)\n : path.join(directory, 'node_modules', ...packageSegments);\n if (fs.existsSync(path.join(candidate, 'package.json'))) return candidate;\n const parent = path.dirname(directory);\n if (parent === directory) return undefined;\n directory = parent;\n }\n}\n\nfunction readPackageVersion(packageRoot: string): string | undefined {\n try {\n const manifest = JSON.parse(\n fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf8')\n ) as { version?: unknown };\n return typeof manifest.version === 'string' ? manifest.version : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction readVueVersion(\n requireFromConsumer: NodeRequire,\n manifestPath: string\n): string | undefined {\n try {\n const manifest = requireFromConsumer(manifestPath) as { version?: unknown };\n return typeof manifest.version === 'string' ? manifest.version : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Finds an installed-but-missing declaration that bundled fallback could hide. */\nfunction findDeclaredVueVersion(\n absoluteFile: string,\n projectRoot: string\n): string | undefined {\n const stop = path.resolve(projectRoot);\n let directory = path.dirname(absoluteFile);\n while (true) {\n const version = readDeclaredVueVersion(\n path.join(directory, 'package.json')\n );\n if (version) return version;\n if (directory === stop || directory === path.dirname(directory)) break;\n directory = path.dirname(directory);\n }\n return readDeclaredVueVersion(path.join(stop, 'package.json'));\n}\n\nfunction readDeclaredVueVersion(manifestPath: string): string | undefined {\n try {\n const manifest = JSON.parse(\n fs.readFileSync(manifestPath, 'utf8')\n ) as Record<string, unknown>;\n for (const section of [\n 'dependencies',\n 'devDependencies',\n 'peerDependencies',\n 'optionalDependencies',\n ]) {\n const dependencies = manifest[section];\n if (\n dependencies &&\n typeof dependencies === 'object' &&\n 'vue' in dependencies\n ) {\n const version = (dependencies as Record<string, unknown>).vue;\n return typeof version === 'string' ? version : 'an unknown version';\n }\n }\n } catch (error) {\n if (\n !error ||\n typeof error !== 'object' ||\n !('code' in error) ||\n error.code !== 'ENOENT'\n ) {\n throw error;\n }\n }\n return undefined;\n}\n\nfunction inspectCompiler(\n compiler: ExactVueCompiler,\n parseTemplate?: typeof parseVueTemplate,\n templateCompiler?: TemplateCompiler\n): CompilerResolution {\n const version = compiler.version;\n if (!isSupportedVueVersion(version)) {\n return {\n ok: false,\n details: `Resolved Vue compiler version ${JSON.stringify(version)}; gt-vue supports Vue 3.3 through Vue 3.x.`,\n };\n }\n\n try {\n const templateParseOptionsSupported =\n supportsTemplateParseOptions(compiler);\n if (!parseTemplate && !templateParseOptionsSupported) {\n return {\n ok: false,\n details:\n 'The supplied compiler does not expose exact template parser options. Let the extractor resolve vue/compiler-sfc from the consuming app instead.',\n };\n }\n const compilerBehavior = detectTemplateCompilerBehavior(compiler);\n return {\n ok: true,\n value: {\n compiler,\n implicitSlotWhitespace: compilerBehavior.implicitSlotWhitespace,\n parseTemplate,\n templateCompiler,\n templateParseOptionsSupported,\n valuedVIsReplacesElement: compilerBehavior.valuedVIsReplacesElement,\n version,\n },\n };\n } catch (error) {\n return { ok: false, details: formatResolutionError(error) };\n }\n}\n\n/** Detects the SFC parser option added after Vue 3.4. */\nfunction supportsTemplateParseOptions(compiler: ExactVueCompiler): boolean {\n const source = '<template><Probe>First\\n second</Probe></template>';\n const parseText = (whitespace: 'condense' | 'preserve') => {\n const result = compiler.parse(source, {\n templateParseOptions: { whitespace },\n });\n return collectText(result.descriptor.template?.ast);\n };\n return parseText('condense') !== parseText('preserve');\n}\n\nfunction collectText(value: unknown): string {\n if (!value || typeof value !== 'object') return '';\n let output = '';\n if ('type' in value && value.type === 2 && 'content' in value) {\n output += String(value.content);\n }\n if ('children' in value && Array.isArray(value.children)) {\n for (const child of value.children) output += collectText(child);\n }\n return output;\n}\n\n/**\n * Detects version-sensitive template semantics instead of inferring them from\n * a semver range. Vue 3.3/3.4 use ECMAScript `trim()` for slot whitespace,\n * while Vue 3.5 uses the HTML parser's ASCII set. Vue 3.3 also compiles valued\n * `v-is` as a dynamic selector, while newer Vue releases retain the source\n * element. One behavior probe remains exact if either behavior is backported.\n */\nfunction detectTemplateCompilerBehavior(compiler: ExactVueCompiler): {\n implicitSlotWhitespace: ImplicitSlotWhitespace;\n valuedVIsReplacesElement: boolean;\n} {\n const result = compiler.compileTemplate({\n filename: 'gt-vue-compiler-probe.vue',\n id: 'gt-vue-compiler-probe',\n source:\n '<Probe><template #named>x</template> </Probe><div v-is=\"Probe\" />',\n });\n if (result.errors.length > 0) {\n throw new Error(\n `The Vue compiler compatibility probe failed: ${result.errors.map(String).join('; ')}`\n );\n }\n\n const component = result.ast?.children.find(\n (node) =>\n typeof node === 'object' &&\n node !== null &&\n 'tag' in node &&\n node.tag === 'Probe'\n );\n const codegen =\n component && 'codegenNode' in component ? component.codegenNode : undefined;\n const children =\n codegen &&\n typeof codegen === 'object' &&\n 'children' in codegen &&\n codegen.children &&\n typeof codegen.children === 'object'\n ? codegen.children\n : undefined;\n const properties =\n children && 'properties' in children && Array.isArray(children.properties)\n ? children.properties\n : undefined;\n if (!properties) {\n throw new Error(\n 'The Vue compiler compatibility probe returned an unknown slot AST.'\n );\n }\n\n const hasImplicitDefault = properties.some((property) => {\n if (!property || typeof property !== 'object' || !('key' in property)) {\n return false;\n }\n const key = property.key;\n return (\n key != null &&\n typeof key === 'object' &&\n 'content' in key &&\n key.content === 'default'\n );\n });\n const vIsElement = result.ast?.children.find(\n (node) =>\n typeof node === 'object' &&\n node !== null &&\n 'tag' in node &&\n node.tag === 'div'\n );\n return {\n implicitSlotWhitespace: hasImplicitDefault ? 'html' : 'ecmascript',\n valuedVIsReplacesElement: Boolean(\n vIsElement && 'tagType' in vIsElement && vIsElement.tagType === 1\n ),\n };\n}\n\nfunction isVueCompiler(value: unknown): value is VueCompiler {\n if (!value || typeof value !== 'object') return false;\n return (\n 'compileTemplate' in value &&\n typeof value.compileTemplate === 'function' &&\n 'parse' in value &&\n typeof value.parse === 'function' &&\n 'version' in value &&\n typeof value.version === 'string'\n );\n}\n\n/** Reads a possible CommonJS-interoperability default export. */\nfunction readDefaultExport(value: unknown): unknown {\n return value && typeof value === 'object' && 'default' in value\n ? value.default\n : undefined;\n}\n\nfunction isSupportedVueVersion(version: string): boolean {\n const match = /^(\\d+)\\.(\\d+)(?:\\.|$)/.exec(version);\n if (!match) return false;\n const major = Number(match[1]);\n const minor = Number(match[2]);\n return major === 3 && minor >= 3;\n}\n\nfunction isMissingModule(error: unknown): boolean {\n return (\n !!error &&\n typeof error === 'object' &&\n 'code' in error &&\n error.code === 'MODULE_NOT_FOUND'\n );\n}\n\nfunction formatResolutionError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts all statically discoverable gt-vue messages owned by a project.
|
|
3
|
+
*
|
|
4
|
+
* The project boundary owns workspace discovery, Vue compiler configuration,
|
|
5
|
+
* Vite aliases, local-module resolution, file matching, hashing, and atomic
|
|
6
|
+
* diagnostics so callers do not need any Vue-specific orchestration.
|
|
7
|
+
*/
|
|
8
|
+
export { extractFromVueProject } from './internal/project/extractFromVueProject.js';
|
|
9
|
+
export { mergeVueProjectExtraction } from './internal/project/mergeVueProjectExtraction.js';
|
|
10
|
+
export type { VueProjectExtractionOptions, VueProjectInspection, VueProjectExtractionOutput, VueProjectExtractionResult, } from './types.js';
|
|
11
|
+
export type { InlineExtractionOutput } from './internal/project/mergeVueProjectExtraction.js';
|
package/dist/project.js
ADDED