@generaltranslation/vue-extractor 0.1.0-iris.1 → 0.1.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.
|
@@ -223,7 +223,14 @@ function malformedSuffixHasGTProvenance(sourceCode, filePath, options, language,
|
|
|
223
223
|
}
|
|
224
224
|
/** Removes block closers orphaned when recovery starts inside a function. */
|
|
225
225
|
function trimTrailingRecoveryClosers(sourceCode) {
|
|
226
|
-
|
|
226
|
+
let end = sourceCode.length;
|
|
227
|
+
while (end > 0 && sourceCode[end - 1].trim() === "") end -= 1;
|
|
228
|
+
if (sourceCode[end - 1] !== "}") return sourceCode.slice(0, end);
|
|
229
|
+
do {
|
|
230
|
+
end -= 1;
|
|
231
|
+
while (end > 0 && sourceCode[end - 1].trim() === "") end -= 1;
|
|
232
|
+
} while (sourceCode[end - 1] === "}");
|
|
233
|
+
return sourceCode.slice(0, end);
|
|
227
234
|
}
|
|
228
235
|
/** Chooses the grammar that parsed furthest before a recoverable error. */
|
|
229
236
|
function selectMalformedSuffixLanguage(sourceCode, languages) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extractFromVueSource.js","names":["initModuleLexer","parseModuleImports"],"sources":["../../src/internal/extractFromVueSource.ts"],"sourcesContent":["import { extname } from 'node:path';\nimport {\n init as initModuleLexer,\n parse as parseModuleImports,\n} from 'es-module-lexer';\nimport type { ParserPlugin } from '@babel/parser';\nimport type { SFCBlock, TemplateCompiler } from '#vue-compiler-sfc';\nimport type { RootNode } from '@vue/compiler-dom';\nimport type {\n VueCompilerOptions,\n VueExtractionOptions,\n VueExtractionOutput,\n} from '../types.js';\nimport {\n collectVueScriptImports,\n createVueScriptAnalysis,\n exposeVueScriptImportsToTemplate,\n parseVueScript,\n type VueScriptAnalysis,\n} from './script.js';\nimport { parseScriptAst } from './script/parser.js';\nimport {\n shiftCompilerAstLocations,\n shiftCompilerLocation,\n} from './compilerAst.js';\nimport {\n createLocalModuleResolver,\n type LocalModuleResolver,\n} from './script/localModules.js';\nimport { parseVueTemplate } from './template.js';\nimport type { TemplateBindings, VueExtractionContext } from './types.js';\nimport { addVueError, createVueExtractionContext } from './utils.js';\nimport {\n inspectVueCompiler,\n resolveVueCompiler,\n type ResolvedVueCompiler,\n} from './vueCompiler.js';\n\nconst DEFAULT_SURROUNDING_LINE_COUNT = 5;\nconst MAX_MALFORMED_SUFFIX_RECOVERIES = 64;\n\n/** Parser options supported at runtime but omitted from Vue 3.3 declarations. */\ntype CompatibleTemplateParserOptions = NonNullable<\n Parameters<TemplateCompiler['parse']>[1]\n> & {\n expressionPlugins?: ParserPlugin[];\n};\n\n/** compiler-dom options supported at runtime across the supported Vue range. */\ntype CompatibleCompilerDomParserOptions = NonNullable<\n Parameters<NonNullable<ResolvedVueCompiler['parseTemplate']>>[1]\n> & {\n expressionPlugins?: ParserPlugin[];\n};\n\n/**\n * Extracts General Translation content from one Vue SFC or JavaScript file.\n *\n * This low-level API lets callers parse an individual in-memory source file.\n * Use `@generaltranslation/vue-extractor/project` when discovery, I/O,\n * compiler configuration, hashing, and deduplication should be handled by the\n * package as one project-level operation.\n */\nexport async function extractFromVueSource(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions = {}\n): Promise<VueExtractionOutput> {\n const results: VueExtractionOutput['results'] = [];\n const errors: string[] = [];\n const warnings = new Set<string>();\n const context = createVueExtractionContext(\n filePath,\n sourceCode,\n options.projectRoot ?? process.cwd(),\n options.includeSourceCodeContext ?? false,\n options.surroundingLineCount ?? DEFAULT_SURROUNDING_LINE_COUNT,\n results,\n errors,\n warnings\n );\n const extension = extname(filePath).toLowerCase();\n const scriptAnalysis = createVueScriptAnalysis();\n scriptAnalysis.entryFile = filePath;\n scriptAnalysis.localModules = createLocalModuleResolver(\n options.resolveModule\n );\n\n if (extension === '.vue') {\n const compilerResolution =\n options.compiler !== undefined\n ? inspectVueCompiler(options.compiler)\n : resolveVueCompiler(filePath, options.projectRoot ?? process.cwd());\n if (!compilerResolution.ok) {\n addVueError(\n context,\n undefined,\n 'Could not load the Vue compiler used by this single-file component',\n `Install a supported Vue 3 compiler beside the app. ${compilerResolution.details}`\n );\n return { results, errors, warnings: [...warnings] };\n }\n context.implicitSlotWhitespace =\n compilerResolution.value.implicitSlotWhitespace;\n context.valuedVIsReplacesElement =\n compilerResolution.value.valuedVIsReplacesElement;\n parseVueSingleFileComponent(\n sourceCode,\n context,\n options.compilerOptions ?? {},\n compilerResolution.value,\n scriptAnalysis\n );\n } else {\n if (\n options.requireGTProvenance &&\n !(await hasStandaloneGTProvenance(sourceCode, filePath, options))\n ) {\n return { results, errors, warnings: [...warnings] };\n }\n parseVueScript(\n sourceCode,\n languageFromExtension(extension),\n context,\n createTemplateBindings(),\n false,\n scriptAnalysis,\n false\n );\n }\n\n return { results, errors, warnings: [...warnings] };\n}\n\n/**\n * Uses the declared language, then permissive TSX and Flow, to prove gt-vue\n * ownership without changing the grammar used for extraction.\n *\n * The normal extraction pass still parses the file according to its extension.\n * Diagnostics caused only by GT-shaped names do not establish ownership. This\n * keeps mixed-framework dispatch from making otherwise valid React files fatal.\n */\nasync function hasStandaloneGTProvenance(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions\n): Promise<boolean> {\n const extension = extname(filePath).toLowerCase();\n const probeLanguages = new Set<StandaloneProbeLanguage>([\n languageFromExtension(extension),\n 'tsx',\n 'flow',\n ]);\n const localModules = createLocalModuleResolver(options.resolveModule);\n for (const language of probeLanguages) {\n const probe = probeStandaloneGTProvenance(\n sourceCode,\n filePath,\n options,\n language,\n localModules\n );\n if (probe.hasProvenance) return true;\n if (probe.parsed) return false;\n }\n const suffixSelection = selectMalformedSuffixLanguage(\n sourceCode,\n probeLanguages\n );\n const moduleRecovery = suffixSelection?.recoverable\n ? await recoverMalformedModuleReferences(\n sourceCode,\n filePath,\n options,\n probeLanguages,\n localModules\n )\n : { hasProvenance: false, preamble: '' };\n if (moduleRecovery.hasProvenance) {\n return true;\n }\n return hasMalformedStandaloneGTProvenance(\n sourceCode,\n filePath,\n options,\n probeLanguages,\n localModules,\n moduleRecovery.preamble\n );\n}\n\n/**\n * Recovers static module ownership without reparsing an entire malformed file.\n *\n * es-module-lexer ignores comments and literal contents while continuing past\n * unrelated syntax errors. Each declaration is then analyzed on its own,\n * preserving type-only and binding-specific local-barrel semantics. Parseable\n * declarations are also returned as a preamble for later recovered uses.\n */\nasync function recoverMalformedModuleReferences(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions,\n languages: ReadonlySet<StandaloneProbeLanguage>,\n localModules: LocalModuleResolver\n): Promise<{ hasProvenance: boolean; preamble: string }> {\n await initModuleLexer;\n let imports: ReturnType<typeof parseModuleImports>[0];\n try {\n [imports] = parseModuleImports(sourceCode);\n } catch {\n imports = [];\n }\n\n const declarations = new Set<string>();\n for (const moduleImport of imports) {\n if (!moduleImport.n) continue;\n for (const declaration of readModuleStatementCandidates(\n sourceCode,\n moduleImport.ss,\n moduleImport.se\n )) {\n for (const language of languages) {\n const probe = probeStandaloneGTProvenance(\n declaration,\n filePath,\n options,\n language,\n localModules\n );\n if (probe.hasProvenance) {\n return { hasProvenance: true, preamble: '' };\n }\n if (probe.parsed) {\n declarations.add(declaration);\n break;\n }\n }\n if (declarations.has(declaration)) break;\n }\n }\n return {\n hasProvenance: false,\n preamble: [...declarations].join('\\n'),\n };\n}\n\n/** Returns small statement slices enclosing one lexed module reference. */\nfunction readModuleStatementCandidates(\n sourceCode: string,\n statementStart: number,\n specifierEnd: number\n): string[] {\n const precedingBoundaries = [';', '\\n', '{', '}']\n .map((separator) => sourceCode.lastIndexOf(separator, statementStart - 1))\n .filter((offset) => offset >= 0)\n .map((offset) => offset + 1);\n precedingBoundaries.push(0);\n const followingBoundaries = [';', '\\n', '}']\n .map((separator) => sourceCode.indexOf(separator, specifierEnd))\n .filter((offset) => offset >= 0)\n .map((offset) => offset + 1);\n const starts = [\n ...precedingBoundaries.sort((left, right) => right - left),\n statementStart,\n ];\n const ends = [\n ...followingBoundaries.sort((left, right) => left - right),\n specifierEnd,\n ];\n const candidates = new Set<string>();\n for (const start of starts) {\n for (const end of ends) {\n if (end <= start) continue;\n const candidate = sourceCode.slice(start, end).trim();\n if (candidate) candidates.add(candidate);\n }\n }\n return [...candidates];\n}\n\ntype StandaloneProbeLanguage = 'flow' | 'js' | 'jsx' | 'ts' | 'tsx';\n\n/** Runs one syntax-tolerant, read-only provenance classification pass. */\nfunction probeStandaloneGTProvenance(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions,\n language: StandaloneProbeLanguage,\n localModules: LocalModuleResolver\n): { hasProvenance: boolean; parsed: boolean } {\n const results: VueExtractionOutput['results'] = [];\n const errors: string[] = [];\n const warnings = new Set<string>();\n const projectRoot = options.projectRoot ?? process.cwd();\n const context = createVueExtractionContext(\n filePath,\n sourceCode,\n projectRoot,\n false,\n options.surroundingLineCount ?? DEFAULT_SURROUNDING_LINE_COUNT,\n results,\n errors,\n warnings\n );\n const analysis = createVueScriptAnalysis();\n analysis.entryFile = filePath;\n analysis.localModules = localModules;\n const parsed = parseVueScript(\n sourceCode,\n language,\n context,\n createTemplateBindings(),\n false,\n analysis,\n false\n );\n if (results.length > 0 || analysisHasGTProvenance(analysis)) {\n return { hasProvenance: true, parsed };\n }\n return { hasProvenance: false, parsed };\n}\n\n/**\n * Finds concrete module references when malformed syntax prevents a full AST.\n *\n * Each supported grammar recovers a complete prefix, then the grammar that\n * parsed furthest gets a bounded suffix search. Unterminated literal errors\n * never receive suffix recovery, so literal contents cannot become code.\n */\nfunction hasMalformedStandaloneGTProvenance(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions,\n languages: ReadonlySet<StandaloneProbeLanguage>,\n localModules: LocalModuleResolver,\n recoveredPreamble: string\n): boolean {\n for (const language of languages) {\n if (\n leadingStatementPrefixHasGTProvenance(\n sourceCode,\n filePath,\n options,\n language,\n localModules\n )\n ) {\n return true;\n }\n }\n const suffixSelection = selectMalformedSuffixLanguage(sourceCode, languages);\n return Boolean(\n suffixSelection?.recoverable &&\n malformedSuffixHasGTProvenance(\n sourceCode,\n filePath,\n options,\n suffixSelection.language,\n localModules,\n recoveredPreamble\n )\n );\n}\n\n/** Preserves CommonJS and TypeScript import ownership before a syntax error. */\nfunction leadingStatementPrefixHasGTProvenance(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions,\n language: StandaloneProbeLanguage,\n localModules: LocalModuleResolver\n): boolean {\n let errorOffset: number;\n try {\n parseScriptAst(sourceCode, language);\n return false;\n } catch (error) {\n const offset = (error as { pos?: unknown }).pos;\n if (typeof offset !== 'number') return false;\n errorOffset = offset;\n }\n const boundary = Math.max(\n sourceCode.lastIndexOf(';', errorOffset - 1) + 1,\n sourceCode.lastIndexOf('\\n', errorOffset - 1) + 1,\n sourceCode.lastIndexOf('}', errorOffset - 1) + 1\n );\n if (boundary <= 0) return false;\n const prefix = sourceCode.slice(0, boundary).trimEnd();\n if (!prefix) return false;\n const probe = probeStandaloneGTProvenance(\n prefix,\n filePath,\n options,\n language,\n localModules\n );\n return probe.hasProvenance;\n}\n\n/** Recovers later imports and CommonJS calls after a bounded number of errors. */\nfunction malformedSuffixHasGTProvenance(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions,\n language: StandaloneProbeLanguage,\n localModules: LocalModuleResolver,\n recoveredPreamble: string\n): boolean {\n let remaining = sourceCode;\n for (let attempt = 0; attempt < MAX_MALFORMED_SUFFIX_RECOVERIES; attempt++) {\n let errorOffset: number;\n try {\n parseScriptAst(remaining, language);\n const recoveredSource = recoveredPreamble\n ? `${recoveredPreamble}\\n${remaining}`\n : remaining;\n const recoveredProbe = probeStandaloneGTProvenance(\n recoveredSource,\n filePath,\n options,\n language,\n localModules\n );\n if (recoveredProbe.parsed) return recoveredProbe.hasProvenance;\n // The remaining suffix may already contain the declaration retained in\n // the preamble. Probe it alone to avoid a duplicate-binding parse error.\n return probeStandaloneGTProvenance(\n remaining,\n filePath,\n options,\n language,\n localModules\n ).hasProvenance;\n } catch (error) {\n const parseError = readRecoverableParseError(error);\n if (!parseError) return false;\n errorOffset = parseError.offset;\n }\n const boundary = findMalformedRecoveryBoundary(remaining, errorOffset);\n if (boundary <= 0 || boundary >= remaining.length) return false;\n remaining = remaining.slice(boundary);\n const recoveredSource = recoveredPreamble\n ? `${recoveredPreamble}\\n${remaining}`\n : remaining;\n let probe = probeStandaloneGTProvenance(\n recoveredSource,\n filePath,\n options,\n language,\n localModules\n );\n if (!probe.parsed && recoveredPreamble) {\n const trimmedRemaining = trimTrailingRecoveryClosers(remaining);\n if (trimmedRemaining !== remaining) {\n probe = probeStandaloneGTProvenance(\n `${recoveredPreamble}\\n${trimmedRemaining}`,\n filePath,\n options,\n language,\n localModules\n );\n }\n }\n if (probe.hasProvenance) return true;\n if (probe.parsed) return false;\n }\n return false;\n}\n\n/** Removes block closers orphaned when recovery starts inside a function. */\nfunction trimTrailingRecoveryClosers(sourceCode: string): string {\n return sourceCode.replace(/(?:\\s*\\}\\s*)+$/u, '').trimEnd();\n}\n\n/** Chooses the grammar that parsed furthest before a recoverable error. */\nfunction selectMalformedSuffixLanguage(\n sourceCode: string,\n languages: ReadonlySet<StandaloneProbeLanguage>\n): { language: StandaloneProbeLanguage; recoverable: boolean } | undefined {\n let selected:\n | { language: StandaloneProbeLanguage; recoverable: boolean }\n | undefined;\n let furthestOffset = -1;\n for (const language of languages) {\n try {\n parseScriptAst(sourceCode, language);\n } catch (error) {\n const parseError = readParseError(error);\n if (parseError && parseError.offset > furthestOffset) {\n selected = {\n language,\n recoverable: parseError.recoverable,\n };\n furthestOffset = parseError.offset;\n }\n }\n }\n return selected;\n}\n\n/** Rejects recovery that could reinterpret unterminated literal contents. */\nfunction readRecoverableParseError(\n error: unknown\n): { offset: number } | undefined {\n const parsed = readParseError(error);\n return parsed?.recoverable ? { offset: parsed.offset } : undefined;\n}\n\n/** Reads one Babel parser error without trusting unterminated literal state. */\nfunction readParseError(\n error: unknown\n): { offset: number; recoverable: boolean } | undefined {\n const parsed = error as { pos?: unknown; reasonCode?: unknown };\n if (typeof parsed.pos !== 'number') return undefined;\n const unsafeReasonCodes = new Set([\n 'UnterminatedComment',\n 'UnterminatedJsxContent',\n 'UnterminatedRegExp',\n 'UnterminatedString',\n 'UnterminatedTemplate',\n ]);\n return {\n offset: parsed.pos,\n recoverable:\n typeof parsed.reasonCode !== 'string' ||\n !unsafeReasonCodes.has(parsed.reasonCode),\n };\n}\n\n/** Selects the first statement-like boundary after a parser error. */\nfunction findMalformedRecoveryBoundary(\n sourceCode: string,\n errorOffset: number\n): number {\n const candidates = [';', '\\n', '}']\n .map((separator) => sourceCode.indexOf(separator, errorOffset))\n .filter((offset) => offset >= 0);\n return candidates.length > 0 ? Math.min(...candidates) + 1 : -1;\n}\n\n/** Returns whether permissive analysis reached a concrete gt-vue identity. */\nfunction analysisHasGTProvenance(analysis: VueScriptAnalysis): boolean {\n return analysis.hasGTSourceReference;\n}\n\nfunction parseVueSingleFileComponent(\n source: string,\n context: VueExtractionContext,\n compilerOptions: VueCompilerOptions,\n resolvedCompiler: ResolvedVueCompiler,\n scriptAnalysis: VueScriptAnalysis\n): void {\n const { compiler } = resolvedCompiler;\n if (\n compilerOptions.delimiters &&\n !resolvedCompiler.templateCompiler &&\n !resolvedCompiler.templateParseOptionsSupported\n ) {\n addVueError(\n context,\n undefined,\n 'Could not safely apply custom Vue template delimiters with the supplied compiler',\n 'Let the extractor resolve the consuming app compiler, or supply a Vue compiler that applies templateParseOptions during SFC parsing'\n );\n return;\n }\n const expressionPlugins: ParserPlugin[] = sourceUsesTypeScript(source)\n ? ['typescript']\n : [];\n const templateCompiler = createConfiguredTemplateCompiler(\n resolvedCompiler,\n compilerOptions,\n expressionPlugins,\n true\n );\n const result = compiler.parse(source, {\n ...(templateCompiler && { compiler: templateCompiler }),\n filename: context.file,\n pad: 'space',\n sourceMap: false,\n templateParseOptions: {\n ...compilerOptions,\n comments: true,\n expressionPlugins,\n },\n });\n\n for (const error of result.errors) {\n const compilerError =\n typeof error === 'string'\n ? undefined\n : (error as SyntaxError & {\n loc?: Parameters<typeof normalizeCompilerLocation>[0];\n });\n addVueError(\n context,\n compilerError?.loc\n ? normalizeCompilerLocation(compilerError.loc)\n : undefined,\n `Could not parse a gt-vue single-file component: ${typeof error === 'string' ? error : error.message}`,\n 'Fix the Vue template syntax before extracting translations'\n );\n }\n // Vue's SFC parser recovers a partial AST for malformed markup. Publishing\n // translations from that recovery tree can replace complete catalogs with\n // an incomplete source set, so structural parse errors are file-fatal.\n if (result.errors.length > 0) return;\n\n const bindings = createTemplateBindings();\n collectScriptBlockImports(result.descriptor.script, scriptAnalysis);\n collectScriptBlockImports(result.descriptor.scriptSetup, scriptAnalysis);\n const scriptValid = parseScriptBlock(\n result.descriptor.script,\n false,\n context,\n bindings,\n scriptAnalysis\n );\n if (result.descriptor.scriptSetup) {\n exposeVueScriptImportsToTemplate(scriptAnalysis, bindings);\n }\n const scriptSetupValid = parseScriptBlock(\n result.descriptor.scriptSetup,\n true,\n context,\n bindings,\n scriptAnalysis\n );\n if (!scriptValid || !scriptSetupValid) {\n context.results.length = 0;\n return;\n }\n\n const template = result.descriptor.template;\n if (!template) return;\n if (template.lang && template.lang !== 'html') {\n addVueError(\n context,\n template.loc,\n `Found unsupported Vue template language \"${template.lang}\"`,\n 'Use a standard HTML Vue template for gt-vue extraction'\n );\n context.results.length = 0;\n return;\n }\n if (template.src) {\n addVueError(\n context,\n template.loc,\n 'Found an externally sourced Vue template',\n 'Keep the template in the .vue file so gt-vue can extract it'\n );\n context.results.length = 0;\n return;\n }\n const templateAst = resolvedCompiler.parseTemplate\n ? parseTemplateWithCompiler(\n template.content,\n compilerOptions,\n expressionPlugins,\n true,\n context,\n resolvedCompiler.parseTemplate,\n template.loc.start\n )\n : (template.ast as unknown as RootNode);\n if (templateAst) {\n const templateResultStart = context.results.length;\n const templateErrorStart = context.errors.length;\n parseVueTemplate(templateAst, bindings, expressionPlugins, context);\n if (\n context.errors.length === templateErrorStart &&\n template.content.includes('<!--') &&\n !matchesProductionTemplate(\n source,\n compilerOptions,\n expressionPlugins,\n bindings,\n context,\n templateResultStart,\n resolvedCompiler\n )\n ) {\n context.results.length = templateResultStart;\n addVueError(\n context,\n template.loc,\n 'Found translatable Vue content whose hash changes between development and production',\n 'Remove comments that split translatable text or whitespace, or move those comments outside gt-vue <T> components'\n );\n }\n }\n}\n\n/**\n * Verifies that Vite's production comment stripping preserves extracted data.\n *\n * Vue parses templates with comments in development and without them in\n * production. Removing a comment can renormalize adjacent whitespace, so a\n * single persisted catalog key cannot serve both builds. The second parse is\n * limited to templates that contain comments and never executes project code.\n */\nfunction matchesProductionTemplate(\n source: string,\n compilerOptions: VueCompilerOptions,\n expressionPlugins: ParserPlugin[],\n bindings: TemplateBindings,\n context: VueExtractionContext,\n developmentResultStart: number,\n resolvedCompiler: ResolvedVueCompiler\n): boolean {\n const { compiler } = resolvedCompiler;\n const templateCompiler = createConfiguredTemplateCompiler(\n resolvedCompiler,\n compilerOptions,\n expressionPlugins,\n false\n );\n const production = compiler.parse(source, {\n ...(templateCompiler && { compiler: templateCompiler }),\n filename: context.file,\n pad: 'space',\n sourceMap: false,\n templateParseOptions: {\n ...compilerOptions,\n comments: false,\n expressionPlugins,\n },\n });\n const template = production.descriptor.template;\n if (production.errors.length > 0 || !template) return false;\n\n const productionContext: VueExtractionContext = {\n ...context,\n errors: [],\n results: [],\n warnings: new Set(),\n };\n const templateAst = resolvedCompiler.parseTemplate\n ? parseTemplateWithCompiler(\n template.content,\n compilerOptions,\n expressionPlugins,\n false,\n productionContext,\n resolvedCompiler.parseTemplate,\n template.loc.start\n )\n : (template.ast as unknown as RootNode);\n if (!templateAst) return false;\n parseVueTemplate(templateAst, bindings, expressionPlugins, productionContext);\n if (productionContext.errors.length > 0) return false;\n\n const developmentResults = context.results.slice(developmentResultStart);\n return (\n comparableTemplateResults(developmentResults) ===\n comparableTemplateResults(productionContext.results)\n );\n}\n\n/**\n * Applies hash-affecting options during compiler-sfc's structural parse.\n *\n * Vue 3.3 ignores `templateParseOptions`, which can make delimiter-shaped text\n * close an SFC block before the exact template-content parse runs. Supplying\n * the adjacent compiler-dom parser makes the descriptor structural parse use\n * the same delimiters and whitespace. Vue 3.3 caches SFC parses using the\n * parser function's string form, so its deterministic identity includes every\n * closure-captured option to prevent cross-option cache poisoning.\n */\nfunction createConfiguredTemplateCompiler(\n resolvedCompiler: ResolvedVueCompiler,\n compilerOptions: VueCompilerOptions,\n expressionPlugins: ParserPlugin[],\n comments: boolean\n): TemplateCompiler | undefined {\n const templateCompiler = resolvedCompiler.templateCompiler;\n if (!templateCompiler) return undefined;\n\n const parse: TemplateCompiler['parse'] = (source, baseOptions) => {\n const options: CompatibleTemplateParserOptions = {\n ...baseOptions,\n ...compilerOptions,\n comments,\n expressionPlugins,\n };\n return templateCompiler.parse(source, options);\n };\n const identity = JSON.stringify({\n comments,\n delimiters: compilerOptions.delimiters,\n expressionPlugins,\n version: resolvedCompiler.version,\n whitespace: compilerOptions.whitespace,\n });\n Object.defineProperty(parse, 'toString', {\n value: () => `gtVueTemplateParse:${identity}`,\n });\n\n return { compile: templateCompiler.compile, parse };\n}\n\n/** Parses template content with the exact compiler-dom beside consumer Vue. */\nfunction parseTemplateWithCompiler(\n source: string,\n compilerOptions: VueCompilerOptions,\n expressionPlugins: ParserPlugin[],\n comments: boolean,\n context: VueExtractionContext,\n parseTemplate: NonNullable<ResolvedVueCompiler['parseTemplate']>,\n origin: CompilerPosition\n): RootNode | undefined {\n const errors: Array<SyntaxError & { loc?: ExtractionLocationLike }> = [];\n const options: CompatibleCompilerDomParserOptions = {\n ...compilerOptions,\n comments,\n expressionPlugins,\n onError(error) {\n errors.push(error as SyntaxError & { loc?: ExtractionLocationLike });\n },\n };\n const ast = parseTemplate(source, options);\n if (errors.length === 0) {\n shiftCompilerAstLocations(ast, origin);\n return ast;\n }\n const shiftedErrorPositions = new WeakSet<object>();\n for (const error of errors) {\n if (error.loc) {\n shiftCompilerLocation(error.loc, origin, shiftedErrorPositions);\n }\n addVueError(\n context,\n error.loc ? normalizeCompilerLocation(error.loc) : undefined,\n `Could not parse a gt-vue template: ${error.message}`,\n 'Fix the Vue template syntax before extracting translations'\n );\n }\n return undefined;\n}\n\ntype ExtractionLocationLike = Parameters<typeof normalizeCompilerLocation>[0];\ntype CompilerPosition = {\n column: number;\n line: number;\n offset: number;\n};\n\n/** Omits location-only metadata while comparing persisted template content. */\nfunction comparableTemplateResults(\n results: VueExtractionOutput['results']\n): string {\n return JSON.stringify(\n results.map((result) => ({\n dataFormat: result.dataFormat,\n metadata: {\n context: result.metadata.context,\n id: result.metadata.id,\n maxChars: result.metadata.maxChars,\n requiresReview: result.metadata.requiresReview,\n },\n source: result.source,\n }))\n );\n}\n\nfunction collectScriptBlockImports(\n block: SFCBlock | null,\n scriptAnalysis: VueScriptAnalysis\n): void {\n if (!block || block.src || !isSupportedScriptLanguage(block.lang)) return;\n collectVueScriptImports(block.content, block.lang, scriptAnalysis);\n}\n\nfunction parseScriptBlock(\n block: SFCBlock | null,\n exposeToTemplate: boolean,\n context: VueExtractionContext,\n bindings: TemplateBindings,\n scriptAnalysis: VueScriptAnalysis\n): boolean {\n if (!block) return true;\n if (block.src) {\n addVueError(\n context,\n block.loc,\n 'Found an externally sourced Vue script block',\n 'Keep translation calls and gt-vue imports in the .vue file'\n );\n return false;\n }\n if (!isSupportedScriptLanguage(block.lang)) {\n addVueError(\n context,\n block.loc,\n `Found unsupported Vue script language \"${block.lang}\"`,\n 'Use JavaScript or TypeScript for gt-vue extraction'\n );\n return false;\n }\n\n return parseVueScript(\n block.content,\n block.lang,\n context,\n bindings,\n exposeToTemplate,\n scriptAnalysis\n );\n}\n\nfunction createTemplateBindings(): TemplateBindings {\n return {\n arrayLengths: new Map(),\n componentFactories: new Set(),\n components: new Map(),\n containerKinds: new Map(),\n possibleGTContainers: new Set(),\n gtContainerFactories: new Set(),\n directBindings: new Set(),\n registeredComponents: new Map(),\n registeredVueBuiltins: new Map(),\n staticValues: new Map(),\n identityFunctions: new Set(),\n possibleStaticStrings: new Map(),\n stringFunctions: new Map(),\n uncertainStringFunctions: new Set(),\n uncertainComponents: new Set(),\n uncertainGTComponents: new Set(),\n gtComponentFactories: new Set(),\n uncertainRegisteredComponents: new Set(),\n uncertainRegisteredGTComponents: new Set(),\n vueBuiltins: new Map(),\n };\n}\n\nfunction sourceUsesTypeScript(source: string): boolean {\n let offset = 0;\n while (offset < source.length) {\n const start = source.indexOf('<script', offset);\n if (start === -1) return false;\n const boundary = source[start + '<script'.length];\n if (boundary !== '>' && !boundary?.match(/\\s/)) {\n offset = start + '<script'.length;\n continue;\n }\n\n const end = findOpeningTagEnd(source, start + '<script'.length);\n if (end === -1) return false;\n const language = readOpeningTagAttribute(\n source.slice(start + '<script'.length, end),\n 'lang'\n );\n if (typeof language === 'string' && /^tsx?$/i.test(language)) return true;\n offset = end + 1;\n }\n return false;\n}\n\nfunction isSupportedScriptLanguage(language: string | undefined): boolean {\n const normalizedLanguage = language?.toLowerCase();\n return (\n normalizedLanguage === undefined ||\n normalizedLanguage === 'js' ||\n normalizedLanguage === 'jsx' ||\n normalizedLanguage === 'ts' ||\n normalizedLanguage === 'tsx'\n );\n}\n\n/** Finds an opening tag boundary while respecting quoted attribute values. */\nfunction findOpeningTagEnd(source: string, start: number): number {\n let quote: '\"' | \"'\" | undefined;\n for (let index = start; index < source.length; index += 1) {\n const character = source[index];\n if (quote) {\n if (character === quote) quote = undefined;\n } else if (character === '\"' || character === \"'\") {\n quote = character;\n } else if (character === '>') {\n return index;\n }\n }\n return -1;\n}\n\n/** Reads one case-sensitive SFC attribute with quoted or unquoted syntax. */\nfunction readOpeningTagAttribute(\n attributes: string,\n requestedName: string\n): string | true | undefined {\n let offset = 0;\n while (offset < attributes.length) {\n while (offset < attributes.length && /\\s/.test(attributes[offset])) {\n offset += 1;\n }\n if (attributes[offset] === '/') {\n offset += 1;\n continue;\n }\n const nameStart = offset;\n while (offset < attributes.length && !/[\\s=]/.test(attributes[offset])) {\n offset += 1;\n }\n const name = attributes.slice(nameStart, offset);\n if (!name) break;\n\n while (offset < attributes.length && /\\s/.test(attributes[offset])) {\n offset += 1;\n }\n let value: string | true = true;\n if (attributes[offset] === '=') {\n offset += 1;\n while (offset < attributes.length && /\\s/.test(attributes[offset])) {\n offset += 1;\n }\n const quote = attributes[offset];\n if (quote === '\"' || quote === \"'\") {\n offset += 1;\n const valueStart = offset;\n while (offset < attributes.length && attributes[offset] !== quote) {\n offset += 1;\n }\n value = attributes.slice(valueStart, offset);\n if (attributes[offset] === quote) offset += 1;\n } else {\n const valueStart = offset;\n while (offset < attributes.length && !/\\s/.test(attributes[offset])) {\n offset += 1;\n }\n value = attributes.slice(valueStart, offset);\n }\n }\n if (name === requestedName) return value;\n }\n return undefined;\n}\n\nfunction languageFromExtension(\n extension: string\n): Exclude<StandaloneProbeLanguage, 'flow'> {\n if (extension === '.ts' || extension === '.mts' || extension === '.cts') {\n return 'ts';\n }\n if (extension === '.tsx') return 'tsx';\n if (extension === '.jsx') return 'jsx';\n return 'js';\n}\n\nfunction normalizeCompilerLocation(location: {\n end?: { column?: number; line?: number; offset?: number };\n start?: { column?: number; line?: number; offset?: number };\n}) {\n const start = location.start ?? {};\n const end = location.end ?? start;\n return {\n start: {\n column: start.column ?? 1,\n line: start.line ?? 1,\n offset: start.offset ?? 0,\n },\n end: {\n column: end.column ?? start.column ?? 1,\n line: end.line ?? start.line ?? 1,\n offset: end.offset ?? start.offset ?? 0,\n },\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extractFromVueSource.js","names":["initModuleLexer","parseModuleImports"],"sources":["../../src/internal/extractFromVueSource.ts"],"sourcesContent":["import { extname } from 'node:path';\nimport {\n init as initModuleLexer,\n parse as parseModuleImports,\n} from 'es-module-lexer';\nimport type { ParserPlugin } from '@babel/parser';\nimport type { SFCBlock, TemplateCompiler } from '#vue-compiler-sfc';\nimport type { RootNode } from '@vue/compiler-dom';\nimport type {\n VueCompilerOptions,\n VueExtractionOptions,\n VueExtractionOutput,\n} from '../types.js';\nimport {\n collectVueScriptImports,\n createVueScriptAnalysis,\n exposeVueScriptImportsToTemplate,\n parseVueScript,\n type VueScriptAnalysis,\n} from './script.js';\nimport { parseScriptAst } from './script/parser.js';\nimport {\n shiftCompilerAstLocations,\n shiftCompilerLocation,\n} from './compilerAst.js';\nimport {\n createLocalModuleResolver,\n type LocalModuleResolver,\n} from './script/localModules.js';\nimport { parseVueTemplate } from './template.js';\nimport type { TemplateBindings, VueExtractionContext } from './types.js';\nimport { addVueError, createVueExtractionContext } from './utils.js';\nimport {\n inspectVueCompiler,\n resolveVueCompiler,\n type ResolvedVueCompiler,\n} from './vueCompiler.js';\n\nconst DEFAULT_SURROUNDING_LINE_COUNT = 5;\nconst MAX_MALFORMED_SUFFIX_RECOVERIES = 64;\n\n/** Parser options supported at runtime but omitted from Vue 3.3 declarations. */\ntype CompatibleTemplateParserOptions = NonNullable<\n Parameters<TemplateCompiler['parse']>[1]\n> & {\n expressionPlugins?: ParserPlugin[];\n};\n\n/** compiler-dom options supported at runtime across the supported Vue range. */\ntype CompatibleCompilerDomParserOptions = NonNullable<\n Parameters<NonNullable<ResolvedVueCompiler['parseTemplate']>>[1]\n> & {\n expressionPlugins?: ParserPlugin[];\n};\n\n/**\n * Extracts General Translation content from one Vue SFC or JavaScript file.\n *\n * This low-level API lets callers parse an individual in-memory source file.\n * Use `@generaltranslation/vue-extractor/project` when discovery, I/O,\n * compiler configuration, hashing, and deduplication should be handled by the\n * package as one project-level operation.\n */\nexport async function extractFromVueSource(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions = {}\n): Promise<VueExtractionOutput> {\n const results: VueExtractionOutput['results'] = [];\n const errors: string[] = [];\n const warnings = new Set<string>();\n const context = createVueExtractionContext(\n filePath,\n sourceCode,\n options.projectRoot ?? process.cwd(),\n options.includeSourceCodeContext ?? false,\n options.surroundingLineCount ?? DEFAULT_SURROUNDING_LINE_COUNT,\n results,\n errors,\n warnings\n );\n const extension = extname(filePath).toLowerCase();\n const scriptAnalysis = createVueScriptAnalysis();\n scriptAnalysis.entryFile = filePath;\n scriptAnalysis.localModules = createLocalModuleResolver(\n options.resolveModule\n );\n\n if (extension === '.vue') {\n const compilerResolution =\n options.compiler !== undefined\n ? inspectVueCompiler(options.compiler)\n : resolveVueCompiler(filePath, options.projectRoot ?? process.cwd());\n if (!compilerResolution.ok) {\n addVueError(\n context,\n undefined,\n 'Could not load the Vue compiler used by this single-file component',\n `Install a supported Vue 3 compiler beside the app. ${compilerResolution.details}`\n );\n return { results, errors, warnings: [...warnings] };\n }\n context.implicitSlotWhitespace =\n compilerResolution.value.implicitSlotWhitespace;\n context.valuedVIsReplacesElement =\n compilerResolution.value.valuedVIsReplacesElement;\n parseVueSingleFileComponent(\n sourceCode,\n context,\n options.compilerOptions ?? {},\n compilerResolution.value,\n scriptAnalysis\n );\n } else {\n if (\n options.requireGTProvenance &&\n !(await hasStandaloneGTProvenance(sourceCode, filePath, options))\n ) {\n return { results, errors, warnings: [...warnings] };\n }\n parseVueScript(\n sourceCode,\n languageFromExtension(extension),\n context,\n createTemplateBindings(),\n false,\n scriptAnalysis,\n false\n );\n }\n\n return { results, errors, warnings: [...warnings] };\n}\n\n/**\n * Uses the declared language, then permissive TSX and Flow, to prove gt-vue\n * ownership without changing the grammar used for extraction.\n *\n * The normal extraction pass still parses the file according to its extension.\n * Diagnostics caused only by GT-shaped names do not establish ownership. This\n * keeps mixed-framework dispatch from making otherwise valid React files fatal.\n */\nasync function hasStandaloneGTProvenance(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions\n): Promise<boolean> {\n const extension = extname(filePath).toLowerCase();\n const probeLanguages = new Set<StandaloneProbeLanguage>([\n languageFromExtension(extension),\n 'tsx',\n 'flow',\n ]);\n const localModules = createLocalModuleResolver(options.resolveModule);\n for (const language of probeLanguages) {\n const probe = probeStandaloneGTProvenance(\n sourceCode,\n filePath,\n options,\n language,\n localModules\n );\n if (probe.hasProvenance) return true;\n if (probe.parsed) return false;\n }\n const suffixSelection = selectMalformedSuffixLanguage(\n sourceCode,\n probeLanguages\n );\n const moduleRecovery = suffixSelection?.recoverable\n ? await recoverMalformedModuleReferences(\n sourceCode,\n filePath,\n options,\n probeLanguages,\n localModules\n )\n : { hasProvenance: false, preamble: '' };\n if (moduleRecovery.hasProvenance) {\n return true;\n }\n return hasMalformedStandaloneGTProvenance(\n sourceCode,\n filePath,\n options,\n probeLanguages,\n localModules,\n moduleRecovery.preamble\n );\n}\n\n/**\n * Recovers static module ownership without reparsing an entire malformed file.\n *\n * es-module-lexer ignores comments and literal contents while continuing past\n * unrelated syntax errors. Each declaration is then analyzed on its own,\n * preserving type-only and binding-specific local-barrel semantics. Parseable\n * declarations are also returned as a preamble for later recovered uses.\n */\nasync function recoverMalformedModuleReferences(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions,\n languages: ReadonlySet<StandaloneProbeLanguage>,\n localModules: LocalModuleResolver\n): Promise<{ hasProvenance: boolean; preamble: string }> {\n await initModuleLexer;\n let imports: ReturnType<typeof parseModuleImports>[0];\n try {\n [imports] = parseModuleImports(sourceCode);\n } catch {\n imports = [];\n }\n\n const declarations = new Set<string>();\n for (const moduleImport of imports) {\n if (!moduleImport.n) continue;\n for (const declaration of readModuleStatementCandidates(\n sourceCode,\n moduleImport.ss,\n moduleImport.se\n )) {\n for (const language of languages) {\n const probe = probeStandaloneGTProvenance(\n declaration,\n filePath,\n options,\n language,\n localModules\n );\n if (probe.hasProvenance) {\n return { hasProvenance: true, preamble: '' };\n }\n if (probe.parsed) {\n declarations.add(declaration);\n break;\n }\n }\n if (declarations.has(declaration)) break;\n }\n }\n return {\n hasProvenance: false,\n preamble: [...declarations].join('\\n'),\n };\n}\n\n/** Returns small statement slices enclosing one lexed module reference. */\nfunction readModuleStatementCandidates(\n sourceCode: string,\n statementStart: number,\n specifierEnd: number\n): string[] {\n const precedingBoundaries = [';', '\\n', '{', '}']\n .map((separator) => sourceCode.lastIndexOf(separator, statementStart - 1))\n .filter((offset) => offset >= 0)\n .map((offset) => offset + 1);\n precedingBoundaries.push(0);\n const followingBoundaries = [';', '\\n', '}']\n .map((separator) => sourceCode.indexOf(separator, specifierEnd))\n .filter((offset) => offset >= 0)\n .map((offset) => offset + 1);\n const starts = [\n ...precedingBoundaries.sort((left, right) => right - left),\n statementStart,\n ];\n const ends = [\n ...followingBoundaries.sort((left, right) => left - right),\n specifierEnd,\n ];\n const candidates = new Set<string>();\n for (const start of starts) {\n for (const end of ends) {\n if (end <= start) continue;\n const candidate = sourceCode.slice(start, end).trim();\n if (candidate) candidates.add(candidate);\n }\n }\n return [...candidates];\n}\n\ntype StandaloneProbeLanguage = 'flow' | 'js' | 'jsx' | 'ts' | 'tsx';\n\n/** Runs one syntax-tolerant, read-only provenance classification pass. */\nfunction probeStandaloneGTProvenance(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions,\n language: StandaloneProbeLanguage,\n localModules: LocalModuleResolver\n): { hasProvenance: boolean; parsed: boolean } {\n const results: VueExtractionOutput['results'] = [];\n const errors: string[] = [];\n const warnings = new Set<string>();\n const projectRoot = options.projectRoot ?? process.cwd();\n const context = createVueExtractionContext(\n filePath,\n sourceCode,\n projectRoot,\n false,\n options.surroundingLineCount ?? DEFAULT_SURROUNDING_LINE_COUNT,\n results,\n errors,\n warnings\n );\n const analysis = createVueScriptAnalysis();\n analysis.entryFile = filePath;\n analysis.localModules = localModules;\n const parsed = parseVueScript(\n sourceCode,\n language,\n context,\n createTemplateBindings(),\n false,\n analysis,\n false\n );\n if (results.length > 0 || analysisHasGTProvenance(analysis)) {\n return { hasProvenance: true, parsed };\n }\n return { hasProvenance: false, parsed };\n}\n\n/**\n * Finds concrete module references when malformed syntax prevents a full AST.\n *\n * Each supported grammar recovers a complete prefix, then the grammar that\n * parsed furthest gets a bounded suffix search. Unterminated literal errors\n * never receive suffix recovery, so literal contents cannot become code.\n */\nfunction hasMalformedStandaloneGTProvenance(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions,\n languages: ReadonlySet<StandaloneProbeLanguage>,\n localModules: LocalModuleResolver,\n recoveredPreamble: string\n): boolean {\n for (const language of languages) {\n if (\n leadingStatementPrefixHasGTProvenance(\n sourceCode,\n filePath,\n options,\n language,\n localModules\n )\n ) {\n return true;\n }\n }\n const suffixSelection = selectMalformedSuffixLanguage(sourceCode, languages);\n return Boolean(\n suffixSelection?.recoverable &&\n malformedSuffixHasGTProvenance(\n sourceCode,\n filePath,\n options,\n suffixSelection.language,\n localModules,\n recoveredPreamble\n )\n );\n}\n\n/** Preserves CommonJS and TypeScript import ownership before a syntax error. */\nfunction leadingStatementPrefixHasGTProvenance(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions,\n language: StandaloneProbeLanguage,\n localModules: LocalModuleResolver\n): boolean {\n let errorOffset: number;\n try {\n parseScriptAst(sourceCode, language);\n return false;\n } catch (error) {\n const offset = (error as { pos?: unknown }).pos;\n if (typeof offset !== 'number') return false;\n errorOffset = offset;\n }\n const boundary = Math.max(\n sourceCode.lastIndexOf(';', errorOffset - 1) + 1,\n sourceCode.lastIndexOf('\\n', errorOffset - 1) + 1,\n sourceCode.lastIndexOf('}', errorOffset - 1) + 1\n );\n if (boundary <= 0) return false;\n const prefix = sourceCode.slice(0, boundary).trimEnd();\n if (!prefix) return false;\n const probe = probeStandaloneGTProvenance(\n prefix,\n filePath,\n options,\n language,\n localModules\n );\n return probe.hasProvenance;\n}\n\n/** Recovers later imports and CommonJS calls after a bounded number of errors. */\nfunction malformedSuffixHasGTProvenance(\n sourceCode: string,\n filePath: string,\n options: VueExtractionOptions,\n language: StandaloneProbeLanguage,\n localModules: LocalModuleResolver,\n recoveredPreamble: string\n): boolean {\n let remaining = sourceCode;\n for (let attempt = 0; attempt < MAX_MALFORMED_SUFFIX_RECOVERIES; attempt++) {\n let errorOffset: number;\n try {\n parseScriptAst(remaining, language);\n const recoveredSource = recoveredPreamble\n ? `${recoveredPreamble}\\n${remaining}`\n : remaining;\n const recoveredProbe = probeStandaloneGTProvenance(\n recoveredSource,\n filePath,\n options,\n language,\n localModules\n );\n if (recoveredProbe.parsed) return recoveredProbe.hasProvenance;\n // The remaining suffix may already contain the declaration retained in\n // the preamble. Probe it alone to avoid a duplicate-binding parse error.\n return probeStandaloneGTProvenance(\n remaining,\n filePath,\n options,\n language,\n localModules\n ).hasProvenance;\n } catch (error) {\n const parseError = readRecoverableParseError(error);\n if (!parseError) return false;\n errorOffset = parseError.offset;\n }\n const boundary = findMalformedRecoveryBoundary(remaining, errorOffset);\n if (boundary <= 0 || boundary >= remaining.length) return false;\n remaining = remaining.slice(boundary);\n const recoveredSource = recoveredPreamble\n ? `${recoveredPreamble}\\n${remaining}`\n : remaining;\n let probe = probeStandaloneGTProvenance(\n recoveredSource,\n filePath,\n options,\n language,\n localModules\n );\n if (!probe.parsed && recoveredPreamble) {\n const trimmedRemaining = trimTrailingRecoveryClosers(remaining);\n if (trimmedRemaining !== remaining) {\n probe = probeStandaloneGTProvenance(\n `${recoveredPreamble}\\n${trimmedRemaining}`,\n filePath,\n options,\n language,\n localModules\n );\n }\n }\n if (probe.hasProvenance) return true;\n if (probe.parsed) return false;\n }\n return false;\n}\n\n/** Removes block closers orphaned when recovery starts inside a function. */\nfunction trimTrailingRecoveryClosers(sourceCode: string): string {\n let end = sourceCode.length;\n while (end > 0 && sourceCode[end - 1]!.trim() === '') end -= 1;\n if (sourceCode[end - 1] !== '}') return sourceCode.slice(0, end);\n\n do {\n end -= 1;\n while (end > 0 && sourceCode[end - 1]!.trim() === '') end -= 1;\n } while (sourceCode[end - 1] === '}');\n return sourceCode.slice(0, end);\n}\n\n/** Chooses the grammar that parsed furthest before a recoverable error. */\nfunction selectMalformedSuffixLanguage(\n sourceCode: string,\n languages: ReadonlySet<StandaloneProbeLanguage>\n): { language: StandaloneProbeLanguage; recoverable: boolean } | undefined {\n let selected:\n | { language: StandaloneProbeLanguage; recoverable: boolean }\n | undefined;\n let furthestOffset = -1;\n for (const language of languages) {\n try {\n parseScriptAst(sourceCode, language);\n } catch (error) {\n const parseError = readParseError(error);\n if (parseError && parseError.offset > furthestOffset) {\n selected = {\n language,\n recoverable: parseError.recoverable,\n };\n furthestOffset = parseError.offset;\n }\n }\n }\n return selected;\n}\n\n/** Rejects recovery that could reinterpret unterminated literal contents. */\nfunction readRecoverableParseError(\n error: unknown\n): { offset: number } | undefined {\n const parsed = readParseError(error);\n return parsed?.recoverable ? { offset: parsed.offset } : undefined;\n}\n\n/** Reads one Babel parser error without trusting unterminated literal state. */\nfunction readParseError(\n error: unknown\n): { offset: number; recoverable: boolean } | undefined {\n const parsed = error as { pos?: unknown; reasonCode?: unknown };\n if (typeof parsed.pos !== 'number') return undefined;\n const unsafeReasonCodes = new Set([\n 'UnterminatedComment',\n 'UnterminatedJsxContent',\n 'UnterminatedRegExp',\n 'UnterminatedString',\n 'UnterminatedTemplate',\n ]);\n return {\n offset: parsed.pos,\n recoverable:\n typeof parsed.reasonCode !== 'string' ||\n !unsafeReasonCodes.has(parsed.reasonCode),\n };\n}\n\n/** Selects the first statement-like boundary after a parser error. */\nfunction findMalformedRecoveryBoundary(\n sourceCode: string,\n errorOffset: number\n): number {\n const candidates = [';', '\\n', '}']\n .map((separator) => sourceCode.indexOf(separator, errorOffset))\n .filter((offset) => offset >= 0);\n return candidates.length > 0 ? Math.min(...candidates) + 1 : -1;\n}\n\n/** Returns whether permissive analysis reached a concrete gt-vue identity. */\nfunction analysisHasGTProvenance(analysis: VueScriptAnalysis): boolean {\n return analysis.hasGTSourceReference;\n}\n\nfunction parseVueSingleFileComponent(\n source: string,\n context: VueExtractionContext,\n compilerOptions: VueCompilerOptions,\n resolvedCompiler: ResolvedVueCompiler,\n scriptAnalysis: VueScriptAnalysis\n): void {\n const { compiler } = resolvedCompiler;\n if (\n compilerOptions.delimiters &&\n !resolvedCompiler.templateCompiler &&\n !resolvedCompiler.templateParseOptionsSupported\n ) {\n addVueError(\n context,\n undefined,\n 'Could not safely apply custom Vue template delimiters with the supplied compiler',\n 'Let the extractor resolve the consuming app compiler, or supply a Vue compiler that applies templateParseOptions during SFC parsing'\n );\n return;\n }\n const expressionPlugins: ParserPlugin[] = sourceUsesTypeScript(source)\n ? ['typescript']\n : [];\n const templateCompiler = createConfiguredTemplateCompiler(\n resolvedCompiler,\n compilerOptions,\n expressionPlugins,\n true\n );\n const result = compiler.parse(source, {\n ...(templateCompiler && { compiler: templateCompiler }),\n filename: context.file,\n pad: 'space',\n sourceMap: false,\n templateParseOptions: {\n ...compilerOptions,\n comments: true,\n expressionPlugins,\n },\n });\n\n for (const error of result.errors) {\n const compilerError =\n typeof error === 'string'\n ? undefined\n : (error as SyntaxError & {\n loc?: Parameters<typeof normalizeCompilerLocation>[0];\n });\n addVueError(\n context,\n compilerError?.loc\n ? normalizeCompilerLocation(compilerError.loc)\n : undefined,\n `Could not parse a gt-vue single-file component: ${typeof error === 'string' ? error : error.message}`,\n 'Fix the Vue template syntax before extracting translations'\n );\n }\n // Vue's SFC parser recovers a partial AST for malformed markup. Publishing\n // translations from that recovery tree can replace complete catalogs with\n // an incomplete source set, so structural parse errors are file-fatal.\n if (result.errors.length > 0) return;\n\n const bindings = createTemplateBindings();\n collectScriptBlockImports(result.descriptor.script, scriptAnalysis);\n collectScriptBlockImports(result.descriptor.scriptSetup, scriptAnalysis);\n const scriptValid = parseScriptBlock(\n result.descriptor.script,\n false,\n context,\n bindings,\n scriptAnalysis\n );\n if (result.descriptor.scriptSetup) {\n exposeVueScriptImportsToTemplate(scriptAnalysis, bindings);\n }\n const scriptSetupValid = parseScriptBlock(\n result.descriptor.scriptSetup,\n true,\n context,\n bindings,\n scriptAnalysis\n );\n if (!scriptValid || !scriptSetupValid) {\n context.results.length = 0;\n return;\n }\n\n const template = result.descriptor.template;\n if (!template) return;\n if (template.lang && template.lang !== 'html') {\n addVueError(\n context,\n template.loc,\n `Found unsupported Vue template language \"${template.lang}\"`,\n 'Use a standard HTML Vue template for gt-vue extraction'\n );\n context.results.length = 0;\n return;\n }\n if (template.src) {\n addVueError(\n context,\n template.loc,\n 'Found an externally sourced Vue template',\n 'Keep the template in the .vue file so gt-vue can extract it'\n );\n context.results.length = 0;\n return;\n }\n const templateAst = resolvedCompiler.parseTemplate\n ? parseTemplateWithCompiler(\n template.content,\n compilerOptions,\n expressionPlugins,\n true,\n context,\n resolvedCompiler.parseTemplate,\n template.loc.start\n )\n : (template.ast as unknown as RootNode);\n if (templateAst) {\n const templateResultStart = context.results.length;\n const templateErrorStart = context.errors.length;\n parseVueTemplate(templateAst, bindings, expressionPlugins, context);\n if (\n context.errors.length === templateErrorStart &&\n template.content.includes('<!--') &&\n !matchesProductionTemplate(\n source,\n compilerOptions,\n expressionPlugins,\n bindings,\n context,\n templateResultStart,\n resolvedCompiler\n )\n ) {\n context.results.length = templateResultStart;\n addVueError(\n context,\n template.loc,\n 'Found translatable Vue content whose hash changes between development and production',\n 'Remove comments that split translatable text or whitespace, or move those comments outside gt-vue <T> components'\n );\n }\n }\n}\n\n/**\n * Verifies that Vite's production comment stripping preserves extracted data.\n *\n * Vue parses templates with comments in development and without them in\n * production. Removing a comment can renormalize adjacent whitespace, so a\n * single persisted catalog key cannot serve both builds. The second parse is\n * limited to templates that contain comments and never executes project code.\n */\nfunction matchesProductionTemplate(\n source: string,\n compilerOptions: VueCompilerOptions,\n expressionPlugins: ParserPlugin[],\n bindings: TemplateBindings,\n context: VueExtractionContext,\n developmentResultStart: number,\n resolvedCompiler: ResolvedVueCompiler\n): boolean {\n const { compiler } = resolvedCompiler;\n const templateCompiler = createConfiguredTemplateCompiler(\n resolvedCompiler,\n compilerOptions,\n expressionPlugins,\n false\n );\n const production = compiler.parse(source, {\n ...(templateCompiler && { compiler: templateCompiler }),\n filename: context.file,\n pad: 'space',\n sourceMap: false,\n templateParseOptions: {\n ...compilerOptions,\n comments: false,\n expressionPlugins,\n },\n });\n const template = production.descriptor.template;\n if (production.errors.length > 0 || !template) return false;\n\n const productionContext: VueExtractionContext = {\n ...context,\n errors: [],\n results: [],\n warnings: new Set(),\n };\n const templateAst = resolvedCompiler.parseTemplate\n ? parseTemplateWithCompiler(\n template.content,\n compilerOptions,\n expressionPlugins,\n false,\n productionContext,\n resolvedCompiler.parseTemplate,\n template.loc.start\n )\n : (template.ast as unknown as RootNode);\n if (!templateAst) return false;\n parseVueTemplate(templateAst, bindings, expressionPlugins, productionContext);\n if (productionContext.errors.length > 0) return false;\n\n const developmentResults = context.results.slice(developmentResultStart);\n return (\n comparableTemplateResults(developmentResults) ===\n comparableTemplateResults(productionContext.results)\n );\n}\n\n/**\n * Applies hash-affecting options during compiler-sfc's structural parse.\n *\n * Vue 3.3 ignores `templateParseOptions`, which can make delimiter-shaped text\n * close an SFC block before the exact template-content parse runs. Supplying\n * the adjacent compiler-dom parser makes the descriptor structural parse use\n * the same delimiters and whitespace. Vue 3.3 caches SFC parses using the\n * parser function's string form, so its deterministic identity includes every\n * closure-captured option to prevent cross-option cache poisoning.\n */\nfunction createConfiguredTemplateCompiler(\n resolvedCompiler: ResolvedVueCompiler,\n compilerOptions: VueCompilerOptions,\n expressionPlugins: ParserPlugin[],\n comments: boolean\n): TemplateCompiler | undefined {\n const templateCompiler = resolvedCompiler.templateCompiler;\n if (!templateCompiler) return undefined;\n\n const parse: TemplateCompiler['parse'] = (source, baseOptions) => {\n const options: CompatibleTemplateParserOptions = {\n ...baseOptions,\n ...compilerOptions,\n comments,\n expressionPlugins,\n };\n return templateCompiler.parse(source, options);\n };\n const identity = JSON.stringify({\n comments,\n delimiters: compilerOptions.delimiters,\n expressionPlugins,\n version: resolvedCompiler.version,\n whitespace: compilerOptions.whitespace,\n });\n Object.defineProperty(parse, 'toString', {\n value: () => `gtVueTemplateParse:${identity}`,\n });\n\n return { compile: templateCompiler.compile, parse };\n}\n\n/** Parses template content with the exact compiler-dom beside consumer Vue. */\nfunction parseTemplateWithCompiler(\n source: string,\n compilerOptions: VueCompilerOptions,\n expressionPlugins: ParserPlugin[],\n comments: boolean,\n context: VueExtractionContext,\n parseTemplate: NonNullable<ResolvedVueCompiler['parseTemplate']>,\n origin: CompilerPosition\n): RootNode | undefined {\n const errors: Array<SyntaxError & { loc?: ExtractionLocationLike }> = [];\n const options: CompatibleCompilerDomParserOptions = {\n ...compilerOptions,\n comments,\n expressionPlugins,\n onError(error) {\n errors.push(error as SyntaxError & { loc?: ExtractionLocationLike });\n },\n };\n const ast = parseTemplate(source, options);\n if (errors.length === 0) {\n shiftCompilerAstLocations(ast, origin);\n return ast;\n }\n const shiftedErrorPositions = new WeakSet<object>();\n for (const error of errors) {\n if (error.loc) {\n shiftCompilerLocation(error.loc, origin, shiftedErrorPositions);\n }\n addVueError(\n context,\n error.loc ? normalizeCompilerLocation(error.loc) : undefined,\n `Could not parse a gt-vue template: ${error.message}`,\n 'Fix the Vue template syntax before extracting translations'\n );\n }\n return undefined;\n}\n\ntype ExtractionLocationLike = Parameters<typeof normalizeCompilerLocation>[0];\ntype CompilerPosition = {\n column: number;\n line: number;\n offset: number;\n};\n\n/** Omits location-only metadata while comparing persisted template content. */\nfunction comparableTemplateResults(\n results: VueExtractionOutput['results']\n): string {\n return JSON.stringify(\n results.map((result) => ({\n dataFormat: result.dataFormat,\n metadata: {\n context: result.metadata.context,\n id: result.metadata.id,\n maxChars: result.metadata.maxChars,\n requiresReview: result.metadata.requiresReview,\n },\n source: result.source,\n }))\n );\n}\n\nfunction collectScriptBlockImports(\n block: SFCBlock | null,\n scriptAnalysis: VueScriptAnalysis\n): void {\n if (!block || block.src || !isSupportedScriptLanguage(block.lang)) return;\n collectVueScriptImports(block.content, block.lang, scriptAnalysis);\n}\n\nfunction parseScriptBlock(\n block: SFCBlock | null,\n exposeToTemplate: boolean,\n context: VueExtractionContext,\n bindings: TemplateBindings,\n scriptAnalysis: VueScriptAnalysis\n): boolean {\n if (!block) return true;\n if (block.src) {\n addVueError(\n context,\n block.loc,\n 'Found an externally sourced Vue script block',\n 'Keep translation calls and gt-vue imports in the .vue file'\n );\n return false;\n }\n if (!isSupportedScriptLanguage(block.lang)) {\n addVueError(\n context,\n block.loc,\n `Found unsupported Vue script language \"${block.lang}\"`,\n 'Use JavaScript or TypeScript for gt-vue extraction'\n );\n return false;\n }\n\n return parseVueScript(\n block.content,\n block.lang,\n context,\n bindings,\n exposeToTemplate,\n scriptAnalysis\n );\n}\n\nfunction createTemplateBindings(): TemplateBindings {\n return {\n arrayLengths: new Map(),\n componentFactories: new Set(),\n components: new Map(),\n containerKinds: new Map(),\n possibleGTContainers: new Set(),\n gtContainerFactories: new Set(),\n directBindings: new Set(),\n registeredComponents: new Map(),\n registeredVueBuiltins: new Map(),\n staticValues: new Map(),\n identityFunctions: new Set(),\n possibleStaticStrings: new Map(),\n stringFunctions: new Map(),\n uncertainStringFunctions: new Set(),\n uncertainComponents: new Set(),\n uncertainGTComponents: new Set(),\n gtComponentFactories: new Set(),\n uncertainRegisteredComponents: new Set(),\n uncertainRegisteredGTComponents: new Set(),\n vueBuiltins: new Map(),\n };\n}\n\nfunction sourceUsesTypeScript(source: string): boolean {\n let offset = 0;\n while (offset < source.length) {\n const start = source.indexOf('<script', offset);\n if (start === -1) return false;\n const boundary = source[start + '<script'.length];\n if (boundary !== '>' && !boundary?.match(/\\s/)) {\n offset = start + '<script'.length;\n continue;\n }\n\n const end = findOpeningTagEnd(source, start + '<script'.length);\n if (end === -1) return false;\n const language = readOpeningTagAttribute(\n source.slice(start + '<script'.length, end),\n 'lang'\n );\n if (typeof language === 'string' && /^tsx?$/i.test(language)) return true;\n offset = end + 1;\n }\n return false;\n}\n\nfunction isSupportedScriptLanguage(language: string | undefined): boolean {\n const normalizedLanguage = language?.toLowerCase();\n return (\n normalizedLanguage === undefined ||\n normalizedLanguage === 'js' ||\n normalizedLanguage === 'jsx' ||\n normalizedLanguage === 'ts' ||\n normalizedLanguage === 'tsx'\n );\n}\n\n/** Finds an opening tag boundary while respecting quoted attribute values. */\nfunction findOpeningTagEnd(source: string, start: number): number {\n let quote: '\"' | \"'\" | undefined;\n for (let index = start; index < source.length; index += 1) {\n const character = source[index];\n if (quote) {\n if (character === quote) quote = undefined;\n } else if (character === '\"' || character === \"'\") {\n quote = character;\n } else if (character === '>') {\n return index;\n }\n }\n return -1;\n}\n\n/** Reads one case-sensitive SFC attribute with quoted or unquoted syntax. */\nfunction readOpeningTagAttribute(\n attributes: string,\n requestedName: string\n): string | true | undefined {\n let offset = 0;\n while (offset < attributes.length) {\n while (offset < attributes.length && /\\s/.test(attributes[offset])) {\n offset += 1;\n }\n if (attributes[offset] === '/') {\n offset += 1;\n continue;\n }\n const nameStart = offset;\n while (offset < attributes.length && !/[\\s=]/.test(attributes[offset])) {\n offset += 1;\n }\n const name = attributes.slice(nameStart, offset);\n if (!name) break;\n\n while (offset < attributes.length && /\\s/.test(attributes[offset])) {\n offset += 1;\n }\n let value: string | true = true;\n if (attributes[offset] === '=') {\n offset += 1;\n while (offset < attributes.length && /\\s/.test(attributes[offset])) {\n offset += 1;\n }\n const quote = attributes[offset];\n if (quote === '\"' || quote === \"'\") {\n offset += 1;\n const valueStart = offset;\n while (offset < attributes.length && attributes[offset] !== quote) {\n offset += 1;\n }\n value = attributes.slice(valueStart, offset);\n if (attributes[offset] === quote) offset += 1;\n } else {\n const valueStart = offset;\n while (offset < attributes.length && !/\\s/.test(attributes[offset])) {\n offset += 1;\n }\n value = attributes.slice(valueStart, offset);\n }\n }\n if (name === requestedName) return value;\n }\n return undefined;\n}\n\nfunction languageFromExtension(\n extension: string\n): Exclude<StandaloneProbeLanguage, 'flow'> {\n if (extension === '.ts' || extension === '.mts' || extension === '.cts') {\n return 'ts';\n }\n if (extension === '.tsx') return 'tsx';\n if (extension === '.jsx') return 'jsx';\n return 'js';\n}\n\nfunction normalizeCompilerLocation(location: {\n end?: { column?: number; line?: number; offset?: number };\n start?: { column?: number; line?: number; offset?: number };\n}) {\n const start = location.start ?? {};\n const end = location.end ?? start;\n return {\n start: {\n column: start.column ?? 1,\n line: start.line ?? 1,\n offset: start.offset ?? 0,\n },\n end: {\n column: end.column ?? start.column ?? 1,\n line: end.line ?? start.line ?? 1,\n offset: end.offset ?? start.offset ?? 0,\n },\n };\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@generaltranslation/vue-extractor",
|
|
3
|
-
"version": "0.1.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Vue source code extraction for General Translation",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -69,8 +69,8 @@
|
|
|
69
69
|
"semver": "^7.8.5",
|
|
70
70
|
"tsconfig-paths": "^4.2.0",
|
|
71
71
|
"yaml": "^2.8.0",
|
|
72
|
-
"@generaltranslation/format": "0.1.
|
|
73
|
-
"generaltranslation": "9.1.
|
|
72
|
+
"@generaltranslation/format": "0.1.8",
|
|
73
|
+
"generaltranslation": "9.1.7"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
76
|
"@types/babel__traverse": "^7.20.6",
|