diff --git a/docs/CLI.md b/docs/CLI.md index 13e8b68..5d8ca1b 100644 --- a/docs/CLI.md +++ b/docs/CLI.md @@ -11,3 +11,5 @@ $ svelte-i18n extract [options] [output-file] - `--overwrite` - overwrite the content of the `output` file instead of just appending missing properties. Default: `false`. - `-c, --config` - define the path of a `svelte.config.js` in case your svelte components need to be preprocessed. + +- `--unsave` - disable the import library check. This can be used if the library name for some reason is not exactly "svelte-i18n". Default: `false`. diff --git a/src/cli/extract.ts b/src/cli/extract.ts index 65625e9..7d29659 100644 --- a/src/cli/extract.ts +++ b/src/cli/extract.ts @@ -50,7 +50,10 @@ function isMessagesDefinitionCall(node: Node, methodName: string) { ); } -function getLibImportDeclarations(ast: Ast): ImportDeclaration[] { +function getLibImportDeclarations( + ast: Ast, + ignoreImport: boolean, +): ImportDeclaration[] { const bodyElements = [ ...(ast.instance?.content.body ?? []), ...(ast.module?.content.body ?? []), @@ -58,7 +61,8 @@ function getLibImportDeclarations(ast: Ast): ImportDeclaration[] { return bodyElements.filter( (node) => - node.type === 'ImportDeclaration' && node.source.value === LIB_NAME, + node.type === 'ImportDeclaration' && + (node.source.value === LIB_NAME || ignoreImport), ) as ImportDeclaration[]; } @@ -75,8 +79,8 @@ function getFormatSpecifiers(decl: ImportDeclaration) { ) as ImportSpecifier[]; } -export function collectFormatCalls(ast: Ast) { - const importDecls = getLibImportDeclarations(ast); +export function collectFormatCalls(ast: Ast, ignoreLib = false) { + const importDecls = getLibImportDeclarations(ast, ignoreLib); if (importDecls.length === 0) return []; @@ -112,9 +116,9 @@ export function collectFormatCalls(ast: Ast) { // replace: (node: import("estree").BaseNode) => void; // }, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => void; -export function collectMessageDefinitions(ast: Ast) { +export function collectMessageDefinitions(ast: Ast, ignoreImport = false) { const definitions: ObjectExpression[] = []; - const defineImportDecl = getLibImportDeclarations(ast).find( + const defineImportDecl = getLibImportDeclarations(ast, ignoreImport).find( getDefineMessagesSpecifier, ); @@ -155,10 +159,13 @@ export function collectMessageDefinitions(ast: Ast) { ); } -export function collectMessages(markup: string): Message[] { +export function collectMessages( + markup: string, + ignoreImport = false, +): Message[] { const ast = parse(markup); - const calls = collectFormatCalls(ast); - const definitions = collectMessageDefinitions(ast); + const calls = collectFormatCalls(ast, ignoreImport); + const definitions = collectMessageDefinitions(ast, ignoreImport); return [ ...definitions.map((definition) => getObjFromExpression(definition)), @@ -194,13 +201,15 @@ export function extractMessages( markup: string, { accumulator = {}, + ignoreImport = false, shallow = false, }: { accumulator?: Record; + ignoreImport?: boolean; shallow?: boolean; } = {}, ) { - collectMessages(markup).forEach((messageObj) => { + collectMessages(markup, ignoreImport).forEach((messageObj) => { let defaultValue = messageObj.default; if (typeof defaultValue === 'undefined') { diff --git a/src/cli/index.ts b/src/cli/index.ts index 2828df7..c09f820 100644 --- a/src/cli/index.ts +++ b/src/cli/index.ts @@ -51,11 +51,13 @@ program 'path to the "svelte.config.js" file', `${process.cwd()}/svelte.config.js`, ) - .action(async (globStr, output, { shallow, overwrite, config }) => { + .option('--unsave', 'disable the import-lib validation', false) + .action(async (globStr, output, { shallow, overwrite, config, unsave }) => { const filesToExtract = (await glob(globStr)).filter((file) => file.match(/\.html|svelte$/i), ); + const ignoreImport = unsave; const isConfigDir = await isDirectory(config); const resolvedConfigPath = resolve( config, @@ -98,7 +100,7 @@ program content = processed.code; } - extractMessages(content, { accumulator, shallow }); + extractMessages(content, { accumulator, shallow, ignoreImport }); } catch (e: unknown) { if ( isSvelteError(e, 'parse-error') && diff --git a/test/cli/extract.test.ts b/test/cli/extract.test.ts index a980092..4fbd401 100644 --- a/test/cli/extract.test.ts +++ b/test/cli/extract.test.ts @@ -26,6 +26,30 @@ describe('collecting format calls', () => { expect(calls).toHaveLength(0); }); + it('returns nothing if import from wrong lib', () => { + const ast = parse(``); + + const calls = collectFormatCalls(ast); + + expect(calls).toHaveLength(0); + }); + + it('returns all format calls if import from wrong lib and import-check is disabled', () => { + const ast = parse(``); + + const ignoreLib = true; + const calls = collectFormatCalls(ast, ignoreLib); + + expect(calls).toHaveLength(1); + expect(calls[0]).toMatchObject({ type: 'CallExpression' }); + }); + it('returns nothing if there are no format imports', () => { const ast = parse( `