From 2f6501659e8590bc9f9b63ea41534e8826632eb3 Mon Sep 17 00:00:00 2001 From: Sahin Vardar Date: Tue, 29 Oct 2024 09:48:53 +0100 Subject: [PATCH] fix: working on ast instead of string for script tag (#24) --- src/extract-i18n-keys.ts | 21 ++++++++++++--------- src/i18n-preprocessor.ts | 13 +++++-------- src/string-utils.ts | 11 ----------- src/tests/string-utils.test.ts | 20 +------------------- 4 files changed, 18 insertions(+), 47 deletions(-) diff --git a/src/extract-i18n-keys.ts b/src/extract-i18n-keys.ts index eafc16f..b5e8d65 100644 --- a/src/extract-i18n-keys.ts +++ b/src/extract-i18n-keys.ts @@ -5,9 +5,10 @@ import _ from 'lodash'; import fs from 'node:fs/promises'; import path from 'node:path'; import { walk } from 'estree-walker'; -import { extractKeyPathFromFile, stripScriptTag } from './string-utils.js'; +import { extractKeyPathFromFile } from './string-utils.js'; import { scanDir } from './utils.js'; import { preprocess, PreprocessorGroup, parse } from 'svelte/compiler'; +import printAst from '@vardario/svelte-ast-printer'; function extractI18nKeys(root: any, callIdentifier: string): string[] { const result: string[] = []; @@ -49,15 +50,17 @@ export async function processSvelteFile( const preprocessExtract = (): PreprocessorGroup => { return { async markup({ content, filename }) { - const { code } = stripScriptTag(rawCode); - const ast = parse(code, { modern: true }); + const ast = parse(content, { modern: true }); keys.push(...extractI18nKeys(ast.fragment, callIdentifier)); - return { code: content }; - }, - async script({ content, filename }) { - const ast = acorn.parse(content, { ecmaVersion: 'latest', sourceType: 'module' }) as Node; - keys.push(...extractI18nKeys(ast, callIdentifier)); - return { code: content }; + if (ast.instance) { + keys.push(...extractI18nKeys(ast.instance.content, callIdentifier)); + } + + if (ast.module) { + keys.push(...extractI18nKeys(ast.module.content, callIdentifier)); + } + + return { code: printAst(ast) }; } }; }; diff --git a/src/i18n-preprocessor.ts b/src/i18n-preprocessor.ts index 1cdfd26..891e69c 100644 --- a/src/i18n-preprocessor.ts +++ b/src/i18n-preprocessor.ts @@ -1,9 +1,10 @@ -import printHtml, { PrinterIdentOptions } from '@vardario/svelte-ast-printer'; +import { PrinterIdentOptions } from '@vardario/svelte-ast-printer'; import { parse as scriptParse } from 'acorn'; import { CallExpression, Node } from 'estree'; import { walk } from 'estree-walker'; -import { addPrefixToI18nArgument, extractKeyPathFromFile, stripScriptTag } from './string-utils.js'; +import { extractKeyPathFromFile } from './string-utils.js'; import { AST, type PreprocessorGroup, parse as svelteParse } from 'svelte/compiler'; +import printAst from '@vardario/svelte-ast-printer'; export function create18nCallLabelAttribute(callIdentifier: string, i18nKey: string) { const expression = scriptParse(`${callIdentifier}("${i18nKey}")`, { ecmaVersion: 'latest' }); @@ -114,16 +115,12 @@ export const i18nProcessor = (options?: I18nProcessorOptions): PreprocessorGroup return { async markup({ content, filename }) { return preprocess(content, filename, async () => { - const { code, scriptTags } = stripScriptTag(content); - const root = svelteParse(code, { modern: true }); + const root = svelteParse(content, { modern: true }); const keyPath = extractKeyPathFromFile(filename!); adjustI18nKeys(root, keyPath, callIdentifier); - const processedScriptTags = scriptTags.map(tag => addPrefixToI18nArgument(tag, keyPath)); - const transformedCode = printHtml(root, options?.indent); - const result = `${processedScriptTags.join('\n')}${processedScriptTags.length ? '\n' : ''}${transformedCode}`; - return { code: result }; + return { code: printAst(root, options?.indent) }; }); } }; diff --git a/src/string-utils.ts b/src/string-utils.ts index 37180bd..802b3f5 100644 --- a/src/string-utils.ts +++ b/src/string-utils.ts @@ -1,16 +1,5 @@ import path from 'node:path'; -export function stripScriptTag(code: string) { - const scriptTagRegEx = /([\s\S]*?<\/script>)/gi; - const scriptTags: string[] = []; - - for (const match of code.matchAll(scriptTagRegEx)) { - scriptTags.push(match[0]); - } - - return { code: code.replace(scriptTagRegEx, ''), scriptTags }; -} - export function extractKeyPathFromFile(filename: string) { filename = filename.split('.').slice(0, -1).join('.'); const regEx = /(components|routes)/; diff --git a/src/tests/string-utils.test.ts b/src/tests/string-utils.test.ts index 5dc7b12..56e5171 100644 --- a/src/tests/string-utils.test.ts +++ b/src/tests/string-utils.test.ts @@ -1,6 +1,6 @@ import path from 'node:path'; import { describe, expect, test } from 'vitest'; -import { addPrefixToI18nArgument, extractKeyPathFromFile, stripScriptTag } from '../string-utils.js'; +import { addPrefixToI18nArgument, extractKeyPathFromFile } from '../string-utils.js'; import { __dirname } from '../utils.js'; describe('string-utils', () => { @@ -17,24 +17,6 @@ describe('string-utils', () => { ); }); - test('stripScriptTag', () => { - const result0 = stripScriptTag('
'); - const result1 = stripScriptTag('
'); - const result2 = stripScriptTag('
'); - - expect(result0.code).toBe('
'); - expect(result0.scriptTags).toStrictEqual(['']); - - expect(result1.code).toBe('
'); - expect(result1.scriptTags).toStrictEqual(['']); - - expect(result2.code).toBe('
'); - expect(result2.scriptTags).toStrictEqual([ - '', - '' - ]); - }); - test('addPrefixToI18nArgument', () => { expect(addPrefixToI18nArgument("const a = $i18n('key')", 'prefix')).toBe("const a = $i18n('prefix.key')"); expect(addPrefixToI18nArgument("const a = $i18n('key', { count: 1 })", 'prefix')).toBe(