@ai-translate/cli 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.
- package/LICENSE +21 -0
- package/README.md +199 -0
- package/dist/bin.d.mts +1 -0
- package/dist/bin.mjs +9 -0
- package/dist/bin.mjs.map +1 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/src-Cnnq284f.mjs +947 -0
- package/dist/src-Cnnq284f.mjs.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src-Cnnq284f.mjs","names":["fs","parseDotenv","fs","fs"],"sources":["../src/config.ts","../src/init.ts","../src/transaction.ts","../src/index.ts"],"sourcesContent":["import { existsSync, promises as fs } from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { config as loadDotenv, parse as parseDotenv } from \"dotenv\";\nimport { createJiti } from \"jiti\";\n\nimport { defineConfig } from \"@ai-translate/core\";\nimport type { AiTranslateConfig } from \"@ai-translate/core/types\";\n\nconst CONFIG_CANDIDATES = [\n \"ai-translate.config.ts\",\n \"ai-translate.config.mts\",\n \"ai-translate.config.js\",\n \"ai-translate.config.mjs\",\n] as const;\n\nfunction isAiTranslateConfig(value: unknown): value is AiTranslateConfig {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"catalogs\" in value &&\n \"provider\" in value &&\n \"sourceLocale\" in value &&\n \"state\" in value &&\n \"targetLocales\" in value\n );\n}\n\nexport function findConfigPath(cwd: string, explicitPath?: string): string {\n if (explicitPath) {\n return path.resolve(cwd, explicitPath);\n }\n\n for (const candidate of CONFIG_CANDIDATES) {\n const fullPath = path.join(cwd, candidate);\n if (existsSync(fullPath)) {\n return fullPath;\n }\n }\n\n throw new Error(\n `Unable to find ai-translate config in ${cwd}. Expected one of: ${CONFIG_CANDIDATES.join(\", \")}`,\n );\n}\n\nexport async function loadEnvFiles(cwd: string): Promise<Record<string, string>> {\n const nodeEnv = process.env.NODE_ENV;\n const candidates = [\n \".env\",\n \".env.local\",\n nodeEnv ? `.env.${nodeEnv}` : undefined,\n nodeEnv ? `.env.${nodeEnv}.local` : undefined,\n ].filter((value): value is string => value !== undefined);\n\n const merged: Record<string, string> = {};\n for (const fileName of candidates) {\n const filePath = path.join(cwd, fileName);\n try {\n const raw = await fs.readFile(filePath, \"utf8\");\n Object.assign(merged, parseDotenv(raw));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n }\n\n loadDotenv({\n override: false,\n path: candidates.map((candidate) => path.join(cwd, candidate)),\n processEnv: process.env,\n });\n\n return merged;\n}\n\nexport async function loadConfig(\n cwd: string,\n explicitPath?: string,\n): Promise<{ config: AiTranslateConfig; configPath: string }> {\n const configPath = findConfigPath(cwd, explicitPath);\n const jiti = createJiti(import.meta.url, {\n interopDefault: true,\n moduleCache: false,\n });\n const loaded: unknown = await jiti.import(configPath);\n const resolved =\n typeof loaded === \"object\" && loaded !== null && \"default\" in loaded\n ? loaded.default ?? loaded\n : loaded;\n\n if (!isAiTranslateConfig(resolved)) {\n throw new Error(`Config file ${configPath} did not export an ai-translate config object.`);\n }\n\n return {\n config: defineConfig(resolved),\n configPath,\n };\n}\n","import { promises as fs } from \"node:fs\";\nimport * as path from \"node:path\";\n\nimport { detectProject, renderConfig } from \"@ai-translate/next\";\nimport type { DetectedSetup, Integration, ProviderChoice } from \"@ai-translate/next\";\n\nconst CONFIG_FILENAME = \"ai-translate.config.ts\";\nconst DEFAULT_AI_SDK_PACKAGE = \"@ai-sdk/openai\";\n\n/** Packages a generated config imports from, whichever provider it wires up. */\nconst REQUIRED_PACKAGES = [\"@ai-translate/cli\", \"@ai-translate/fs-json\"];\n\nexport interface InitOptions {\n /** Overwrites an existing config instead of refusing. */\n force?: boolean;\n /** Selects an integration when detection finds more than one. */\n integration?: string;\n /** Replaces the shipped integrations. A project that localizes something the\n * toolkit does not recognise can register its own detector rather than\n * writing the config by hand. */\n integrations?: readonly Integration[];\n /** Model id written into the generated config. */\n model?: string;\n /** Prints the config that would be written and touches nothing. */\n preview?: boolean;\n /** `openai` talks to OpenAI directly; `ai-sdk` routes through the AI SDK. */\n provider?: ProviderChoice;\n /** AI SDK vendor package, for example `@ai-sdk/anthropic`. */\n providerPackage?: string;\n}\n\nexport interface InitResult {\n configPath: string | null;\n lines: readonly string[];\n setup: DetectedSetup;\n}\n\nfunction describe(setup: DetectedSetup): string[] {\n return [\n `Detected ${setup.displayName}:`,\n ...setup.evidence.map((item) => ` - ${item.detail} (${item.source})`),\n ` - Source locale ${setup.plan.sourceLocale}, ${String(\n setup.plan.targetLocales.length,\n )} target locale(s): ${setup.plan.targetLocales.join(\", \")}`,\n ];\n}\n\nasync function missingPackages(\n cwd: string,\n plan: DetectedSetup[\"plan\"],\n options: InitOptions,\n): Promise<string[]> {\n const expected = [\n ...REQUIRED_PACKAGES,\n ...(plan.messageFormat === \"plain\" ? [] : [\"@ai-translate/message-formats\"]),\n ...(options.provider === \"ai-sdk\"\n ? [\"@ai-translate/provider-ai-sdk\", \"ai\", options.providerPackage ?? DEFAULT_AI_SDK_PACKAGE]\n : [\"@ai-translate/provider-openai\"]),\n ];\n\n try {\n const raw = await fs.readFile(path.join(cwd, \"package.json\"), \"utf8\");\n const manifest = JSON.parse(raw) as Record<string, Record<string, string> | undefined>;\n const declared = new Set([\n ...Object.keys(manifest.dependencies ?? {}),\n ...Object.keys(manifest.devDependencies ?? {}),\n ]);\n return expected.filter((name) => !declared.has(name));\n } catch {\n return expected;\n }\n}\n\nfunction chooseSetup(\n setups: readonly DetectedSetup[],\n requested: string | undefined,\n): DetectedSetup {\n if (requested !== undefined) {\n const match = setups.find((setup) => setup.integrationId === requested);\n if (match === undefined) {\n throw new Error(\n `No ${requested} setup was detected. Detected: ${\n setups.map((setup) => setup.integrationId).join(\", \") || \"none\"\n }.`,\n );\n }\n return match;\n }\n\n const [best, ...rest] = setups;\n if (best === undefined) {\n throw new Error(\n \"No supported Next.js localization setup was found. ai-translate init currently \" +\n \"recognises next-intl and i18next. Write ai-translate.config.ts by hand, or run \" +\n \"init from the directory holding package.json and your locale files.\",\n );\n }\n if (rest.length > 0 && rest[0]?.confidence === best.confidence) {\n // Two equally plausible setups is a genuine ambiguity, not something to\n // resolve by coin flip: writing the wrong one silently would point the\n // whole pipeline at the wrong catalog.\n throw new Error(\n `Found more than one localization setup (${setups\n .map((setup) => setup.integrationId)\n .join(\", \")}). Re-run with --integration <id> to choose.`,\n );\n }\n return best;\n}\n\n/**\n * Detects the project's localization setup and writes a config for it.\n *\n * Nothing else is touched. Installing packages, wiring scripts, and editing the\n * Next.js config stay in the user's hands, so `init` on an unfamiliar repository\n * produces exactly one new file and a list of instructions.\n */\nexport async function runInit(cwd: string, options: InitOptions = {}): Promise<InitResult> {\n const setups = await detectProject(\n cwd,\n options.integrations === undefined ? {} : { integrations: options.integrations },\n );\n const setup = chooseSetup(setups, options.integration);\n const contents = renderConfig(setup.plan, {\n ...(options.model === undefined ? {} : { model: options.model }),\n ...(options.provider === undefined ? {} : { provider: options.provider }),\n ...(options.providerPackage === undefined ? {} : { providerPackage: options.providerPackage }),\n });\n const configPath = path.join(cwd, CONFIG_FILENAME);\n const lines = describe(setup);\n\n for (const warning of setup.plan.warnings) {\n lines.push(` ! ${warning}`);\n }\n\n const others = setups.filter((candidate) => candidate !== setup);\n if (others.length > 0) {\n lines.push(\n `Also detected, not used: ${others.map((candidate) => candidate.displayName).join(\", \")}.`,\n );\n }\n\n if (options.preview === true) {\n lines.push(\"\", `Would write ${CONFIG_FILENAME}:`, \"\", contents);\n return { configPath: null, lines, setup };\n }\n\n const exists = await fs\n .access(configPath)\n .then(() => true)\n .catch(() => false);\n if (exists && options.force !== true) {\n throw new Error(`${CONFIG_FILENAME} already exists. Pass --force to overwrite it.`);\n }\n\n await fs.writeFile(configPath, contents, \"utf8\");\n lines.push(\"\", `Wrote ${CONFIG_FILENAME}.`, \"\", \"Next steps:\");\n\n const install = await missingPackages(cwd, setup.plan, options);\n let step = 1;\n if (install.length > 0) {\n lines.push(` ${String(step++)}. Install: ${install.join(\" \")}`);\n }\n const apiKeyVariable =\n options.provider === \"ai-sdk\"\n ? `the API key your ${options.providerPackage ?? DEFAULT_AI_SDK_PACKAGE} provider reads`\n : \"OPENAI_API_KEY\";\n lines.push(\n ` ${String(step++)}. Set ${apiKeyVariable}, in your shell or in .env.local.`,\n ` ${String(step++)}. Review the model and locale list in ${CONFIG_FILENAME}.`,\n ` ${String(step++)}. Run \"ai-translate validate\" to confirm the config loads.`,\n ` ${String(step++)}. Run \"ai-translate check\" to see what a sync would do.`,\n ` ${String(step)}. Run \"ai-translate sync\" to translate.`,\n );\n\n return { configPath, lines, setup };\n}\n","import { randomUUID } from \"node:crypto\";\nimport { promises as fs } from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\n\nimport type {\n AiTranslateConfig,\n CatalogAdapter,\n DocumentRef,\n Entry,\n LoadedDocument,\n ScaffoldLocaleOptions,\n ScaffoldLocaleResult,\n SyncStateLoadScope,\n SyncStateSnapshot,\n SyncStateStore,\n} from \"@ai-translate/core/types\";\nimport { supportsScopedSave } from \"@ai-translate/core/types\";\nimport type {\n DurableDocumentChange,\n} from \"@ai-translate/fs-json\";\n\nconst DURABLE_TRANSACTION_STATE_STORE = Symbol.for(\n \"@ai-translate/fs-json/durable-transaction-state-store\",\n);\n\nfunction cloneState(state: SyncStateSnapshot): SyncStateSnapshot {\n return structuredClone(state);\n}\n\nfunction cloneEntry(entry: Entry): Entry {\n return {\n ...entry,\n address: entry.address.map((segment) => ({ ...segment })),\n ...(entry.meta === undefined ? {} : { meta: { ...entry.meta } }),\n ...(entry.tokens === undefined ? {} : { tokens: entry.tokens.map((token) => ({ ...token })) }),\n };\n}\n\n/** Adapter state may contain parser-owned class instances, so retain it while\n * isolating the mutable translation entries. Staged writes are subsequently\n * serialized and reloaded by the real adapter to obtain isolated live state. */\nfunction cloneDocument(document: LoadedDocument): LoadedDocument {\n return {\n entries: document.entries.map(cloneEntry),\n ...(document.reconciliation === undefined\n ? {}\n : {\n reconciliation: {\n ...(document.reconciliation.previousPointers === undefined\n ? {}\n : { previousPointers: { ...document.reconciliation.previousPointers } }),\n ...(document.reconciliation.retiredStateKeys === undefined\n ? {}\n : { retiredStateKeys: [...document.reconciliation.retiredStateKeys] }),\n },\n }),\n ref: { ...document.ref },\n state: document.state,\n ...(document.structureDigest === undefined\n ? {}\n : { structureDigest: document.structureDigest }),\n };\n}\n\nfunction restoreDocumentRef(document: LoadedDocument, ref: DocumentRef): LoadedDocument {\n return cloneDocument({ ...document, ref: { ...ref } });\n}\n\nfunction documentKey(ref: DocumentRef): string {\n return [ref.catalogId, ref.format, ref.locale, ref.path, ref.unitId].join(\"\\u0000\");\n}\n\nclass StagedStateStore implements SyncStateStore {\n private dirty = false;\n private snapshot: SyncStateSnapshot;\n\n constructor(initial: SyncStateSnapshot) {\n this.snapshot = cloneState(initial);\n }\n\n hasChanges(): boolean {\n return this.dirty;\n }\n\n load(): Promise<SyncStateSnapshot> {\n return Promise.resolve(cloneState(this.snapshot));\n }\n\n save(state: SyncStateSnapshot): Promise<void> {\n this.snapshot = cloneState(state);\n this.dirty = true;\n return Promise.resolve();\n }\n\n stagedSnapshot(): SyncStateSnapshot {\n return cloneState(this.snapshot);\n }\n\n withLock<T>(operation: () => Promise<T>): Promise<T> {\n return operation();\n }\n}\n\ninterface StagedFile {\n mode: number | undefined;\n original: Buffer | null;\n realPath: string;\n tempPath: string;\n}\n\nasync function readOriginal(filePath: string): Promise<{\n mode: number | undefined;\n original: Buffer | null;\n}> {\n try {\n const [original, stats] = await Promise.all([fs.readFile(filePath), fs.stat(filePath)]);\n return { mode: stats.mode, original };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return { mode: undefined, original: null };\n }\n throw error;\n }\n}\n\nasync function writeFileAtomic(filePath: string, contents: Buffer, mode?: number): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n const temporaryPath = path.join(\n path.dirname(filePath),\n `.${path.basename(filePath)}.ai-translate-${randomUUID()}`,\n );\n try {\n await fs.writeFile(temporaryPath, contents);\n if (mode !== undefined) {\n await fs.chmod(temporaryPath, mode);\n }\n await fs.rename(temporaryPath, filePath);\n } finally {\n await fs.rm(temporaryPath, { force: true });\n }\n}\n\nclass StagedCatalogs {\n private readonly files = new Map<string, StagedFile>();\n private readonly pendingRefs = new Map<string, { catalog: CatalogAdapter; ref: DocumentRef }>();\n private tempRoot: string | undefined;\n\n constructor(\n private readonly catalogs: readonly CatalogAdapter[],\n private readonly sourceLocale: string,\n ) {}\n\n adapters(): readonly CatalogAdapter[] {\n return this.catalogs.map((catalog) => this.createAdapter(catalog));\n }\n\n async cleanup(): Promise<void> {\n if (this.tempRoot !== undefined) {\n await fs.rm(this.tempRoot, { force: true, recursive: true });\n }\n }\n\n async promote(): Promise<void> {\n for (const staged of this.files.values()) {\n await writeFileAtomic(staged.realPath, await fs.readFile(staged.tempPath), staged.mode);\n }\n }\n\n async durableChanges(): Promise<readonly DurableDocumentChange[]> {\n return Promise.all(\n [...this.files.values()].map(async (staged) => ({\n ...(staged.mode === undefined ? {} : { mode: staged.mode }),\n next: await fs.readFile(staged.tempPath),\n original: staged.original,\n path: staged.realPath,\n })),\n );\n }\n\n async rollback(): Promise<void> {\n const failures: unknown[] = [];\n for (const staged of this.files.values()) {\n try {\n if (staged.original === null) {\n await fs.rm(staged.realPath, { force: true });\n } else {\n await writeFileAtomic(staged.realPath, staged.original, staged.mode);\n }\n } catch (error) {\n failures.push(error);\n }\n }\n if (failures.length > 0) {\n throw new AggregateError(failures, \"Failed to restore localized documents after commit.\");\n }\n }\n\n private async stageFile(realPath: string): Promise<StagedFile> {\n const existing = this.files.get(realPath);\n if (existing) {\n return existing;\n }\n this.tempRoot ??= await fs.mkdtemp(path.join(os.tmpdir(), \"ai-translate-stage-\"));\n const { mode, original } = await readOriginal(realPath);\n const tempPath = path.join(\n this.tempRoot,\n `${String(this.files.size)}${path.extname(realPath) || \".document\"}`,\n );\n if (original !== null) {\n await fs.writeFile(tempPath, original);\n }\n const staged = { mode, original, realPath, tempPath };\n this.files.set(realPath, staged);\n return staged;\n }\n\n private async loadStaged(\n catalog: CatalogAdapter,\n ref: DocumentRef,\n ): Promise<LoadedDocument | null> {\n const staged = this.files.get(ref.path);\n if (!staged) {\n const document = await catalog.loadDocument(ref);\n return document === null ? null : cloneDocument(document);\n }\n const tempRef = { ...ref, path: staged.tempPath };\n const document = await catalog.loadDocument(tempRef);\n return document === null ? null : restoreDocumentRef(document, ref);\n }\n\n private async writeStaged(catalog: CatalogAdapter, document: LoadedDocument): Promise<void> {\n const staged = await this.stageFile(document.ref.path);\n const tempRef = { ...document.ref, path: staged.tempPath };\n const stagedDocument = await catalog.loadDocument(tempRef);\n await catalog.writeDocument({\n ...cloneDocument(document),\n ref: tempRef,\n // The reconciled document is authoritative: it carries the source shape,\n // so keys dropped from the source do not survive in the target. Formats\n // that pack several logical documents into one file merge that shape\n // into the staged file themselves so sibling writes are not lost.\n state:\n stagedDocument === null || catalog.mergeStagedState === undefined\n ? document.state\n : catalog.mergeStagedState({ document, staged: stagedDocument }),\n });\n const persisted = await catalog.loadDocument(tempRef);\n if (persisted === null) {\n throw new Error(\n `Catalog \"${catalog.id}\" did not persist staged document ${document.ref.path}.`,\n );\n }\n this.pendingRefs.set(documentKey(document.ref), { catalog, ref: { ...document.ref } });\n\n // A bundle catalog can expose several logical documents backed by one file.\n // Re-read every staged ref for the path so later repair rounds see the\n // aggregate serialized state, not a pre-write per-unit snapshot.\n for (const pending of this.pendingRefs.values()) {\n if (pending.ref.path === document.ref.path) {\n const pendingTempRef = { ...pending.ref, path: staged.tempPath };\n if ((await pending.catalog.loadDocument(pendingTempRef)) === null) {\n throw new Error(\n `Catalog \"${pending.catalog.id}\" could not reload staged document ${pending.ref.path}.`,\n );\n }\n }\n }\n }\n\n private createAdapter(catalog: CatalogAdapter): CatalogAdapter {\n const mergeStagedState = catalog.mergeStagedState?.bind(catalog);\n return {\n createDocumentRef: (sourceRef, locale) => catalog.createDocumentRef(sourceRef, locale),\n id: catalog.id,\n listDocumentRefs: (sourceLocale) => catalog.listDocumentRefs(sourceLocale),\n loadDocument: (ref) => this.loadStaged(catalog, ref),\n ...(mergeStagedState === undefined ? {} : { mergeStagedState }),\n reconcileDocument: async (args) => {\n const document = await catalog.reconcileDocument({\n ...(args.history === undefined\n ? {}\n : { history: args.history.map((entry) => structuredClone(entry)) }),\n ref: { ...args.ref },\n source: cloneDocument(args.source),\n target: args.target === null ? null : cloneDocument(args.target),\n });\n return cloneDocument(document);\n },\n ...(catalog.scaffoldLocale === undefined\n ? {}\n : {\n scaffoldLocale: (options: ScaffoldLocaleOptions) =>\n this.scaffoldCatalog(catalog, options),\n }),\n writeDocument: (document) => this.writeStaged(catalog, document),\n };\n }\n\n private async scaffoldCatalog(\n catalog: CatalogAdapter,\n options: ScaffoldLocaleOptions,\n ): Promise<ScaffoldLocaleResult> {\n const strategy = options.strategy ?? \"copy-source\";\n const fromLocale =\n strategy === \"copy-source\" ? this.sourceLocale : (options.fromLocale ?? this.sourceLocale);\n const refs = await catalog.listDocumentRefs(fromLocale);\n if (strategy === \"empty\") {\n return {\n catalogId: catalog.id,\n createdDocuments: 0,\n locale: options.locale,\n skippedDocuments: refs.length,\n strategy,\n };\n }\n\n let createdDocuments = 0;\n let skippedDocuments = 0;\n const adapter = this.createAdapter(catalog);\n for (const sourceRef of refs) {\n const targetRef = adapter.createDocumentRef(sourceRef, options.locale);\n if ((await adapter.loadDocument(targetRef)) !== null) {\n skippedDocuments += 1;\n continue;\n }\n const source = await adapter.loadDocument(sourceRef);\n if (source === null) {\n skippedDocuments += 1;\n continue;\n }\n await adapter.writeDocument(\n await adapter.reconcileDocument({ ref: targetRef, source, target: null }),\n );\n createdDocuments += 1;\n }\n\n return {\n catalogId: catalog.id,\n createdDocuments,\n locale: options.locale,\n skippedDocuments,\n strategy,\n };\n }\n}\n\nfunction commitFailure(commitError: unknown, rollbackErrors: readonly unknown[]): Error {\n return rollbackErrors.length === 0\n ? commitError instanceof Error\n ? commitError\n : new Error(String(commitError))\n : new AggregateError(\n [commitError, ...rollbackErrors],\n \"Translation commit failed and could not be completely rolled back.\",\n );\n}\n\ninterface DurableCommitCoordinator {\n commit(transaction: {\n documents: readonly DurableDocumentChange[];\n initialState: SyncStateSnapshot;\n nextState: SyncStateSnapshot;\n }): Promise<void>;\n}\n\nfunction durableStateStore(state: SyncStateStore): DurableCommitCoordinator | null {\n if (typeof state === \"object\" && state !== null) {\n const candidate = (state as unknown as Record<PropertyKey, unknown>)[\n DURABLE_TRANSACTION_STATE_STORE\n ];\n if (\n typeof candidate === \"object\" &&\n candidate !== null &&\n \"commit\" in candidate &&\n typeof candidate.commit === \"function\"\n ) {\n return candidate as DurableCommitCoordinator;\n }\n }\n return null;\n}\n\nexport async function runStagedCatalogTransaction<T>(\n config: AiTranslateConfig,\n operation: (stagedConfig: AiTranslateConfig) => Promise<T>,\n shouldCommit: (result: T) => boolean = () => true,\n scope?: SyncStateLoadScope,\n): Promise<T> {\n /*\n * Staging copies the snapshot several times between here and the commit, so\n * loading locales the run cannot touch is the dominant cost of a narrow sync.\n * The scope is only honoured by stores that merge on save; everywhere else the\n * snapshot still has to describe the whole corpus, because omission means\n * deletion.\n */\n const saveScope = supportsScopedSave(config.state) ? scope : undefined;\n\n return config.state.withLock(async () => {\n const initialState = await config.state.load(saveScope);\n const stagedState = new StagedStateStore(initialState);\n const stagedCatalogs = new StagedCatalogs(config.catalogs, config.sourceLocale);\n const stagedConfig: AiTranslateConfig = {\n ...config,\n catalogs: stagedCatalogs.adapters(),\n state: stagedState,\n };\n try {\n const result = await operation(stagedConfig);\n if (!shouldCommit(result)) {\n return result;\n }\n\n const durableStore = durableStateStore(config.state);\n if (durableStore !== null) {\n const documents = await stagedCatalogs.durableChanges();\n if (documents.length > 0 || stagedState.hasChanges()) {\n await durableStore.commit({\n documents,\n initialState: cloneState(initialState),\n nextState: stagedState.stagedSnapshot(),\n ...(saveScope === undefined ? {} : { scope: saveScope }),\n });\n }\n } else {\n let stateSaveAttempted = false;\n try {\n await stagedCatalogs.promote();\n if (stagedState.hasChanges()) {\n stateSaveAttempted = true;\n await config.state.save(stagedState.stagedSnapshot(), saveScope);\n }\n } catch (error) {\n const rollbackErrors: unknown[] = [];\n try {\n await stagedCatalogs.rollback();\n } catch (rollbackError) {\n rollbackErrors.push(rollbackError);\n }\n if (stateSaveAttempted) {\n try {\n await config.state.save(cloneState(initialState), saveScope);\n } catch (rollbackError) {\n rollbackErrors.push(rollbackError);\n }\n }\n throw commitFailure(error, rollbackErrors);\n }\n }\n return result;\n } finally {\n await stagedCatalogs.cleanup();\n }\n });\n}\n","import {\n auditCatalogs,\n resolveStateScope,\n syncCatalogs,\n usesGeneratorSelfCheck,\n validateCatalogs,\n withTranslationIssueCache,\n} from \"@ai-translate/core\";\nimport type {\n AiTranslateConfig,\n CatalogScaffoldStrategy,\n SemanticAuditResult,\n SyncCatalogsOptions,\n SyncResult,\n SyncStateSnapshot,\n ValidationResult,\n} from \"@ai-translate/core/types\";\nimport { adoptExistingTranslations } from \"@ai-translate/fs-json\";\nimport type { IdenticalToSourcePolicy } from \"@ai-translate/fs-json\";\nimport type { ProviderChoice } from \"@ai-translate/next\";\n\nimport { loadConfig, loadEnvFiles } from \"./config\";\nimport { runInit } from \"./init\";\nimport { runStagedCatalogTransaction } from \"./transaction\";\n\nexport { defineConfig } from \"@ai-translate/core\";\nexport { findConfigPath, loadConfig, loadEnvFiles } from \"./config\";\n\ninterface CommandOptions {\n auditCheck?: boolean;\n catalogIds?: string[];\n config?: string;\n dryRun?: boolean;\n force?: boolean;\n forceRetranslate?: boolean;\n forceRetranslatePaths?: string[];\n includePaths?: string[];\n from?: string;\n identicalToSource?: IdenticalToSourcePolicy;\n locales?: string[];\n integration?: string;\n maxPendingTranslations?: number;\n model?: string;\n preview?: boolean;\n provider?: string;\n providerPackage?: string;\n refresh?: boolean;\n strategy?: CatalogScaffoldStrategy;\n unitIds?: string[];\n}\n\ninterface ParsedCommand {\n command?: string;\n options: CommandOptions;\n positionals: string[];\n}\n\nfunction requireOptionValue(optionName: string, value: string | undefined): string {\n if (value === undefined) {\n throw new Error(`Option \"--${optionName}\" requires a value.`);\n }\n\n return value;\n}\n\nfunction requireProviderChoice(value: string): ProviderChoice {\n if (value !== \"ai-sdk\" && value !== \"openai\") {\n throw new Error(`Option \"--provider\" accepts \"openai\" or \"ai-sdk\", not \"${value}\".`);\n }\n\n return value;\n}\n\nfunction requireIdenticalToSourcePolicy(value: string): IdenticalToSourcePolicy {\n if (value !== \"adopt\" && value !== \"skip\") {\n throw new Error(\n `Option \"--identical-to-source\" accepts \"adopt\" or \"skip\", not \"${value}\".`,\n );\n }\n\n return value;\n}\n\nfunction requireNonNegativeIntegerOption(optionName: string, value: string | undefined): number {\n const rawValue = requireOptionValue(optionName, value);\n const parsedValue = Number(rawValue);\n if (!Number.isSafeInteger(parsedValue) || parsedValue < 0) {\n throw new Error(`Option \"--${optionName}\" requires a non-negative integer.`);\n }\n return parsedValue;\n}\n\nasync function validateConfig(\n config: AiTranslateConfig,\n configPath: string,\n options: SyncCatalogsOptions,\n): Promise<ValidationResult> {\n const result = await validateCatalogs(config, options);\n return {\n ...result,\n configPath,\n };\n}\n\nconst DEFAULT_SEMANTIC_REPAIR_ROUNDS = 0;\n\ninterface SemanticAuditConvergenceResult {\n audit: SemanticAuditResult | undefined;\n repairRounds: number;\n sync: SyncResult;\n}\n\nfunction printSyncSummary(\n result: SyncResult,\n semanticAudit?: SemanticAuditResult,\n semanticRepairRounds = 0,\n): void {\n const pendingTranslationReasons = summarizePendingTranslationReasons(result);\n const failedTranslationIssues = summarizeFailedTranslationIssues(result);\n console.log(\n JSON.stringify(\n {\n dryRun: result.dryRun,\n metrics: result.metrics,\n ...(result.dryRun && Object.keys(pendingTranslationReasons).length > 0\n ? { pendingTranslationReasons }\n : {}),\n ...(semanticAudit === undefined ? {} : { semanticAudit, semanticRepairRounds }),\n ...(failedTranslationIssues === undefined ? {} : { failedTranslationIssues }),\n },\n null,\n 2,\n ),\n );\n}\n\nfunction summarizeFailedTranslationIssues(result: SyncResult):\n | {\n counts: Record<string, number>;\n examples: readonly {\n catalogId: string;\n code: string;\n locale: string;\n message: string;\n path: string;\n unitId: string;\n }[];\n }\n | undefined {\n if (result.metrics.failedEntries === 0) {\n return undefined;\n }\n const errors = result.documents.flatMap((document) =>\n document.issues\n .filter((issue) => issue.severity === \"error\")\n .map((issue) => ({\n catalogId: document.catalogId,\n code: issue.code,\n locale: document.locale,\n message: issue.message,\n path: document.path,\n unitId: document.unitId,\n })),\n );\n const counts: Record<string, number> = {};\n for (const issue of errors) {\n counts[issue.code] = (counts[issue.code] ?? 0) + 1;\n }\n return {\n counts: Object.fromEntries(\n Object.entries(counts).toSorted(\n ([leftCode, leftCount], [rightCode, rightCount]) =>\n rightCount - leftCount || leftCode.localeCompare(rightCode),\n ),\n ),\n examples: errors.slice(0, 25),\n };\n}\n\nfunction summarizePendingTranslationReasons(result: SyncResult): Record<string, number> {\n const summary: Record<string, number> = {};\n for (const document of result.documents) {\n for (const [reason, count] of Object.entries(document.pendingTranslationReasons ?? {})) {\n summary[reason] = (summary[reason] ?? 0) + count;\n }\n }\n return Object.fromEntries(\n Object.entries(summary).toSorted(\n ([leftReason, leftCount], [rightReason, rightCount]) =>\n rightCount - leftCount || leftReason.localeCompare(rightReason),\n ),\n );\n}\n\nfunction dryRunBudgetError(config: AiTranslateConfig, result: SyncResult): string | undefined {\n if (!result.dryRun || config.validation?.dryRunBudget === undefined) {\n return undefined;\n }\n const budget = config.validation.dryRunBudget;\n if (\n budget.maxPendingTranslations !== undefined &&\n result.metrics.translatedEntries > budget.maxPendingTranslations\n ) {\n return (\n `Translation dry-run planned ${String(\n result.metrics.translatedEntries,\n )} provider translations, ` +\n `exceeding the configured budget of ${String(budget.maxPendingTranslations)}.`\n );\n }\n const reasons = summarizePendingTranslationReasons(result);\n const forbidden = (budget.forbiddenPendingTranslationReasons ?? []).filter(\n (reason) => (reasons[reason] ?? 0) > 0,\n );\n return forbidden.length === 0\n ? undefined\n : `Translation dry-run included forbidden selection reasons: ${forbidden\n .map((reason) => `${reason} (${String(reasons[reason] ?? 0)})`)\n .join(\", \")}.`;\n}\n\nfunction assertDryRunBudget(config: AiTranslateConfig, result: SyncResult): void {\n const error = dryRunBudgetError(config, result);\n if (error !== undefined) {\n throw new Error(error);\n }\n}\n\nasync function convergeSemanticAudits(\n config: AiTranslateConfig,\n options: SyncCatalogsOptions,\n): Promise<SemanticAuditConvergenceResult> {\n let sync = await syncCatalogs(config, options);\n if (\n options.dryRun === true ||\n sync.metrics.failedEntries > 0 ||\n (config.semanticAudits?.length ?? 0) === 0 ||\n usesGeneratorSelfCheck(config)\n ) {\n return { audit: undefined, repairRounds: 0, sync };\n }\n\n let audit = await auditCatalogs(config, options);\n let repairRounds = 0;\n const maxSemanticRepairRounds =\n config.validation?.semanticRepairAttempts ?? DEFAULT_SEMANTIC_REPAIR_ROUNDS;\n const repairOptions = { ...options };\n delete repairOptions.forceRetranslate;\n delete repairOptions.forceRetranslatePaths;\n while (audit.retranslate > 0 && repairRounds < maxSemanticRepairRounds) {\n repairRounds += 1;\n sync = await syncCatalogs(config, repairOptions);\n if (sync.metrics.failedEntries > 0) {\n break;\n }\n audit = await auditCatalogs(config, options);\n }\n\n return { audit, repairRounds, sync };\n}\n\nasync function syncWithSemanticAuditConvergence(\n config: AiTranslateConfig,\n options: SyncCatalogsOptions,\n): Promise<SemanticAuditConvergenceResult> {\n if (options.dryRun === true) {\n return convergeSemanticAudits(config, options);\n }\n return runStagedCatalogTransaction(\n config,\n (stagedConfig) => convergeSemanticAudits(stagedConfig, options),\n (result) => semanticAuditConvergenceError(result) === undefined,\n resolveStateScope(config, options),\n );\n}\n\nfunction semanticAuditConvergenceError(result: SemanticAuditConvergenceResult): string | undefined {\n if (result.sync.metrics.failedEntries > 0) {\n return \"Sync completed with failed translation entries.\";\n }\n if ((result.audit?.unresolved ?? 0) > 0) {\n return \"Sync completed with unresolved semantic audits. Review or refresh the audit findings.\";\n }\n if ((result.audit?.retranslate ?? 0) > 0) {\n return `Semantic audit rejected translations after ${String(\n result.repairRounds,\n )} configured repair round(s).`;\n }\n if (result.audit?.issues.some((issue) => issue.severity === \"error\")) {\n return \"Semantic audit completed with unresolved or unsafe translations.\";\n }\n return undefined;\n}\n\nfunction assertSemanticAuditConvergence(result: SemanticAuditConvergenceResult): void {\n const error = semanticAuditConvergenceError(result);\n if (error !== undefined) {\n throw new Error(error);\n }\n}\n\nfunction buildSyncOptions(options: CommandOptions): SyncCatalogsOptions {\n const syncOptions: SyncCatalogsOptions = {};\n if (options.catalogIds && options.catalogIds.length > 0) {\n syncOptions.catalogIds = options.catalogIds;\n }\n\n if (options.dryRun !== undefined) {\n syncOptions.dryRun = options.dryRun;\n }\n\n if (options.forceRetranslate !== undefined) {\n syncOptions.forceRetranslate = options.forceRetranslate;\n }\n\n if (options.forceRetranslatePaths && options.forceRetranslatePaths.length > 0) {\n syncOptions.forceRetranslate = true;\n syncOptions.forceRetranslatePaths = options.forceRetranslatePaths;\n }\n\n if (options.includePaths && options.includePaths.length > 0) {\n syncOptions.includePaths = options.includePaths;\n }\n\n if (options.locales && options.locales.length > 0) {\n syncOptions.locales = options.locales;\n }\n\n if (options.maxPendingTranslations !== undefined) {\n syncOptions.maxPendingTranslations = options.maxPendingTranslations;\n }\n\n if (options.unitIds && options.unitIds.length > 0) {\n syncOptions.unitIds = options.unitIds;\n }\n\n return syncOptions;\n}\n\nfunction projectStateLocales(\n state: SyncStateSnapshot,\n locales: readonly string[] | undefined,\n): SyncStateSnapshot {\n if (locales === undefined || locales.length === 0) {\n return state;\n }\n const included = new Set(locales);\n return {\n entries: Object.fromEntries(\n Object.entries(state.entries).filter(([, entry]) => included.has(entry.locale)),\n ),\n version: state.version,\n };\n}\n\nfunction hasStoredSemanticAudits(state: SyncStateSnapshot): boolean {\n return Object.values(state.entries).some(\n (entry) => Object.keys(entry.validationAudits ?? {}).length > 0,\n );\n}\n\nconst EMPTY_SEMANTIC_AUDIT = {\n accepted: 0,\n audited: 0,\n cached: 0,\n checked: 0,\n issues: [],\n retranslate: 0,\n unresolved: 0,\n} as const;\n\nasync function scaffoldLocale(\n config: AiTranslateConfig,\n locale: string,\n options: {\n fromLocale?: string;\n strategy?: CatalogScaffoldStrategy;\n } = {},\n) {\n return Promise.all(\n config.catalogs.map(async (catalog) => {\n if (!catalog.scaffoldLocale) {\n return null;\n }\n\n return catalog.scaffoldLocale({\n ...(options.fromLocale === undefined ? {} : { fromLocale: options.fromLocale }),\n locale,\n ...(options.strategy === undefined ? {} : { strategy: options.strategy }),\n });\n }),\n );\n}\n\nfunction printHelp(): void {\n console.log(`ai-translate\n\nUsage:\n ai-translate init [--integration <next-intl|i18next>] [--provider <openai|ai-sdk>] [--provider-package <@ai-sdk/...>] [--model <id>] [--preview] [--force]\n ai-translate validate [--config <path>]\n ai-translate check [--config <path>] [--locale <locale>] [--catalog <id>] [--unit <id>] [--include-path <json-pointer>] [--max-pending-translations <count>]\n ai-translate audit [--check] [--refresh] [--config <path>] [--locale <locale>] [--catalog <id>] [--unit <id>] [--include-path <json-pointer>]\n ai-translate sync [--config <path>] [--dry-run] [--force-retranslate] [--force-retranslate-path <json-pointer>] [--include-path <json-pointer>] [--locale <locale>] [--catalog <id>] [--unit <id>] [--max-pending-translations <count>]\n ai-translate new-locale <locale> [--from <locale>] [--strategy <strategy>] [--config <path>]\n ai-translate scaffold-locale <locale> --from <locale> [--strategy <strategy>] [--config <path>]\n ai-translate adopt [--identical-to-source <adopt|skip>] [--dry-run] [--config <path>]\n ai-translate --help\n ai-translate --version`);\n}\n\nfunction parseCommand(argv: readonly string[]): ParsedCommand {\n const options: CommandOptions = {};\n const positionals: string[] = [];\n let command: string | undefined;\n\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (arg === undefined) {\n continue;\n }\n\n if (arg === \"--help\" || arg === \"-h\") {\n return {\n command: \"help\",\n options,\n positionals,\n };\n }\n\n if (arg === \"--version\" || arg === \"-v\") {\n return {\n command: \"version\",\n options,\n positionals,\n };\n }\n\n if (arg.startsWith(\"--\")) {\n const [flag = \"\", inlineValue] = arg.slice(2).split(\"=\", 2);\n if (flag.length === 0) {\n throw new Error(\"Encountered an empty option flag.\");\n }\n\n const nextValue = inlineValue ?? argv[index + 1];\n switch (flag) {\n case \"check\":\n options.auditCheck = true;\n break;\n case \"config\":\n options.config = requireOptionValue(flag, nextValue);\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n case \"catalog\":\n (options.catalogIds ??= []).push(requireOptionValue(flag, nextValue));\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n case \"dry-run\":\n options.dryRun = true;\n break;\n case \"force\":\n options.force = true;\n break;\n case \"force-retranslate\":\n options.forceRetranslate = true;\n break;\n case \"force-retranslate-path\":\n (options.forceRetranslatePaths ??= []).push(requireOptionValue(flag, nextValue));\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n case \"from\":\n options.from = requireOptionValue(flag, nextValue);\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n case \"include-path\":\n (options.includePaths ??= []).push(requireOptionValue(flag, nextValue));\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n case \"integration\":\n options.integration = requireOptionValue(flag, nextValue);\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n case \"locale\":\n (options.locales ??= []).push(requireOptionValue(flag, nextValue));\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n case \"model\":\n options.model = requireOptionValue(flag, nextValue);\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n case \"preview\":\n options.preview = true;\n break;\n case \"provider\":\n options.provider = requireOptionValue(flag, nextValue);\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n case \"provider-package\":\n options.providerPackage = requireOptionValue(flag, nextValue);\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n case \"max-pending-translations\":\n options.maxPendingTranslations = requireNonNegativeIntegerOption(flag, nextValue);\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n case \"identical-to-source\":\n options.identicalToSource = requireIdenticalToSourcePolicy(\n requireOptionValue(flag, nextValue),\n );\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n case \"refresh\":\n options.refresh = true;\n break;\n case \"strategy\": {\n const strategy = requireOptionValue(flag, nextValue) as CatalogScaffoldStrategy;\n options.strategy = strategy;\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n }\n case \"unit\":\n (options.unitIds ??= []).push(requireOptionValue(flag, nextValue));\n if (inlineValue === undefined) {\n index += 1;\n }\n break;\n default:\n throw new Error(`Unknown option \"--${flag}\".`);\n }\n\n continue;\n }\n\n if (!command) {\n command = arg;\n continue;\n }\n\n positionals.push(arg);\n }\n\n const parsedCommand: ParsedCommand = {\n options,\n positionals,\n };\n if (command !== undefined) {\n parsedCommand.command = command;\n }\n\n return parsedCommand;\n}\n\nexport async function runCli(\n argv: readonly string[] = process.argv.slice(2),\n cwd: string = process.cwd(),\n): Promise<number> {\n try {\n const parsed = parseCommand(argv);\n if (!parsed.command || parsed.command === \"help\") {\n printHelp();\n return 0;\n }\n\n if (parsed.command === \"version\") {\n console.log(\"0.0.0\");\n return 0;\n }\n\n switch (parsed.command) {\n case \"init\": {\n // No loadConfig and no loadEnvFiles: init runs before either exists.\n const result = await runInit(cwd, {\n force: parsed.options.force === true,\n ...(parsed.options.integration === undefined\n ? {}\n : { integration: parsed.options.integration }),\n ...(parsed.options.model === undefined ? {} : { model: parsed.options.model }),\n preview: parsed.options.preview === true || parsed.options.dryRun === true,\n ...(parsed.options.provider === undefined\n ? {}\n : { provider: requireProviderChoice(parsed.options.provider) }),\n ...(parsed.options.providerPackage === undefined\n ? {}\n : { providerPackage: parsed.options.providerPackage }),\n });\n console.log(result.lines.join(\"\\n\"));\n return 0;\n }\n case \"validate\": {\n await loadEnvFiles(cwd);\n const { config, configPath } = await loadConfig(cwd, parsed.options.config);\n const summary = await validateConfig(config, configPath, buildSyncOptions(parsed.options));\n console.log(JSON.stringify(summary, null, 2));\n if (summary.issues.some((issue) => issue.severity === \"error\")) {\n throw new Error(\"Validation failed.\");\n }\n return 0;\n }\n case \"check\": {\n await loadEnvFiles(cwd);\n const { config, configPath } = await loadConfig(cwd, parsed.options.config);\n const checkOptions: SyncCatalogsOptions = {\n ...buildSyncOptions(parsed.options),\n ...(process.env.AI_TRANSLATE_CHECK_SNAPSHOT_LOCK === \"1\"\n ? { assumeStateLock: true }\n : {}),\n };\n // Ask the store to materialise only the locales under check, then keep\n // the projection: a store is free to ignore the scope and return a\n // superset, and check must narrow regardless of which store is wired up.\n const stateSnapshot = projectStateLocales(\n await config.state.load(\n checkOptions.locales === undefined ? undefined : { locales: checkOptions.locales },\n ),\n checkOptions.locales,\n );\n const checkConfig: AiTranslateConfig = {\n ...config,\n state: {\n load: () => Promise.resolve(stateSnapshot),\n save: () =>\n Promise.reject(new Error(\"Translation check cannot persist translation state.\")),\n withLock: (operation) => config.state.withLock(operation),\n },\n };\n const needsSemanticAudit =\n (checkConfig.semanticAudits?.length ?? 0) > 0 || hasStoredSemanticAudits(stateSnapshot);\n const { auditResult, dryRunResult, validationResult } = await withTranslationIssueCache(\n async () => {\n const checkedValidation = await validateConfig(checkConfig, configPath, {\n ...checkOptions,\n acceptedProvenanceFastPath: true,\n });\n const checkedDryRun = await syncCatalogs(checkConfig, {\n ...checkOptions,\n dryRun: true,\n });\n const checkedAudit = needsSemanticAudit\n ? await auditCatalogs(checkConfig, {\n ...checkOptions,\n checkOnly: true,\n })\n : EMPTY_SEMANTIC_AUDIT;\n return {\n auditResult: checkedAudit,\n dryRunResult: checkedDryRun,\n validationResult: checkedValidation,\n };\n },\n );\n const hasValidationErrors = validationResult.issues.some(\n (issue) => issue.severity === \"error\",\n );\n const hasPendingSync =\n dryRunResult.metrics.changedDocuments > 0 ||\n dryRunResult.metrics.failedEntries > 0 ||\n dryRunResult.metrics.staleManualEntries > 0 ||\n dryRunResult.metrics.translatedEntries > 0;\n const hasAuditErrors = auditResult.issues.some((issue) => issue.severity === \"error\");\n\n console.log(\n JSON.stringify(\n {\n validation: validationResult,\n audit: auditResult,\n dryRun: dryRunResult.metrics,\n },\n null,\n 2,\n ),\n );\n if (hasValidationErrors || hasPendingSync || hasAuditErrors) {\n if (hasAuditErrors && !hasValidationErrors && !hasPendingSync) {\n throw new Error(\n \"Translation check failed because semantic audit provenance is missing, stale, or unresolved. Run ai-translate audit --refresh.\",\n );\n }\n throw new Error(\n \"Translation check failed. Run ai-translate sync to reconcile localized content.\",\n );\n }\n return 0;\n }\n case \"audit\": {\n await loadEnvFiles(cwd);\n const { config } = await loadConfig(cwd, parsed.options.config);\n const result = await auditCatalogs(config, {\n ...buildSyncOptions(parsed.options),\n checkOnly: parsed.options.auditCheck ?? false,\n refresh: parsed.options.refresh ?? false,\n });\n console.log(JSON.stringify(result, null, 2));\n if (result.issues.some((issue) => issue.severity === \"error\")) {\n throw new Error(\n parsed.options.auditCheck\n ? \"Semantic audit check failed. Run ai-translate audit --refresh.\"\n : \"Semantic audit completed with unresolved or unsafe translations.\",\n );\n }\n return 0;\n }\n case \"sync\": {\n await loadEnvFiles(cwd);\n const { config } = await loadConfig(cwd, parsed.options.config);\n /*\n * The cache key is the full validation input, so a changed translation\n * gets a fresh entry. Sync validates the same entry once to decide\n * whether existing output is still valid and again while resolving\n * acceptance provenance; `check` has always deduplicated that pair.\n */\n const result = await withTranslationIssueCache(() =>\n syncWithSemanticAuditConvergence(config, buildSyncOptions(parsed.options)),\n );\n printSyncSummary(result.sync, result.audit, result.repairRounds);\n assertDryRunBudget(config, result.sync);\n assertSemanticAuditConvergence(result);\n return 0;\n }\n case \"new-locale\": {\n const locale = parsed.positionals[0];\n if (!locale) {\n throw new Error('The \"new-locale\" command requires a <locale> argument.');\n }\n\n await loadEnvFiles(cwd);\n const { config } = await loadConfig(cwd, parsed.options.config);\n const fromLocale = parsed.options.from ?? config.sourceLocale;\n const strategy = parsed.options.strategy ?? \"copy-source\";\n\n if (parsed.options.dryRun && fromLocale !== config.sourceLocale) {\n throw new Error(\n 'The \"new-locale\" command only supports --from <sourceLocale> when used with --dry-run.',\n );\n }\n\n if (parsed.options.dryRun && strategy !== \"copy-source\") {\n throw new Error(\n 'The \"new-locale\" command only supports --strategy copy-source when used with --dry-run.',\n );\n }\n\n if (strategy !== \"copy-source\" && fromLocale === config.sourceLocale) {\n throw new Error(\n `The \"${strategy}\" strategy requires --from <locale> to be a translated locale.`,\n );\n }\n\n const syncOptions: SyncCatalogsOptions = {\n ...buildSyncOptions(parsed.options),\n forceRetranslate: strategy === \"copy-locale-and-retranslate\",\n locales: [locale],\n };\n const transaction = parsed.options.dryRun\n ? {\n result: await convergeSemanticAudits(config, syncOptions),\n scaffoldResults: [],\n }\n : await runStagedCatalogTransaction(\n config,\n async (stagedConfig) => {\n const scaffoldResults = await scaffoldLocale(stagedConfig, locale, {\n fromLocale,\n strategy,\n });\n const result = await convergeSemanticAudits(stagedConfig, syncOptions);\n return { result, scaffoldResults };\n },\n ({ result }) => semanticAuditConvergenceError(result) === undefined,\n );\n const { result, scaffoldResults } = transaction;\n console.log(\n JSON.stringify(\n {\n dryRun: result.sync.dryRun,\n fromLocale,\n locale,\n metrics: result.sync.metrics,\n scaffoldResults,\n ...(result.audit === undefined\n ? {}\n : {\n semanticAudit: result.audit,\n semanticRepairRounds: result.repairRounds,\n }),\n strategy,\n status: semanticAuditConvergenceError(result) === undefined ? \"ok\" : \"failed\",\n },\n null,\n 2,\n ),\n );\n assertSemanticAuditConvergence(result);\n return 0;\n }\n case \"scaffold-locale\": {\n const locale = parsed.positionals[0];\n if (!locale) {\n throw new Error('The \"scaffold-locale\" command requires a <locale> argument.');\n }\n\n if (!parsed.options.from) {\n throw new Error('The \"scaffold-locale\" command requires --from <locale>.');\n }\n\n await loadEnvFiles(cwd);\n const { config } = await loadConfig(cwd, parsed.options.config);\n const scaffoldResults = await scaffoldLocale(config, locale, {\n fromLocale: parsed.options.from,\n strategy: parsed.options.strategy ?? \"copy-locale\",\n });\n console.log(\n JSON.stringify(\n {\n fromLocale: parsed.options.from,\n locale,\n scaffoldResults,\n strategy: parsed.options.strategy ?? \"copy-locale\",\n status: \"ok\",\n },\n null,\n 2,\n ),\n );\n return 0;\n }\n case \"adopt\": {\n await loadEnvFiles(cwd);\n const { config } = await loadConfig(cwd, parsed.options.config);\n const result = await adoptExistingTranslations({\n catalogs: config.catalogs,\n identicalToSource: parsed.options.identicalToSource ?? \"adopt\",\n sourceLocale: config.sourceLocale,\n targetLocales: config.targetLocales,\n });\n\n if (!parsed.options.dryRun) {\n await config.state.save(result.state);\n }\n\n console.log(\n JSON.stringify(\n {\n adopted: result.adopted,\n dryRun: parsed.options.dryRun === true,\n identicalToSource: result.identicalToSource,\n status: \"ok\",\n untranslated: result.untranslated,\n },\n null,\n 2,\n ),\n );\n return 0;\n }\n default:\n throw new Error(`Unknown command \"${parsed.command}\".`);\n }\n } catch (error) {\n console.error(\n error instanceof Error ? error.message : `Unexpected CLI failure: ${String(error)}`,\n );\n return 1;\n }\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ai-translate/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Command-line interface for ai-translate: validate, check, audit, and sync localized content generated from a single source locale.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"i18n",
|
|
7
|
+
"l10n",
|
|
8
|
+
"internationalization",
|
|
9
|
+
"localization",
|
|
10
|
+
"translation",
|
|
11
|
+
"cli",
|
|
12
|
+
"ai",
|
|
13
|
+
"llm"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "Thiago Peres",
|
|
17
|
+
"homepage": "https://github.com/thiagoperes/ai-translate/tree/main/packages/ai-translate-cli#readme",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/thiagoperes/ai-translate.git",
|
|
21
|
+
"directory": "packages/ai-translate-cli"
|
|
22
|
+
},
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/thiagoperes/ai-translate/issues"
|
|
25
|
+
},
|
|
26
|
+
"bin": {
|
|
27
|
+
"ai-translate": "./dist/bin.mjs"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist"
|
|
31
|
+
],
|
|
32
|
+
"type": "module",
|
|
33
|
+
"main": "./dist/index.mjs",
|
|
34
|
+
"types": "./dist/index.d.mts",
|
|
35
|
+
"exports": {
|
|
36
|
+
".": {
|
|
37
|
+
"types": "./dist/index.d.mts",
|
|
38
|
+
"import": "./dist/index.mjs",
|
|
39
|
+
"default": "./dist/index.mjs"
|
|
40
|
+
},
|
|
41
|
+
"./package.json": "./package.json"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"dotenv": "17.4.2",
|
|
48
|
+
"jiti": "2.7.0",
|
|
49
|
+
"@ai-translate/core": "0.1.0",
|
|
50
|
+
"@ai-translate/fs-json": "0.1.0",
|
|
51
|
+
"@ai-translate/next": "0.1.0"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=20.19.0"
|
|
55
|
+
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "tsdown",
|
|
58
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
59
|
+
"lint": "pnpm --dir ../.. exec oxlint -c .oxlintrc.json --type-aware --deny-warnings packages/ai-translate-cli/src packages/ai-translate-cli/test packages/ai-translate-cli/vitest.config.ts packages/ai-translate-cli/tsdown.config.ts",
|
|
60
|
+
"test": "vitest run --config vitest.config.ts",
|
|
61
|
+
"coverage": "vitest run --config vitest.config.ts --coverage",
|
|
62
|
+
"coverage:strict": "vitest run --config vitest.config.ts --coverage --coverage.include=src/config.ts --coverage.thresholds.lines=95 --coverage.thresholds.functions=95 --coverage.thresholds.branches=95 --coverage.thresholds.statements=95",
|
|
63
|
+
"test:pack": "publint . && attw --pack . --profile esm-only"
|
|
64
|
+
}
|
|
65
|
+
}
|