@intlayer/svelte-compiler 8.7.8-canary.0 → 8.7.9

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.
@@ -247,8 +247,8 @@ const intlayerSvelteExtract = (code, filename, options = {}) => {
247
247
  extracted: true
248
248
  };
249
249
  };
250
- const processSvelteFile = (filePath, _componentKey, packageName, tools, save = true) => {
251
- const code = (0, node_fs.readFileSync)(filePath, "utf-8");
250
+ const processSvelteFile = (filePath, _componentKey, packageName, tools, save = true, providedCode) => {
251
+ const code = providedCode ?? (0, node_fs.readFileSync)(filePath, "utf-8");
252
252
  let extractedContent = null;
253
253
  const result = intlayerSvelteExtract(code, filePath, {
254
254
  packageName,
@@ -1 +1 @@
1
- {"version":3,"file":"svelte-intlayer-extract.cjs","names":["t","DEFAULT_LOCALE","MagicString"],"sources":["../../src/svelte-intlayer-extract.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { parse as babelParse, types as t, traverse } from '@babel/core';\nimport { DEFAULT_LOCALE } from '@intlayer/config/defaultValues';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport MagicString from 'magic-string';\nimport { parse } from 'svelte/compiler';\n\ntype ExistingCallInfo = {\n isDestructured: boolean;\n existingDestructuredKeys: string[];\n /** The variable name used to store the call result (e.g. `t` in `const t = useIntlayer(...)`) */\n variableName: string;\n /** Absolute position of `}` in the full file — only valid when `isDestructured` */\n closingBraceAbsolutePos: number;\n /** Absolute position of end of last property — only valid when `isDestructured` */\n lastPropAbsoluteEnd: number;\n} | null;\n\n/**\n * Detects whether a script block already contains a `useIntlayer` /\n * `getIntlayer` call and whether its result is destructured.\n */\nconst detectExistingIntlayerCall = (\n scriptText: string,\n absoluteOffset: number\n): ExistingCallInfo => {\n let info: ExistingCallInfo = null;\n\n try {\n const ast = babelParse(scriptText, {\n parserOpts: { sourceType: 'module', plugins: ['typescript', 'jsx'] },\n });\n\n if (!ast) return null;\n\n traverse(ast, {\n CallExpression(path: any) {\n const callee = path.node.callee;\n\n if (\n !t.isIdentifier(callee) ||\n (callee.name !== 'useIntlayer' && callee.name !== 'getIntlayer')\n )\n return;\n\n const parent = path.parent;\n\n if (t.isVariableDeclarator(parent) && t.isObjectPattern(parent.id)) {\n const properties = parent.id.properties;\n const existingDestructuredKeys = properties\n .filter(\n (p: any): p is typeof t.objectProperty =>\n t.isObjectProperty(p) && t.isIdentifier(p.key)\n )\n .map((p: any) => (p.key as any).name as string);\n const lastProp = properties[properties.length - 1];\n\n info = {\n isDestructured: true,\n variableName: 'content',\n existingDestructuredKeys,\n closingBraceAbsolutePos: absoluteOffset + (parent.id.end! - 1),\n lastPropAbsoluteEnd: absoluteOffset + lastProp.end!,\n };\n } else {\n const variableName =\n t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)\n ? parent.id.name\n : 'content';\n\n info = {\n isDestructured: false,\n variableName,\n existingDestructuredKeys: [],\n closingBraceAbsolutePos: -1,\n lastPropAbsoluteEnd: -1,\n };\n }\n\n path.stop();\n },\n });\n } catch {\n // Silently ignore parse failures — fall back to no-info\n }\n\n return info;\n};\n\nexport type ExtractedContent = Record<string, string>;\n\nexport type ExtractResult = {\n dictionaryKey: string;\n filePath: string;\n content: ExtractedContent;\n locale: Locale;\n};\n\nexport type ExtractPluginOptions = {\n defaultLocale?: Locale;\n packageName?: string;\n filesList?: string[];\n shouldExtract?: (text: string) => boolean;\n onExtract?: (result: ExtractResult) => void;\n dictionaryKey?: string;\n attributesToExtract?: readonly string[];\n extractDictionaryKeyFromPath?: (path: string) => string;\n generateKey?: (text: string, existingKeys: Set<string>) => string;\n};\n\ntype Replacement = {\n start: number;\n end: number;\n replacement: string;\n key: string;\n value: string;\n};\n\n/* ────────────────────────────────────────── helpers ─────────────────────── */\n\nexport const shouldProcessFile = (\n filename: string | undefined,\n filesList?: string[]\n): boolean => {\n if (!filename) return false;\n if (!filesList || filesList.length === 0) return true;\n\n const normalizedFilename = filename.replace(/\\\\/g, '/');\n return filesList.some((f) => {\n const normalizedF = f.replace(/\\\\/g, '/');\n return normalizedF === normalizedFilename;\n });\n};\n\n/* ────────────────────────────────────────── plugin ──────────────────────── */\n\nexport const intlayerSvelteExtract = (\n code: string,\n filename: string,\n options: ExtractPluginOptions = {}\n): { code: string; map?: unknown; extracted: boolean } | null => {\n const {\n defaultLocale = DEFAULT_LOCALE,\n packageName = 'svelte-intlayer',\n filesList,\n shouldExtract,\n onExtract,\n dictionaryKey: dictionaryKeyOption,\n attributesToExtract = [],\n extractDictionaryKeyFromPath,\n generateKey,\n } = options;\n\n if (!shouldProcessFile(filename, filesList)) return null;\n if (!filename.endsWith('.svelte')) return null;\n\n const magic = new MagicString(code);\n const extractedContent: ExtractedContent = {};\n const existingKeys = new Set<string>();\n const dictionaryKey =\n dictionaryKeyOption ?? extractDictionaryKeyFromPath?.(filename) ?? '';\n const replacements: Replacement[] = [];\n\n // Extract and walk Script using Babel\n const scriptRegex = /<script[^>]*>([\\s\\S]*?)<\\/script>/;\n const scriptMatch = scriptRegex.exec(code);\n let hasScriptExtraction = false;\n const scriptContent = scriptMatch ? scriptMatch[1] : '';\n\n // Detect existing call BEFORE walking the template so the access pattern\n // (bare key vs. $content.key) can be chosen consistently.\n const existingCallInfo = scriptMatch\n ? detectExistingIntlayerCall(\n scriptContent,\n scriptMatch.index + scriptMatch[0].indexOf('>') + 1\n )\n : null;\n\n const isDestructured = existingCallInfo?.isDestructured ?? false;\n const varName = existingCallInfo?.variableName ?? 'content';\n\n let ast: any;\n try {\n ast = parse(code);\n } catch (e) {\n console.warn(\n `Svelte extraction: Failed to parse Svelte AST for ${filename}`,\n e\n );\n return null;\n }\n\n // Walk Svelte HTML AST.\n // Svelte 4 used numeric type constants; Svelte 5 uses string type names.\n // We check for both to remain compatible.\n const isTextNode = (node: any) => node.type === 'Text' || node.type === 3;\n const isAttributeNode = (node: any) =>\n node.type === 'Attribute' || node.type === 6;\n const isExpressionTagNode = (node: any): boolean =>\n node.type === 'MustacheTag' ||\n node.type === 8 || // Svelte 4 numeric\n node.type === 'ExpressionTag'; // Svelte 5\n\n const walkSvelte = (node: any) => {\n if (isTextNode(node)) {\n const text = node.data ?? node.content ?? '';\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n // Destructured: each property is a plain value → `{key}`.\n // Otherwise use the reactive store subscription `{$content.key}`.\n const ref = isDestructured ? key : `$${varName}.${key}`;\n replacements.push({\n start: node.start,\n end: node.end,\n replacement: `{${ref}}`,\n key,\n value: text.replace(/\\s+/g, ' ').trim(),\n });\n }\n } else if (\n isAttributeNode(node) &&\n (attributesToExtract as readonly string[]).includes(node.name)\n ) {\n if (node.value && node.value.length === 1 && isTextNode(node.value[0])) {\n const text = node.value[0].data ?? node.value[0].content ?? '';\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `$${varName}.${key}`;\n replacements.push({\n start: node.start,\n end: node.end,\n replacement: `${node.name}={${ref}}`,\n key,\n value: text.trim(),\n });\n }\n }\n }\n\n const children =\n node.children ?? node.fragment?.nodes ?? node.fragment?.children;\n\n // Try to handle mixed text + expression children as an insertion\n if (children?.some(isExpressionTagNode)) {\n const parts: {\n type: 'text' | 'var';\n value: string;\n originalExpr: string;\n }[] = [];\n let hasSignificantText = false;\n let isValid = true;\n\n for (const child of children) {\n if (isTextNode(child)) {\n const text = child.data ?? child.content ?? '';\n if (text.trim().length > 0) hasSignificantText = true;\n parts.push({ type: 'text', value: text, originalExpr: '' });\n } else if (isExpressionTagNode(child)) {\n // Source slice: skip the leading `{` and trailing `}`\n const exprCode = code.slice(child.start + 1, child.end - 1).trim();\n const varName = exprCode.includes('.')\n ? exprCode\n .split('.')\n .pop()!\n .replace(/[^\\w$]/g, '')\n : exprCode;\n parts.push({ type: 'var', value: varName, originalExpr: exprCode });\n } else {\n isValid = false;\n break;\n }\n }\n\n if (\n isValid &&\n hasSignificantText &&\n parts.some((p) => p.type === 'var')\n ) {\n let combined = '';\n for (const p of parts) {\n combined += p.type === 'var' ? `{{${p.value}}}` : p.value;\n }\n const cleanString = combined.replace(/\\s+/g, ' ').trim();\n\n if (shouldExtract?.(cleanString) && generateKey) {\n const key = generateKey(cleanString, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `$${varName}.${key}`;\n\n const uniqueVarPairs = [\n ...new Set(\n parts\n .filter((p) => p.type === 'var')\n .map((p) => `${p.value}: ${p.originalExpr}`)\n ),\n ];\n const varArgs = uniqueVarPairs.join(', ');\n const replacement = `{${ref}({ ${varArgs} })}`;\n\n const firstChild = children[0];\n const lastChild = children[children.length - 1];\n replacements.push({\n start: firstChild.start,\n end: lastChild.end,\n replacement,\n key,\n value: cleanString,\n });\n\n // Don't recurse into these children\n if (node.attributes) node.attributes.forEach(walkSvelte);\n return;\n }\n }\n }\n\n if (children) children.forEach(walkSvelte);\n if (node.attributes) node.attributes.forEach(walkSvelte);\n };\n\n if (ast.html) {\n walkSvelte(ast.html);\n }\n\n if (scriptMatch) {\n const openTagEndIndex = scriptMatch[0].indexOf('>') + 1;\n const offset = scriptMatch.index + openTagEndIndex;\n\n try {\n const babelAst = babelParse(scriptContent, {\n parserOpts: {\n sourceType: 'module',\n plugins: ['typescript', 'jsx'],\n },\n });\n\n if (babelAst) {\n traverse(babelAst, {\n StringLiteral(path: any) {\n if (path.parentPath.isImportDeclaration()) return;\n if (path.parentPath.isExportDeclaration()) return;\n if (path.parentPath.isImportSpecifier()) return;\n if (path.parentPath.isObjectProperty() && path.key === 'key')\n return;\n\n if (path.parentPath.isCallExpression()) {\n const callee = path.parentPath.node.callee;\n if (\n t.isMemberExpression(callee) &&\n t.isIdentifier(callee.object) &&\n callee.object.name === 'console'\n )\n return;\n\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 't')\n )\n return;\n\n if (callee.type === 'Import') return;\n if (t.isIdentifier(callee) && callee.name === 'require') return;\n }\n\n const text = path.node.value;\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n hasScriptExtraction = true;\n\n if (path.node.start != null && path.node.end != null) {\n // Destructured: each property is a plain value → access directly.\n // Otherwise use `get(content).key` to read the Svelte store.\n const ref = isDestructured ? key : `get(${varName}).${key}`;\n replacements.push({\n start: offset + path.node.start,\n end: offset + path.node.end,\n replacement: ref,\n key,\n value: text.trim(),\n });\n }\n }\n },\n });\n }\n } catch (error) {\n console.warn(\n `Svelte extraction: Failed to parse script content for ${filename}`,\n error\n );\n }\n }\n\n // Abort if nothing was extracted\n if (replacements.length === 0) return null;\n\n // Apply Replacements in Reverse Order (prevents magic-string chunk errors)\n replacements.sort((a, b) => b.start - a.start);\n for (const { start, end, replacement, key, value } of replacements) {\n magic.overwrite(start, end, replacement);\n extractedContent[key] = value;\n }\n\n // When the existing call is destructured, inject only the missing keys into\n // the ObjectPattern — no new `content` variable is needed.\n if (\n existingCallInfo?.isDestructured &&\n existingCallInfo.closingBraceAbsolutePos >= 0\n ) {\n const missingKeys = Object.keys(extractedContent).filter(\n (k) => !existingCallInfo.existingDestructuredKeys.includes(k)\n );\n\n if (missingKeys.length > 0) {\n // Insert right after the last property so the space/newline before `}`\n // is naturally preserved: `{ a }` → `{ a, b }`.\n magic.appendLeft(\n existingCallInfo.lastPropAbsoluteEnd,\n `, ${missingKeys.join(', ')}`\n );\n }\n }\n\n // Inject necessary imports and setup\n const hasUseIntlayerImport =\n /import\\s*{[^}]*useIntlayer[^}]*}\\s*from\\s*['\"][^'\"]+['\"]/.test(\n scriptContent\n ) || /import\\s+useIntlayer\\s+from\\s*['\"][^'\"]+['\"]/.test(scriptContent);\n\n const hasGetImport =\n /import\\s*{[^}]*get[^}]*}\\s*from\\s*['\"]svelte\\/store['\"]/.test(\n scriptContent\n );\n\n // An existing call (destructured or not) means no new declaration is needed.\n const hasContentDeclaration =\n existingCallInfo !== null ||\n /const\\s+content\\s*=\\s*useIntlayer\\s*\\(/.test(scriptContent);\n\n const importStmt = hasUseIntlayerImport\n ? ''\n : `import { useIntlayer } from '${packageName}';`;\n const getImportStmt =\n hasScriptExtraction && !isDestructured && !hasGetImport\n ? `import { get } from 'svelte/store';`\n : '';\n const contentDecl = hasContentDeclaration\n ? ''\n : `const content = useIntlayer('${dictionaryKey}');`;\n\n const injectionParts = [importStmt, getImportStmt, contentDecl].filter(\n Boolean\n );\n\n if (injectionParts.length > 0) {\n const injection = `\\n ${injectionParts.join('\\n ')}\\n`;\n\n if (scriptMatch) {\n const scriptContentStart =\n scriptMatch.index + scriptMatch[0].indexOf('>') + 1;\n magic.appendLeft(scriptContentStart, injection);\n } else {\n magic.prepend(\n `<script>\\n ${importStmt}\\n ${hasScriptExtraction ? \"import { get } from 'svelte/store';\" : ''}\\n ${contentDecl}\\n</script>\\n\\n`\n );\n }\n }\n\n if (onExtract) {\n onExtract({\n dictionaryKey,\n filePath: filename,\n content: extractedContent,\n locale: defaultLocale,\n });\n }\n\n return {\n code: magic.toString(),\n map: magic.generateMap({ source: filename, includeContent: true }),\n extracted: true,\n };\n};\n\ntype Tools = {\n generateKey: (text: string, existingKeys: Set<string>) => string;\n shouldExtract: (text: string) => boolean;\n extractDictionaryKeyFromPath: (path: string) => string;\n attributesToExtract: readonly string[];\n extractTsContent: any;\n};\n\nexport const processSvelteFile = (\n filePath: string,\n _componentKey: string,\n packageName: string,\n tools: Tools,\n save: boolean = true\n): {\n extractedContent: Record<string, string>;\n code: string;\n map?: any;\n} | null => {\n const code = readFileSync(filePath, 'utf-8');\n let extractedContent: Record<string, string> | null = null;\n\n const result = intlayerSvelteExtract(code, filePath, {\n packageName,\n dictionaryKey: _componentKey,\n shouldExtract: tools.shouldExtract,\n generateKey: tools.generateKey,\n extractDictionaryKeyFromPath: tools.extractDictionaryKeyFromPath,\n attributesToExtract: tools.attributesToExtract,\n onExtract: (extractResult) => {\n extractedContent = extractResult.content;\n },\n });\n\n if (!result) return null;\n\n if (save) {\n writeFileSync(filePath, result.code);\n }\n\n return {\n extractedContent: extractedContent!,\n code: result.code,\n map: result.map,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"svelte-intlayer-extract.cjs","names":["t","DEFAULT_LOCALE","MagicString"],"sources":["../../src/svelte-intlayer-extract.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { parse as babelParse, types as t, traverse } from '@babel/core';\nimport { DEFAULT_LOCALE } from '@intlayer/config/defaultValues';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport MagicString from 'magic-string';\nimport { parse } from 'svelte/compiler';\n\ntype ExistingCallInfo = {\n isDestructured: boolean;\n existingDestructuredKeys: string[];\n /** The variable name used to store the call result (e.g. `t` in `const t = useIntlayer(...)`) */\n variableName: string;\n /** Absolute position of `}` in the full file — only valid when `isDestructured` */\n closingBraceAbsolutePos: number;\n /** Absolute position of end of last property — only valid when `isDestructured` */\n lastPropAbsoluteEnd: number;\n} | null;\n\n/**\n * Detects whether a script block already contains a `useIntlayer` /\n * `getIntlayer` call and whether its result is destructured.\n */\nconst detectExistingIntlayerCall = (\n scriptText: string,\n absoluteOffset: number\n): ExistingCallInfo => {\n let info: ExistingCallInfo = null;\n\n try {\n const ast = babelParse(scriptText, {\n parserOpts: { sourceType: 'module', plugins: ['typescript', 'jsx'] },\n });\n\n if (!ast) return null;\n\n traverse(ast, {\n CallExpression(path: any) {\n const callee = path.node.callee;\n\n if (\n !t.isIdentifier(callee) ||\n (callee.name !== 'useIntlayer' && callee.name !== 'getIntlayer')\n )\n return;\n\n const parent = path.parent;\n\n if (t.isVariableDeclarator(parent) && t.isObjectPattern(parent.id)) {\n const properties = parent.id.properties;\n const existingDestructuredKeys = properties\n .filter(\n (p: any): p is typeof t.objectProperty =>\n t.isObjectProperty(p) && t.isIdentifier(p.key)\n )\n .map((p: any) => (p.key as any).name as string);\n const lastProp = properties[properties.length - 1];\n\n info = {\n isDestructured: true,\n variableName: 'content',\n existingDestructuredKeys,\n closingBraceAbsolutePos: absoluteOffset + (parent.id.end! - 1),\n lastPropAbsoluteEnd: absoluteOffset + lastProp.end!,\n };\n } else {\n const variableName =\n t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)\n ? parent.id.name\n : 'content';\n\n info = {\n isDestructured: false,\n variableName,\n existingDestructuredKeys: [],\n closingBraceAbsolutePos: -1,\n lastPropAbsoluteEnd: -1,\n };\n }\n\n path.stop();\n },\n });\n } catch {\n // Silently ignore parse failures — fall back to no-info\n }\n\n return info;\n};\n\nexport type ExtractedContent = Record<string, string>;\n\nexport type ExtractResult = {\n dictionaryKey: string;\n filePath: string;\n content: ExtractedContent;\n locale: Locale;\n};\n\nexport type ExtractPluginOptions = {\n defaultLocale?: Locale;\n packageName?: string;\n filesList?: string[];\n shouldExtract?: (text: string) => boolean;\n onExtract?: (result: ExtractResult) => void;\n dictionaryKey?: string;\n attributesToExtract?: readonly string[];\n extractDictionaryKeyFromPath?: (path: string) => string;\n generateKey?: (text: string, existingKeys: Set<string>) => string;\n};\n\ntype Replacement = {\n start: number;\n end: number;\n replacement: string;\n key: string;\n value: string;\n};\n\n/* ────────────────────────────────────────── helpers ─────────────────────── */\n\nexport const shouldProcessFile = (\n filename: string | undefined,\n filesList?: string[]\n): boolean => {\n if (!filename) return false;\n if (!filesList || filesList.length === 0) return true;\n\n const normalizedFilename = filename.replace(/\\\\/g, '/');\n return filesList.some((f) => {\n const normalizedF = f.replace(/\\\\/g, '/');\n return normalizedF === normalizedFilename;\n });\n};\n\n/* ────────────────────────────────────────── plugin ──────────────────────── */\n\nexport const intlayerSvelteExtract = (\n code: string,\n filename: string,\n options: ExtractPluginOptions = {}\n): { code: string; map?: unknown; extracted: boolean } | null => {\n const {\n defaultLocale = DEFAULT_LOCALE,\n packageName = 'svelte-intlayer',\n filesList,\n shouldExtract,\n onExtract,\n dictionaryKey: dictionaryKeyOption,\n attributesToExtract = [],\n extractDictionaryKeyFromPath,\n generateKey,\n } = options;\n\n if (!shouldProcessFile(filename, filesList)) return null;\n if (!filename.endsWith('.svelte')) return null;\n\n const magic = new MagicString(code);\n const extractedContent: ExtractedContent = {};\n const existingKeys = new Set<string>();\n const dictionaryKey =\n dictionaryKeyOption ?? extractDictionaryKeyFromPath?.(filename) ?? '';\n const replacements: Replacement[] = [];\n\n // Extract and walk Script using Babel\n const scriptRegex = /<script[^>]*>([\\s\\S]*?)<\\/script>/;\n const scriptMatch = scriptRegex.exec(code);\n let hasScriptExtraction = false;\n const scriptContent = scriptMatch ? scriptMatch[1] : '';\n\n // Detect existing call BEFORE walking the template so the access pattern\n // (bare key vs. $content.key) can be chosen consistently.\n const existingCallInfo = scriptMatch\n ? detectExistingIntlayerCall(\n scriptContent,\n scriptMatch.index + scriptMatch[0].indexOf('>') + 1\n )\n : null;\n\n const isDestructured = existingCallInfo?.isDestructured ?? false;\n const varName = existingCallInfo?.variableName ?? 'content';\n\n let ast: any;\n try {\n ast = parse(code);\n } catch (e) {\n console.warn(\n `Svelte extraction: Failed to parse Svelte AST for ${filename}`,\n e\n );\n return null;\n }\n\n // Walk Svelte HTML AST.\n // Svelte 4 used numeric type constants; Svelte 5 uses string type names.\n // We check for both to remain compatible.\n const isTextNode = (node: any) => node.type === 'Text' || node.type === 3;\n const isAttributeNode = (node: any) =>\n node.type === 'Attribute' || node.type === 6;\n const isExpressionTagNode = (node: any): boolean =>\n node.type === 'MustacheTag' ||\n node.type === 8 || // Svelte 4 numeric\n node.type === 'ExpressionTag'; // Svelte 5\n\n const walkSvelte = (node: any) => {\n if (isTextNode(node)) {\n const text = node.data ?? node.content ?? '';\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n // Destructured: each property is a plain value → `{key}`.\n // Otherwise use the reactive store subscription `{$content.key}`.\n const ref = isDestructured ? key : `$${varName}.${key}`;\n replacements.push({\n start: node.start,\n end: node.end,\n replacement: `{${ref}}`,\n key,\n value: text.replace(/\\s+/g, ' ').trim(),\n });\n }\n } else if (\n isAttributeNode(node) &&\n (attributesToExtract as readonly string[]).includes(node.name)\n ) {\n if (node.value && node.value.length === 1 && isTextNode(node.value[0])) {\n const text = node.value[0].data ?? node.value[0].content ?? '';\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `$${varName}.${key}`;\n replacements.push({\n start: node.start,\n end: node.end,\n replacement: `${node.name}={${ref}}`,\n key,\n value: text.trim(),\n });\n }\n }\n }\n\n const children =\n node.children ?? node.fragment?.nodes ?? node.fragment?.children;\n\n // Try to handle mixed text + expression children as an insertion\n if (children?.some(isExpressionTagNode)) {\n const parts: {\n type: 'text' | 'var';\n value: string;\n originalExpr: string;\n }[] = [];\n let hasSignificantText = false;\n let isValid = true;\n\n for (const child of children) {\n if (isTextNode(child)) {\n const text = child.data ?? child.content ?? '';\n if (text.trim().length > 0) hasSignificantText = true;\n parts.push({ type: 'text', value: text, originalExpr: '' });\n } else if (isExpressionTagNode(child)) {\n // Source slice: skip the leading `{` and trailing `}`\n const exprCode = code.slice(child.start + 1, child.end - 1).trim();\n const varName = exprCode.includes('.')\n ? exprCode\n .split('.')\n .pop()!\n .replace(/[^\\w$]/g, '')\n : exprCode;\n parts.push({ type: 'var', value: varName, originalExpr: exprCode });\n } else {\n isValid = false;\n break;\n }\n }\n\n if (\n isValid &&\n hasSignificantText &&\n parts.some((p) => p.type === 'var')\n ) {\n let combined = '';\n for (const p of parts) {\n combined += p.type === 'var' ? `{{${p.value}}}` : p.value;\n }\n const cleanString = combined.replace(/\\s+/g, ' ').trim();\n\n if (shouldExtract?.(cleanString) && generateKey) {\n const key = generateKey(cleanString, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `$${varName}.${key}`;\n\n const uniqueVarPairs = [\n ...new Set(\n parts\n .filter((p) => p.type === 'var')\n .map((p) => `${p.value}: ${p.originalExpr}`)\n ),\n ];\n const varArgs = uniqueVarPairs.join(', ');\n const replacement = `{${ref}({ ${varArgs} })}`;\n\n const firstChild = children[0];\n const lastChild = children[children.length - 1];\n replacements.push({\n start: firstChild.start,\n end: lastChild.end,\n replacement,\n key,\n value: cleanString,\n });\n\n // Don't recurse into these children\n if (node.attributes) node.attributes.forEach(walkSvelte);\n return;\n }\n }\n }\n\n if (children) children.forEach(walkSvelte);\n if (node.attributes) node.attributes.forEach(walkSvelte);\n };\n\n if (ast.html) {\n walkSvelte(ast.html);\n }\n\n if (scriptMatch) {\n const openTagEndIndex = scriptMatch[0].indexOf('>') + 1;\n const offset = scriptMatch.index + openTagEndIndex;\n\n try {\n const babelAst = babelParse(scriptContent, {\n parserOpts: {\n sourceType: 'module',\n plugins: ['typescript', 'jsx'],\n },\n });\n\n if (babelAst) {\n traverse(babelAst, {\n StringLiteral(path: any) {\n if (path.parentPath.isImportDeclaration()) return;\n if (path.parentPath.isExportDeclaration()) return;\n if (path.parentPath.isImportSpecifier()) return;\n if (path.parentPath.isObjectProperty() && path.key === 'key')\n return;\n\n if (path.parentPath.isCallExpression()) {\n const callee = path.parentPath.node.callee;\n if (\n t.isMemberExpression(callee) &&\n t.isIdentifier(callee.object) &&\n callee.object.name === 'console'\n )\n return;\n\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 't')\n )\n return;\n\n if (callee.type === 'Import') return;\n if (t.isIdentifier(callee) && callee.name === 'require') return;\n }\n\n const text = path.node.value;\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n hasScriptExtraction = true;\n\n if (path.node.start != null && path.node.end != null) {\n // Destructured: each property is a plain value → access directly.\n // Otherwise use `get(content).key` to read the Svelte store.\n const ref = isDestructured ? key : `get(${varName}).${key}`;\n replacements.push({\n start: offset + path.node.start,\n end: offset + path.node.end,\n replacement: ref,\n key,\n value: text.trim(),\n });\n }\n }\n },\n });\n }\n } catch (error) {\n console.warn(\n `Svelte extraction: Failed to parse script content for ${filename}`,\n error\n );\n }\n }\n\n // Abort if nothing was extracted\n if (replacements.length === 0) return null;\n\n // Apply Replacements in Reverse Order (prevents magic-string chunk errors)\n replacements.sort((a, b) => b.start - a.start);\n for (const { start, end, replacement, key, value } of replacements) {\n magic.overwrite(start, end, replacement);\n extractedContent[key] = value;\n }\n\n // When the existing call is destructured, inject only the missing keys into\n // the ObjectPattern — no new `content` variable is needed.\n if (\n existingCallInfo?.isDestructured &&\n existingCallInfo.closingBraceAbsolutePos >= 0\n ) {\n const missingKeys = Object.keys(extractedContent).filter(\n (k) => !existingCallInfo.existingDestructuredKeys.includes(k)\n );\n\n if (missingKeys.length > 0) {\n // Insert right after the last property so the space/newline before `}`\n // is naturally preserved: `{ a }` → `{ a, b }`.\n magic.appendLeft(\n existingCallInfo.lastPropAbsoluteEnd,\n `, ${missingKeys.join(', ')}`\n );\n }\n }\n\n // Inject necessary imports and setup\n const hasUseIntlayerImport =\n /import\\s*{[^}]*useIntlayer[^}]*}\\s*from\\s*['\"][^'\"]+['\"]/.test(\n scriptContent\n ) || /import\\s+useIntlayer\\s+from\\s*['\"][^'\"]+['\"]/.test(scriptContent);\n\n const hasGetImport =\n /import\\s*{[^}]*get[^}]*}\\s*from\\s*['\"]svelte\\/store['\"]/.test(\n scriptContent\n );\n\n // An existing call (destructured or not) means no new declaration is needed.\n const hasContentDeclaration =\n existingCallInfo !== null ||\n /const\\s+content\\s*=\\s*useIntlayer\\s*\\(/.test(scriptContent);\n\n const importStmt = hasUseIntlayerImport\n ? ''\n : `import { useIntlayer } from '${packageName}';`;\n const getImportStmt =\n hasScriptExtraction && !isDestructured && !hasGetImport\n ? `import { get } from 'svelte/store';`\n : '';\n const contentDecl = hasContentDeclaration\n ? ''\n : `const content = useIntlayer('${dictionaryKey}');`;\n\n const injectionParts = [importStmt, getImportStmt, contentDecl].filter(\n Boolean\n );\n\n if (injectionParts.length > 0) {\n const injection = `\\n ${injectionParts.join('\\n ')}\\n`;\n\n if (scriptMatch) {\n const scriptContentStart =\n scriptMatch.index + scriptMatch[0].indexOf('>') + 1;\n magic.appendLeft(scriptContentStart, injection);\n } else {\n magic.prepend(\n `<script>\\n ${importStmt}\\n ${hasScriptExtraction ? \"import { get } from 'svelte/store';\" : ''}\\n ${contentDecl}\\n</script>\\n\\n`\n );\n }\n }\n\n if (onExtract) {\n onExtract({\n dictionaryKey,\n filePath: filename,\n content: extractedContent,\n locale: defaultLocale,\n });\n }\n\n return {\n code: magic.toString(),\n map: magic.generateMap({ source: filename, includeContent: true }),\n extracted: true,\n };\n};\n\ntype Tools = {\n generateKey: (text: string, existingKeys: Set<string>) => string;\n shouldExtract: (text: string) => boolean;\n extractDictionaryKeyFromPath: (path: string) => string;\n attributesToExtract: readonly string[];\n extractTsContent: any;\n};\n\nexport const processSvelteFile = (\n filePath: string,\n _componentKey: string,\n packageName: string,\n tools: Tools,\n save: boolean = true,\n providedCode?: string\n): {\n extractedContent: Record<string, string>;\n code: string;\n map?: any;\n} | null => {\n const code = providedCode ?? readFileSync(filePath, 'utf-8');\n let extractedContent: Record<string, string> | null = null;\n\n const result = intlayerSvelteExtract(code, filePath, {\n packageName,\n dictionaryKey: _componentKey,\n shouldExtract: tools.shouldExtract,\n generateKey: tools.generateKey,\n extractDictionaryKeyFromPath: tools.extractDictionaryKeyFromPath,\n attributesToExtract: tools.attributesToExtract,\n onExtract: (extractResult) => {\n extractedContent = extractResult.content;\n },\n });\n\n if (!result) return null;\n\n if (save) {\n writeFileSync(filePath, result.code);\n }\n\n return {\n extractedContent: extractedContent!,\n code: result.code,\n map: result.map,\n };\n};\n"],"mappings":"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"}
@@ -244,8 +244,8 @@ const intlayerSvelteExtract = (code, filename, options = {}) => {
244
244
  extracted: true
245
245
  };
246
246
  };
247
- const processSvelteFile = (filePath, _componentKey, packageName, tools, save = true) => {
248
- const code = readFileSync(filePath, "utf-8");
247
+ const processSvelteFile = (filePath, _componentKey, packageName, tools, save = true, providedCode) => {
248
+ const code = providedCode ?? readFileSync(filePath, "utf-8");
249
249
  let extractedContent = null;
250
250
  const result = intlayerSvelteExtract(code, filePath, {
251
251
  packageName,
@@ -1 +1 @@
1
- {"version":3,"file":"svelte-intlayer-extract.mjs","names":["babelParse","t","parse"],"sources":["../../src/svelte-intlayer-extract.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { parse as babelParse, types as t, traverse } from '@babel/core';\nimport { DEFAULT_LOCALE } from '@intlayer/config/defaultValues';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport MagicString from 'magic-string';\nimport { parse } from 'svelte/compiler';\n\ntype ExistingCallInfo = {\n isDestructured: boolean;\n existingDestructuredKeys: string[];\n /** The variable name used to store the call result (e.g. `t` in `const t = useIntlayer(...)`) */\n variableName: string;\n /** Absolute position of `}` in the full file — only valid when `isDestructured` */\n closingBraceAbsolutePos: number;\n /** Absolute position of end of last property — only valid when `isDestructured` */\n lastPropAbsoluteEnd: number;\n} | null;\n\n/**\n * Detects whether a script block already contains a `useIntlayer` /\n * `getIntlayer` call and whether its result is destructured.\n */\nconst detectExistingIntlayerCall = (\n scriptText: string,\n absoluteOffset: number\n): ExistingCallInfo => {\n let info: ExistingCallInfo = null;\n\n try {\n const ast = babelParse(scriptText, {\n parserOpts: { sourceType: 'module', plugins: ['typescript', 'jsx'] },\n });\n\n if (!ast) return null;\n\n traverse(ast, {\n CallExpression(path: any) {\n const callee = path.node.callee;\n\n if (\n !t.isIdentifier(callee) ||\n (callee.name !== 'useIntlayer' && callee.name !== 'getIntlayer')\n )\n return;\n\n const parent = path.parent;\n\n if (t.isVariableDeclarator(parent) && t.isObjectPattern(parent.id)) {\n const properties = parent.id.properties;\n const existingDestructuredKeys = properties\n .filter(\n (p: any): p is typeof t.objectProperty =>\n t.isObjectProperty(p) && t.isIdentifier(p.key)\n )\n .map((p: any) => (p.key as any).name as string);\n const lastProp = properties[properties.length - 1];\n\n info = {\n isDestructured: true,\n variableName: 'content',\n existingDestructuredKeys,\n closingBraceAbsolutePos: absoluteOffset + (parent.id.end! - 1),\n lastPropAbsoluteEnd: absoluteOffset + lastProp.end!,\n };\n } else {\n const variableName =\n t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)\n ? parent.id.name\n : 'content';\n\n info = {\n isDestructured: false,\n variableName,\n existingDestructuredKeys: [],\n closingBraceAbsolutePos: -1,\n lastPropAbsoluteEnd: -1,\n };\n }\n\n path.stop();\n },\n });\n } catch {\n // Silently ignore parse failures — fall back to no-info\n }\n\n return info;\n};\n\nexport type ExtractedContent = Record<string, string>;\n\nexport type ExtractResult = {\n dictionaryKey: string;\n filePath: string;\n content: ExtractedContent;\n locale: Locale;\n};\n\nexport type ExtractPluginOptions = {\n defaultLocale?: Locale;\n packageName?: string;\n filesList?: string[];\n shouldExtract?: (text: string) => boolean;\n onExtract?: (result: ExtractResult) => void;\n dictionaryKey?: string;\n attributesToExtract?: readonly string[];\n extractDictionaryKeyFromPath?: (path: string) => string;\n generateKey?: (text: string, existingKeys: Set<string>) => string;\n};\n\ntype Replacement = {\n start: number;\n end: number;\n replacement: string;\n key: string;\n value: string;\n};\n\n/* ────────────────────────────────────────── helpers ─────────────────────── */\n\nexport const shouldProcessFile = (\n filename: string | undefined,\n filesList?: string[]\n): boolean => {\n if (!filename) return false;\n if (!filesList || filesList.length === 0) return true;\n\n const normalizedFilename = filename.replace(/\\\\/g, '/');\n return filesList.some((f) => {\n const normalizedF = f.replace(/\\\\/g, '/');\n return normalizedF === normalizedFilename;\n });\n};\n\n/* ────────────────────────────────────────── plugin ──────────────────────── */\n\nexport const intlayerSvelteExtract = (\n code: string,\n filename: string,\n options: ExtractPluginOptions = {}\n): { code: string; map?: unknown; extracted: boolean } | null => {\n const {\n defaultLocale = DEFAULT_LOCALE,\n packageName = 'svelte-intlayer',\n filesList,\n shouldExtract,\n onExtract,\n dictionaryKey: dictionaryKeyOption,\n attributesToExtract = [],\n extractDictionaryKeyFromPath,\n generateKey,\n } = options;\n\n if (!shouldProcessFile(filename, filesList)) return null;\n if (!filename.endsWith('.svelte')) return null;\n\n const magic = new MagicString(code);\n const extractedContent: ExtractedContent = {};\n const existingKeys = new Set<string>();\n const dictionaryKey =\n dictionaryKeyOption ?? extractDictionaryKeyFromPath?.(filename) ?? '';\n const replacements: Replacement[] = [];\n\n // Extract and walk Script using Babel\n const scriptRegex = /<script[^>]*>([\\s\\S]*?)<\\/script>/;\n const scriptMatch = scriptRegex.exec(code);\n let hasScriptExtraction = false;\n const scriptContent = scriptMatch ? scriptMatch[1] : '';\n\n // Detect existing call BEFORE walking the template so the access pattern\n // (bare key vs. $content.key) can be chosen consistently.\n const existingCallInfo = scriptMatch\n ? detectExistingIntlayerCall(\n scriptContent,\n scriptMatch.index + scriptMatch[0].indexOf('>') + 1\n )\n : null;\n\n const isDestructured = existingCallInfo?.isDestructured ?? false;\n const varName = existingCallInfo?.variableName ?? 'content';\n\n let ast: any;\n try {\n ast = parse(code);\n } catch (e) {\n console.warn(\n `Svelte extraction: Failed to parse Svelte AST for ${filename}`,\n e\n );\n return null;\n }\n\n // Walk Svelte HTML AST.\n // Svelte 4 used numeric type constants; Svelte 5 uses string type names.\n // We check for both to remain compatible.\n const isTextNode = (node: any) => node.type === 'Text' || node.type === 3;\n const isAttributeNode = (node: any) =>\n node.type === 'Attribute' || node.type === 6;\n const isExpressionTagNode = (node: any): boolean =>\n node.type === 'MustacheTag' ||\n node.type === 8 || // Svelte 4 numeric\n node.type === 'ExpressionTag'; // Svelte 5\n\n const walkSvelte = (node: any) => {\n if (isTextNode(node)) {\n const text = node.data ?? node.content ?? '';\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n // Destructured: each property is a plain value → `{key}`.\n // Otherwise use the reactive store subscription `{$content.key}`.\n const ref = isDestructured ? key : `$${varName}.${key}`;\n replacements.push({\n start: node.start,\n end: node.end,\n replacement: `{${ref}}`,\n key,\n value: text.replace(/\\s+/g, ' ').trim(),\n });\n }\n } else if (\n isAttributeNode(node) &&\n (attributesToExtract as readonly string[]).includes(node.name)\n ) {\n if (node.value && node.value.length === 1 && isTextNode(node.value[0])) {\n const text = node.value[0].data ?? node.value[0].content ?? '';\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `$${varName}.${key}`;\n replacements.push({\n start: node.start,\n end: node.end,\n replacement: `${node.name}={${ref}}`,\n key,\n value: text.trim(),\n });\n }\n }\n }\n\n const children =\n node.children ?? node.fragment?.nodes ?? node.fragment?.children;\n\n // Try to handle mixed text + expression children as an insertion\n if (children?.some(isExpressionTagNode)) {\n const parts: {\n type: 'text' | 'var';\n value: string;\n originalExpr: string;\n }[] = [];\n let hasSignificantText = false;\n let isValid = true;\n\n for (const child of children) {\n if (isTextNode(child)) {\n const text = child.data ?? child.content ?? '';\n if (text.trim().length > 0) hasSignificantText = true;\n parts.push({ type: 'text', value: text, originalExpr: '' });\n } else if (isExpressionTagNode(child)) {\n // Source slice: skip the leading `{` and trailing `}`\n const exprCode = code.slice(child.start + 1, child.end - 1).trim();\n const varName = exprCode.includes('.')\n ? exprCode\n .split('.')\n .pop()!\n .replace(/[^\\w$]/g, '')\n : exprCode;\n parts.push({ type: 'var', value: varName, originalExpr: exprCode });\n } else {\n isValid = false;\n break;\n }\n }\n\n if (\n isValid &&\n hasSignificantText &&\n parts.some((p) => p.type === 'var')\n ) {\n let combined = '';\n for (const p of parts) {\n combined += p.type === 'var' ? `{{${p.value}}}` : p.value;\n }\n const cleanString = combined.replace(/\\s+/g, ' ').trim();\n\n if (shouldExtract?.(cleanString) && generateKey) {\n const key = generateKey(cleanString, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `$${varName}.${key}`;\n\n const uniqueVarPairs = [\n ...new Set(\n parts\n .filter((p) => p.type === 'var')\n .map((p) => `${p.value}: ${p.originalExpr}`)\n ),\n ];\n const varArgs = uniqueVarPairs.join(', ');\n const replacement = `{${ref}({ ${varArgs} })}`;\n\n const firstChild = children[0];\n const lastChild = children[children.length - 1];\n replacements.push({\n start: firstChild.start,\n end: lastChild.end,\n replacement,\n key,\n value: cleanString,\n });\n\n // Don't recurse into these children\n if (node.attributes) node.attributes.forEach(walkSvelte);\n return;\n }\n }\n }\n\n if (children) children.forEach(walkSvelte);\n if (node.attributes) node.attributes.forEach(walkSvelte);\n };\n\n if (ast.html) {\n walkSvelte(ast.html);\n }\n\n if (scriptMatch) {\n const openTagEndIndex = scriptMatch[0].indexOf('>') + 1;\n const offset = scriptMatch.index + openTagEndIndex;\n\n try {\n const babelAst = babelParse(scriptContent, {\n parserOpts: {\n sourceType: 'module',\n plugins: ['typescript', 'jsx'],\n },\n });\n\n if (babelAst) {\n traverse(babelAst, {\n StringLiteral(path: any) {\n if (path.parentPath.isImportDeclaration()) return;\n if (path.parentPath.isExportDeclaration()) return;\n if (path.parentPath.isImportSpecifier()) return;\n if (path.parentPath.isObjectProperty() && path.key === 'key')\n return;\n\n if (path.parentPath.isCallExpression()) {\n const callee = path.parentPath.node.callee;\n if (\n t.isMemberExpression(callee) &&\n t.isIdentifier(callee.object) &&\n callee.object.name === 'console'\n )\n return;\n\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 't')\n )\n return;\n\n if (callee.type === 'Import') return;\n if (t.isIdentifier(callee) && callee.name === 'require') return;\n }\n\n const text = path.node.value;\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n hasScriptExtraction = true;\n\n if (path.node.start != null && path.node.end != null) {\n // Destructured: each property is a plain value → access directly.\n // Otherwise use `get(content).key` to read the Svelte store.\n const ref = isDestructured ? key : `get(${varName}).${key}`;\n replacements.push({\n start: offset + path.node.start,\n end: offset + path.node.end,\n replacement: ref,\n key,\n value: text.trim(),\n });\n }\n }\n },\n });\n }\n } catch (error) {\n console.warn(\n `Svelte extraction: Failed to parse script content for ${filename}`,\n error\n );\n }\n }\n\n // Abort if nothing was extracted\n if (replacements.length === 0) return null;\n\n // Apply Replacements in Reverse Order (prevents magic-string chunk errors)\n replacements.sort((a, b) => b.start - a.start);\n for (const { start, end, replacement, key, value } of replacements) {\n magic.overwrite(start, end, replacement);\n extractedContent[key] = value;\n }\n\n // When the existing call is destructured, inject only the missing keys into\n // the ObjectPattern — no new `content` variable is needed.\n if (\n existingCallInfo?.isDestructured &&\n existingCallInfo.closingBraceAbsolutePos >= 0\n ) {\n const missingKeys = Object.keys(extractedContent).filter(\n (k) => !existingCallInfo.existingDestructuredKeys.includes(k)\n );\n\n if (missingKeys.length > 0) {\n // Insert right after the last property so the space/newline before `}`\n // is naturally preserved: `{ a }` → `{ a, b }`.\n magic.appendLeft(\n existingCallInfo.lastPropAbsoluteEnd,\n `, ${missingKeys.join(', ')}`\n );\n }\n }\n\n // Inject necessary imports and setup\n const hasUseIntlayerImport =\n /import\\s*{[^}]*useIntlayer[^}]*}\\s*from\\s*['\"][^'\"]+['\"]/.test(\n scriptContent\n ) || /import\\s+useIntlayer\\s+from\\s*['\"][^'\"]+['\"]/.test(scriptContent);\n\n const hasGetImport =\n /import\\s*{[^}]*get[^}]*}\\s*from\\s*['\"]svelte\\/store['\"]/.test(\n scriptContent\n );\n\n // An existing call (destructured or not) means no new declaration is needed.\n const hasContentDeclaration =\n existingCallInfo !== null ||\n /const\\s+content\\s*=\\s*useIntlayer\\s*\\(/.test(scriptContent);\n\n const importStmt = hasUseIntlayerImport\n ? ''\n : `import { useIntlayer } from '${packageName}';`;\n const getImportStmt =\n hasScriptExtraction && !isDestructured && !hasGetImport\n ? `import { get } from 'svelte/store';`\n : '';\n const contentDecl = hasContentDeclaration\n ? ''\n : `const content = useIntlayer('${dictionaryKey}');`;\n\n const injectionParts = [importStmt, getImportStmt, contentDecl].filter(\n Boolean\n );\n\n if (injectionParts.length > 0) {\n const injection = `\\n ${injectionParts.join('\\n ')}\\n`;\n\n if (scriptMatch) {\n const scriptContentStart =\n scriptMatch.index + scriptMatch[0].indexOf('>') + 1;\n magic.appendLeft(scriptContentStart, injection);\n } else {\n magic.prepend(\n `<script>\\n ${importStmt}\\n ${hasScriptExtraction ? \"import { get } from 'svelte/store';\" : ''}\\n ${contentDecl}\\n</script>\\n\\n`\n );\n }\n }\n\n if (onExtract) {\n onExtract({\n dictionaryKey,\n filePath: filename,\n content: extractedContent,\n locale: defaultLocale,\n });\n }\n\n return {\n code: magic.toString(),\n map: magic.generateMap({ source: filename, includeContent: true }),\n extracted: true,\n };\n};\n\ntype Tools = {\n generateKey: (text: string, existingKeys: Set<string>) => string;\n shouldExtract: (text: string) => boolean;\n extractDictionaryKeyFromPath: (path: string) => string;\n attributesToExtract: readonly string[];\n extractTsContent: any;\n};\n\nexport const processSvelteFile = (\n filePath: string,\n _componentKey: string,\n packageName: string,\n tools: Tools,\n save: boolean = true\n): {\n extractedContent: Record<string, string>;\n code: string;\n map?: any;\n} | null => {\n const code = readFileSync(filePath, 'utf-8');\n let extractedContent: Record<string, string> | null = null;\n\n const result = intlayerSvelteExtract(code, filePath, {\n packageName,\n dictionaryKey: _componentKey,\n shouldExtract: tools.shouldExtract,\n generateKey: tools.generateKey,\n extractDictionaryKeyFromPath: tools.extractDictionaryKeyFromPath,\n attributesToExtract: tools.attributesToExtract,\n onExtract: (extractResult) => {\n extractedContent = extractResult.content;\n },\n });\n\n if (!result) return null;\n\n if (save) {\n writeFileSync(filePath, result.code);\n }\n\n return {\n extractedContent: extractedContent!,\n code: result.code,\n map: result.map,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"svelte-intlayer-extract.mjs","names":["babelParse","t","parse"],"sources":["../../src/svelte-intlayer-extract.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { parse as babelParse, types as t, traverse } from '@babel/core';\nimport { DEFAULT_LOCALE } from '@intlayer/config/defaultValues';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport MagicString from 'magic-string';\nimport { parse } from 'svelte/compiler';\n\ntype ExistingCallInfo = {\n isDestructured: boolean;\n existingDestructuredKeys: string[];\n /** The variable name used to store the call result (e.g. `t` in `const t = useIntlayer(...)`) */\n variableName: string;\n /** Absolute position of `}` in the full file — only valid when `isDestructured` */\n closingBraceAbsolutePos: number;\n /** Absolute position of end of last property — only valid when `isDestructured` */\n lastPropAbsoluteEnd: number;\n} | null;\n\n/**\n * Detects whether a script block already contains a `useIntlayer` /\n * `getIntlayer` call and whether its result is destructured.\n */\nconst detectExistingIntlayerCall = (\n scriptText: string,\n absoluteOffset: number\n): ExistingCallInfo => {\n let info: ExistingCallInfo = null;\n\n try {\n const ast = babelParse(scriptText, {\n parserOpts: { sourceType: 'module', plugins: ['typescript', 'jsx'] },\n });\n\n if (!ast) return null;\n\n traverse(ast, {\n CallExpression(path: any) {\n const callee = path.node.callee;\n\n if (\n !t.isIdentifier(callee) ||\n (callee.name !== 'useIntlayer' && callee.name !== 'getIntlayer')\n )\n return;\n\n const parent = path.parent;\n\n if (t.isVariableDeclarator(parent) && t.isObjectPattern(parent.id)) {\n const properties = parent.id.properties;\n const existingDestructuredKeys = properties\n .filter(\n (p: any): p is typeof t.objectProperty =>\n t.isObjectProperty(p) && t.isIdentifier(p.key)\n )\n .map((p: any) => (p.key as any).name as string);\n const lastProp = properties[properties.length - 1];\n\n info = {\n isDestructured: true,\n variableName: 'content',\n existingDestructuredKeys,\n closingBraceAbsolutePos: absoluteOffset + (parent.id.end! - 1),\n lastPropAbsoluteEnd: absoluteOffset + lastProp.end!,\n };\n } else {\n const variableName =\n t.isVariableDeclarator(parent) && t.isIdentifier(parent.id)\n ? parent.id.name\n : 'content';\n\n info = {\n isDestructured: false,\n variableName,\n existingDestructuredKeys: [],\n closingBraceAbsolutePos: -1,\n lastPropAbsoluteEnd: -1,\n };\n }\n\n path.stop();\n },\n });\n } catch {\n // Silently ignore parse failures — fall back to no-info\n }\n\n return info;\n};\n\nexport type ExtractedContent = Record<string, string>;\n\nexport type ExtractResult = {\n dictionaryKey: string;\n filePath: string;\n content: ExtractedContent;\n locale: Locale;\n};\n\nexport type ExtractPluginOptions = {\n defaultLocale?: Locale;\n packageName?: string;\n filesList?: string[];\n shouldExtract?: (text: string) => boolean;\n onExtract?: (result: ExtractResult) => void;\n dictionaryKey?: string;\n attributesToExtract?: readonly string[];\n extractDictionaryKeyFromPath?: (path: string) => string;\n generateKey?: (text: string, existingKeys: Set<string>) => string;\n};\n\ntype Replacement = {\n start: number;\n end: number;\n replacement: string;\n key: string;\n value: string;\n};\n\n/* ────────────────────────────────────────── helpers ─────────────────────── */\n\nexport const shouldProcessFile = (\n filename: string | undefined,\n filesList?: string[]\n): boolean => {\n if (!filename) return false;\n if (!filesList || filesList.length === 0) return true;\n\n const normalizedFilename = filename.replace(/\\\\/g, '/');\n return filesList.some((f) => {\n const normalizedF = f.replace(/\\\\/g, '/');\n return normalizedF === normalizedFilename;\n });\n};\n\n/* ────────────────────────────────────────── plugin ──────────────────────── */\n\nexport const intlayerSvelteExtract = (\n code: string,\n filename: string,\n options: ExtractPluginOptions = {}\n): { code: string; map?: unknown; extracted: boolean } | null => {\n const {\n defaultLocale = DEFAULT_LOCALE,\n packageName = 'svelte-intlayer',\n filesList,\n shouldExtract,\n onExtract,\n dictionaryKey: dictionaryKeyOption,\n attributesToExtract = [],\n extractDictionaryKeyFromPath,\n generateKey,\n } = options;\n\n if (!shouldProcessFile(filename, filesList)) return null;\n if (!filename.endsWith('.svelte')) return null;\n\n const magic = new MagicString(code);\n const extractedContent: ExtractedContent = {};\n const existingKeys = new Set<string>();\n const dictionaryKey =\n dictionaryKeyOption ?? extractDictionaryKeyFromPath?.(filename) ?? '';\n const replacements: Replacement[] = [];\n\n // Extract and walk Script using Babel\n const scriptRegex = /<script[^>]*>([\\s\\S]*?)<\\/script>/;\n const scriptMatch = scriptRegex.exec(code);\n let hasScriptExtraction = false;\n const scriptContent = scriptMatch ? scriptMatch[1] : '';\n\n // Detect existing call BEFORE walking the template so the access pattern\n // (bare key vs. $content.key) can be chosen consistently.\n const existingCallInfo = scriptMatch\n ? detectExistingIntlayerCall(\n scriptContent,\n scriptMatch.index + scriptMatch[0].indexOf('>') + 1\n )\n : null;\n\n const isDestructured = existingCallInfo?.isDestructured ?? false;\n const varName = existingCallInfo?.variableName ?? 'content';\n\n let ast: any;\n try {\n ast = parse(code);\n } catch (e) {\n console.warn(\n `Svelte extraction: Failed to parse Svelte AST for ${filename}`,\n e\n );\n return null;\n }\n\n // Walk Svelte HTML AST.\n // Svelte 4 used numeric type constants; Svelte 5 uses string type names.\n // We check for both to remain compatible.\n const isTextNode = (node: any) => node.type === 'Text' || node.type === 3;\n const isAttributeNode = (node: any) =>\n node.type === 'Attribute' || node.type === 6;\n const isExpressionTagNode = (node: any): boolean =>\n node.type === 'MustacheTag' ||\n node.type === 8 || // Svelte 4 numeric\n node.type === 'ExpressionTag'; // Svelte 5\n\n const walkSvelte = (node: any) => {\n if (isTextNode(node)) {\n const text = node.data ?? node.content ?? '';\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n // Destructured: each property is a plain value → `{key}`.\n // Otherwise use the reactive store subscription `{$content.key}`.\n const ref = isDestructured ? key : `$${varName}.${key}`;\n replacements.push({\n start: node.start,\n end: node.end,\n replacement: `{${ref}}`,\n key,\n value: text.replace(/\\s+/g, ' ').trim(),\n });\n }\n } else if (\n isAttributeNode(node) &&\n (attributesToExtract as readonly string[]).includes(node.name)\n ) {\n if (node.value && node.value.length === 1 && isTextNode(node.value[0])) {\n const text = node.value[0].data ?? node.value[0].content ?? '';\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `$${varName}.${key}`;\n replacements.push({\n start: node.start,\n end: node.end,\n replacement: `${node.name}={${ref}}`,\n key,\n value: text.trim(),\n });\n }\n }\n }\n\n const children =\n node.children ?? node.fragment?.nodes ?? node.fragment?.children;\n\n // Try to handle mixed text + expression children as an insertion\n if (children?.some(isExpressionTagNode)) {\n const parts: {\n type: 'text' | 'var';\n value: string;\n originalExpr: string;\n }[] = [];\n let hasSignificantText = false;\n let isValid = true;\n\n for (const child of children) {\n if (isTextNode(child)) {\n const text = child.data ?? child.content ?? '';\n if (text.trim().length > 0) hasSignificantText = true;\n parts.push({ type: 'text', value: text, originalExpr: '' });\n } else if (isExpressionTagNode(child)) {\n // Source slice: skip the leading `{` and trailing `}`\n const exprCode = code.slice(child.start + 1, child.end - 1).trim();\n const varName = exprCode.includes('.')\n ? exprCode\n .split('.')\n .pop()!\n .replace(/[^\\w$]/g, '')\n : exprCode;\n parts.push({ type: 'var', value: varName, originalExpr: exprCode });\n } else {\n isValid = false;\n break;\n }\n }\n\n if (\n isValid &&\n hasSignificantText &&\n parts.some((p) => p.type === 'var')\n ) {\n let combined = '';\n for (const p of parts) {\n combined += p.type === 'var' ? `{{${p.value}}}` : p.value;\n }\n const cleanString = combined.replace(/\\s+/g, ' ').trim();\n\n if (shouldExtract?.(cleanString) && generateKey) {\n const key = generateKey(cleanString, existingKeys);\n existingKeys.add(key);\n const ref = isDestructured ? key : `$${varName}.${key}`;\n\n const uniqueVarPairs = [\n ...new Set(\n parts\n .filter((p) => p.type === 'var')\n .map((p) => `${p.value}: ${p.originalExpr}`)\n ),\n ];\n const varArgs = uniqueVarPairs.join(', ');\n const replacement = `{${ref}({ ${varArgs} })}`;\n\n const firstChild = children[0];\n const lastChild = children[children.length - 1];\n replacements.push({\n start: firstChild.start,\n end: lastChild.end,\n replacement,\n key,\n value: cleanString,\n });\n\n // Don't recurse into these children\n if (node.attributes) node.attributes.forEach(walkSvelte);\n return;\n }\n }\n }\n\n if (children) children.forEach(walkSvelte);\n if (node.attributes) node.attributes.forEach(walkSvelte);\n };\n\n if (ast.html) {\n walkSvelte(ast.html);\n }\n\n if (scriptMatch) {\n const openTagEndIndex = scriptMatch[0].indexOf('>') + 1;\n const offset = scriptMatch.index + openTagEndIndex;\n\n try {\n const babelAst = babelParse(scriptContent, {\n parserOpts: {\n sourceType: 'module',\n plugins: ['typescript', 'jsx'],\n },\n });\n\n if (babelAst) {\n traverse(babelAst, {\n StringLiteral(path: any) {\n if (path.parentPath.isImportDeclaration()) return;\n if (path.parentPath.isExportDeclaration()) return;\n if (path.parentPath.isImportSpecifier()) return;\n if (path.parentPath.isObjectProperty() && path.key === 'key')\n return;\n\n if (path.parentPath.isCallExpression()) {\n const callee = path.parentPath.node.callee;\n if (\n t.isMemberExpression(callee) &&\n t.isIdentifier(callee.object) &&\n callee.object.name === 'console'\n )\n return;\n\n if (\n t.isIdentifier(callee) &&\n (callee.name === 'useIntlayer' || callee.name === 't')\n )\n return;\n\n if (callee.type === 'Import') return;\n if (t.isIdentifier(callee) && callee.name === 'require') return;\n }\n\n const text = path.node.value;\n if (shouldExtract?.(text) && generateKey) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n hasScriptExtraction = true;\n\n if (path.node.start != null && path.node.end != null) {\n // Destructured: each property is a plain value → access directly.\n // Otherwise use `get(content).key` to read the Svelte store.\n const ref = isDestructured ? key : `get(${varName}).${key}`;\n replacements.push({\n start: offset + path.node.start,\n end: offset + path.node.end,\n replacement: ref,\n key,\n value: text.trim(),\n });\n }\n }\n },\n });\n }\n } catch (error) {\n console.warn(\n `Svelte extraction: Failed to parse script content for ${filename}`,\n error\n );\n }\n }\n\n // Abort if nothing was extracted\n if (replacements.length === 0) return null;\n\n // Apply Replacements in Reverse Order (prevents magic-string chunk errors)\n replacements.sort((a, b) => b.start - a.start);\n for (const { start, end, replacement, key, value } of replacements) {\n magic.overwrite(start, end, replacement);\n extractedContent[key] = value;\n }\n\n // When the existing call is destructured, inject only the missing keys into\n // the ObjectPattern — no new `content` variable is needed.\n if (\n existingCallInfo?.isDestructured &&\n existingCallInfo.closingBraceAbsolutePos >= 0\n ) {\n const missingKeys = Object.keys(extractedContent).filter(\n (k) => !existingCallInfo.existingDestructuredKeys.includes(k)\n );\n\n if (missingKeys.length > 0) {\n // Insert right after the last property so the space/newline before `}`\n // is naturally preserved: `{ a }` → `{ a, b }`.\n magic.appendLeft(\n existingCallInfo.lastPropAbsoluteEnd,\n `, ${missingKeys.join(', ')}`\n );\n }\n }\n\n // Inject necessary imports and setup\n const hasUseIntlayerImport =\n /import\\s*{[^}]*useIntlayer[^}]*}\\s*from\\s*['\"][^'\"]+['\"]/.test(\n scriptContent\n ) || /import\\s+useIntlayer\\s+from\\s*['\"][^'\"]+['\"]/.test(scriptContent);\n\n const hasGetImport =\n /import\\s*{[^}]*get[^}]*}\\s*from\\s*['\"]svelte\\/store['\"]/.test(\n scriptContent\n );\n\n // An existing call (destructured or not) means no new declaration is needed.\n const hasContentDeclaration =\n existingCallInfo !== null ||\n /const\\s+content\\s*=\\s*useIntlayer\\s*\\(/.test(scriptContent);\n\n const importStmt = hasUseIntlayerImport\n ? ''\n : `import { useIntlayer } from '${packageName}';`;\n const getImportStmt =\n hasScriptExtraction && !isDestructured && !hasGetImport\n ? `import { get } from 'svelte/store';`\n : '';\n const contentDecl = hasContentDeclaration\n ? ''\n : `const content = useIntlayer('${dictionaryKey}');`;\n\n const injectionParts = [importStmt, getImportStmt, contentDecl].filter(\n Boolean\n );\n\n if (injectionParts.length > 0) {\n const injection = `\\n ${injectionParts.join('\\n ')}\\n`;\n\n if (scriptMatch) {\n const scriptContentStart =\n scriptMatch.index + scriptMatch[0].indexOf('>') + 1;\n magic.appendLeft(scriptContentStart, injection);\n } else {\n magic.prepend(\n `<script>\\n ${importStmt}\\n ${hasScriptExtraction ? \"import { get } from 'svelte/store';\" : ''}\\n ${contentDecl}\\n</script>\\n\\n`\n );\n }\n }\n\n if (onExtract) {\n onExtract({\n dictionaryKey,\n filePath: filename,\n content: extractedContent,\n locale: defaultLocale,\n });\n }\n\n return {\n code: magic.toString(),\n map: magic.generateMap({ source: filename, includeContent: true }),\n extracted: true,\n };\n};\n\ntype Tools = {\n generateKey: (text: string, existingKeys: Set<string>) => string;\n shouldExtract: (text: string) => boolean;\n extractDictionaryKeyFromPath: (path: string) => string;\n attributesToExtract: readonly string[];\n extractTsContent: any;\n};\n\nexport const processSvelteFile = (\n filePath: string,\n _componentKey: string,\n packageName: string,\n tools: Tools,\n save: boolean = true,\n providedCode?: string\n): {\n extractedContent: Record<string, string>;\n code: string;\n map?: any;\n} | null => {\n const code = providedCode ?? readFileSync(filePath, 'utf-8');\n let extractedContent: Record<string, string> | null = null;\n\n const result = intlayerSvelteExtract(code, filePath, {\n packageName,\n dictionaryKey: _componentKey,\n shouldExtract: tools.shouldExtract,\n generateKey: tools.generateKey,\n extractDictionaryKeyFromPath: tools.extractDictionaryKeyFromPath,\n attributesToExtract: tools.attributesToExtract,\n onExtract: (extractResult) => {\n extractedContent = extractResult.content;\n },\n });\n\n if (!result) return null;\n\n if (save) {\n writeFileSync(filePath, result.code);\n }\n\n return {\n extractedContent: extractedContent!,\n code: result.code,\n map: result.map,\n };\n};\n"],"mappings":"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"}
@@ -32,7 +32,7 @@ type Tools = {
32
32
  attributesToExtract: readonly string[];
33
33
  extractTsContent: any;
34
34
  };
35
- declare const processSvelteFile: (filePath: string, _componentKey: string, packageName: string, tools: Tools, save?: boolean) => {
35
+ declare const processSvelteFile: (filePath: string, _componentKey: string, packageName: string, tools: Tools, save?: boolean, providedCode?: string) => {
36
36
  extractedContent: Record<string, string>;
37
37
  code: string;
38
38
  map?: any;
@@ -1 +1 @@
1
- {"version":3,"file":"svelte-intlayer-extract.d.ts","names":[],"sources":["../../src/svelte-intlayer-extract.ts"],"mappings":";;;KAyFY,gBAAA,GAAmB,MAAA;AAAA,KAEnB,aAAA;EACV,aAAA;EACA,QAAA;EACA,OAAA,EAAS,gBAAA;EACT,MAAA,EAAQ,MAAA;AAAA;AAAA,KAGE,oBAAA;EACV,aAAA,GAAgB,MAAA;EAChB,WAAA;EACA,SAAA;EACA,aAAA,IAAiB,IAAA;EACjB,SAAA,IAAa,MAAA,EAAQ,aAAA;EACrB,aAAA;EACA,mBAAA;EACA,4BAAA,IAAgC,IAAA;EAChC,WAAA,IAAe,IAAA,UAAc,YAAA,EAAc,GAAA;AAAA;AAAA,cAahC,iBAAA,GACX,QAAA,sBACA,SAAA;AAAA,cAcW,qBAAA,GACX,IAAA,UACA,QAAA,UACA,OAAA,GAAS,oBAAA;EACN,IAAA;EAAc,GAAA;EAAe,SAAA;AAAA;AAAA,KA2V7B,KAAA;EACH,WAAA,GAAc,IAAA,UAAc,YAAA,EAAc,GAAA;EAC1C,aAAA,GAAgB,IAAA;EAChB,4BAAA,GAA+B,IAAA;EAC/B,mBAAA;EACA,gBAAA;AAAA;AAAA,cAGW,iBAAA,GACX,QAAA,UACA,aAAA,UACA,WAAA,UACA,KAAA,EAAO,KAAA,EACP,IAAA;EAEA,gBAAA,EAAkB,MAAA;EAClB,IAAA;EACA,GAAA;AAAA"}
1
+ {"version":3,"file":"svelte-intlayer-extract.d.ts","names":[],"sources":["../../src/svelte-intlayer-extract.ts"],"mappings":";;;KAyFY,gBAAA,GAAmB,MAAA;AAAA,KAEnB,aAAA;EACV,aAAA;EACA,QAAA;EACA,OAAA,EAAS,gBAAA;EACT,MAAA,EAAQ,MAAA;AAAA;AAAA,KAGE,oBAAA;EACV,aAAA,GAAgB,MAAA;EAChB,WAAA;EACA,SAAA;EACA,aAAA,IAAiB,IAAA;EACjB,SAAA,IAAa,MAAA,EAAQ,aAAA;EACrB,aAAA;EACA,mBAAA;EACA,4BAAA,IAAgC,IAAA;EAChC,WAAA,IAAe,IAAA,UAAc,YAAA,EAAc,GAAA;AAAA;AAAA,cAahC,iBAAA,GACX,QAAA,sBACA,SAAA;AAAA,cAcW,qBAAA,GACX,IAAA,UACA,QAAA,UACA,OAAA,GAAS,oBAAA;EACN,IAAA;EAAc,GAAA;EAAe,SAAA;AAAA;AAAA,KA2V7B,KAAA;EACH,WAAA,GAAc,IAAA,UAAc,YAAA,EAAc,GAAA;EAC1C,aAAA,GAAgB,IAAA;EAChB,4BAAA,GAA+B,IAAA;EAC/B,mBAAA;EACA,gBAAA;AAAA;AAAA,cAGW,iBAAA,GACX,QAAA,UACA,aAAA,UACA,WAAA,UACA,KAAA,EAAO,KAAA,EACP,IAAA,YACA,YAAA;EAEA,gBAAA,EAAkB,MAAA;EAClB,IAAA;EACA,GAAA;AAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intlayer/svelte-compiler",
3
- "version": "8.7.8-canary.0",
3
+ "version": "8.7.9",
4
4
  "private": false,
5
5
  "description": "Vite-compatible compiler plugin for Svelte with Intlayer, providing HMR support, file transformation, and optimized dictionary loading for Svelte applications.",
6
6
  "keywords": [
@@ -81,13 +81,13 @@
81
81
  },
82
82
  "dependencies": {
83
83
  "@babel/core": "7.29.0",
84
- "@intlayer/types": "8.7.8-canary.0",
84
+ "@intlayer/types": "8.7.9",
85
85
  "fast-glob": "3.3.3",
86
86
  "magic-string": "0.30.21"
87
87
  },
88
88
  "devDependencies": {
89
- "@intlayer/config": "8.7.8-canary.0",
90
- "@intlayer/types": "8.7.8-canary.0",
89
+ "@intlayer/config": "8.7.9",
90
+ "@intlayer/types": "8.7.9",
91
91
  "@types/babel__core": "7.20.5",
92
92
  "@types/babel__generator": "7.27.0",
93
93
  "@types/babel__traverse": "7.28.0",