@intlayer/cli 8.3.0-canary.4 → 8.3.1
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/dist/cjs/build.cjs +1 -1
- package/dist/cjs/extract.cjs +1 -1
- package/dist/cjs/extract.cjs.map +1 -1
- package/dist/cjs/fill/fill.cjs +1 -1
- package/dist/cjs/fill/formatFillData.cjs.map +1 -1
- package/dist/cjs/fill/listTranslationsTasks.cjs +1 -1
- package/dist/cjs/fill/translateDictionary.cjs +1 -1
- package/dist/cjs/fill/writeFill.cjs +1 -1
- package/dist/cjs/listContentDeclaration.cjs +1 -1
- package/dist/cjs/liveSync.cjs +3 -3
- package/dist/cjs/pull.cjs +1 -1
- package/dist/cjs/push/push.cjs +1 -1
- package/dist/cjs/reviewDoc/reviewDoc.cjs +1 -1
- package/dist/cjs/reviewDoc/reviewDoc.cjs.map +1 -1
- package/dist/cjs/reviewDoc/reviewDocBlockAware.cjs +1 -1
- package/dist/cjs/test/test.cjs +1 -1
- package/dist/cjs/translateDoc/translateDoc.cjs +1 -1
- package/dist/cjs/translateDoc/translateFile.cjs +2 -2
- package/dist/cjs/watch.cjs +1 -1
- package/dist/esm/build.mjs +1 -1
- package/dist/esm/extract.mjs +1 -1
- package/dist/esm/extract.mjs.map +1 -1
- package/dist/esm/fill/fill.mjs +1 -1
- package/dist/esm/fill/formatFillData.mjs.map +1 -1
- package/dist/esm/fill/listTranslationsTasks.mjs +1 -1
- package/dist/esm/fill/translateDictionary.mjs +1 -1
- package/dist/esm/fill/writeFill.mjs +1 -1
- package/dist/esm/listContentDeclaration.mjs +1 -1
- package/dist/esm/liveSync.mjs +2 -2
- package/dist/esm/pull.mjs +1 -1
- package/dist/esm/push/push.mjs +1 -1
- package/dist/esm/reviewDoc/reviewDoc.mjs +1 -1
- package/dist/esm/reviewDoc/reviewDocBlockAware.mjs +1 -1
- package/dist/esm/test/test.mjs +1 -1
- package/dist/esm/translateDoc/translateDoc.mjs +1 -1
- package/dist/esm/translateDoc/translateFile.mjs +2 -2
- package/dist/esm/watch.mjs +1 -1
- package/dist/types/extract.d.ts.map +1 -1
- package/package.json +12 -12
package/dist/cjs/build.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`@intlayer/chokidar/cli`),t=require(`@intlayer/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`@intlayer/chokidar/cli`),t=require(`@intlayer/chokidar/utils`),n=require(`@intlayer/config/node`),r=require(`@intlayer/chokidar/watcher`);const i=async i=>{let a=(0,n.getConfiguration)(i?.configOptions);(0,e.logConfigDetails)(i?.configOptions);let o=null;i?.with&&(o=(0,t.runParallel)(i.with),o.result.catch(()=>{})),await(0,r.buildAndWatchIntlayer)({persistent:i?.watch??!1,skipPrepare:i?.skipPrepare??!1,configuration:a}),!i?.watch&&o&&o.kill()};exports.build=i;
|
|
2
2
|
//# sourceMappingURL=build.cjs.map
|
package/dist/cjs/extract.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./_virtual/_rolldown/runtime.cjs`);let t=require(`node:fs`),n=require(`node:path`),r=require(`@intlayer/babel`),i=require(`@intlayer/chokidar/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./_virtual/_rolldown/runtime.cjs`);let t=require(`node:fs`),n=require(`node:path`),r=require(`@intlayer/babel`),i=require(`@intlayer/chokidar/build`),a=require(`@intlayer/chokidar/cli`),o=require(`@intlayer/chokidar/utils`),s=require(`@intlayer/config/logger`),c=require(`@intlayer/config/node`),l=require(`@intlayer/unmerged-dictionaries-entry`),u=require(`enquirer`);u=e.__toESM(u);const d=async e=>{let d=(0,c.getConfiguration)(e.configOptions);(0,a.logConfigDetails)(e?.configOptions);let f=(0,s.getAppLogger)(d),{baseDir:p}=d.system,{output:m}=d.compiler,h=e=>(0,s.colorizePath)((0,n.relative)(p,e));if(!m){f(`${s.x} No output configuration found. Add a ${(0,s.colorize)(`compiler.output`,s.ANSIColors.BLUE)} in your configuration.`,{level:`error`});return}let g=(0,r.detectPackageName)(p),_=e.files??[];if(_.length===0){let e=(0,o.buildComponentFilesList)(d).map(e=>({value:e,label:(0,n.relative)(p,e)}));if(e.length===0){f(`No extractable files found in the project.`);return}let t=`__select_all__`,r;try{let n=Math.max((process.stdout.columns||80)-15,20),i=e=>e.length>n?`...${e.slice(-(n-3))}`:e,{files:a}=await u.default.prompt({type:`autocomplete`,name:`files`,message:`Select files to extract (Type to search):`,multiple:!0,limit:40,choices:[{name:t,message:`────── Select all ──────`},...e.map(e=>({name:e.value,message:i(e.label)}))],async toggle(e,n){if(!(!e||e.disabled))return e.enabled=n??!e.enabled,e.name===t&&this.choices.filter(e=>e.name!==t).forEach(t=>{t.enabled=e.enabled}),this.render()},format(){return this.state?.submitted&&this.options?.multiple?`${this.selected.filter(e=>e.name!==t).length} file(s) selected`:this.input??``}});r=a.filter(e=>e!==t)}catch{r=Symbol(`cancel`)}typeof r==`symbol`&&process.exit(0),_=r}if(_.length===0){f(`No files selected for extraction.`);return}let v=_.map(e=>(0,n.resolve)(p,e)).filter(e=>(0,t.existsSync)(e)?!0:(f(`File not found: ${h(e)}`),!1));if(v.length===0)return;let y=(0,l.getUnmergedDictionaries)(d);await Promise.all(v.map(async t=>{try{await(0,r.extractContent)(t,g,{unmergedDictionaries:y,configuration:d,codeOnly:e.codeOnly,declarationOnly:e.declarationOnly})}catch(e){f(`Failed to transform ${t}: ${e.message}`)}})),await(0,i.prepareIntlayer)(d)};exports.extract=d;
|
|
2
2
|
//# sourceMappingURL=extract.cjs.map
|
package/dist/cjs/extract.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.cjs","names":[],"sources":["../../src/extract.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport {
|
|
1
|
+
{"version":3,"file":"extract.cjs","names":["x","ANSIColors"],"sources":["../../src/extract.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\nimport {\n detectPackageName,\n extractContent,\n type PackageName,\n} from '@intlayer/babel';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { logConfigDetails } from '@intlayer/chokidar/cli';\nimport { buildComponentFilesList } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizePath,\n getAppLogger,\n x,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { FilePathPattern } from '@intlayer/types/filePathPattern';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport enquirer from 'enquirer';\n\ntype ExtractOptions = {\n files?: string[];\n output?: FilePathPattern;\n configOptions?: GetConfigurationOptions;\n codeOnly?: boolean;\n declarationOnly?: boolean;\n};\n\nexport const extract = async (options: ExtractOptions) => {\n const configuration = getConfiguration(options.configOptions);\n\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(configuration);\n\n const { baseDir } = configuration.system;\n const { output } = configuration.compiler;\n\n const formatPath = (path: string) => {\n const relativePath = relative(baseDir, path);\n return colorizePath(relativePath);\n };\n\n if (!output) {\n appLogger(\n `${x} No output configuration found. Add a ${colorize('compiler.output', ANSIColors.BLUE)} in your configuration.`,\n {\n level: 'error',\n }\n );\n return;\n }\n\n // Detect package\n const packageName: PackageName = detectPackageName(baseDir);\n\n let filesToExtract = options.files ?? [];\n\n if (filesToExtract.length === 0) {\n // Await all promises simultaneously\n const fileList = buildComponentFilesList(configuration);\n\n // Flatten the nested arrays and remove duplicates\n // Relative paths for selection\n const choices = fileList.map((file) => {\n const relPath = relative(baseDir, file);\n return {\n value: file,\n label: relPath,\n };\n });\n\n if (choices.length === 0) {\n appLogger('No extractable files found in the project.');\n return;\n }\n\n const SELECT_ALL = '__select_all__';\n\n type PromptChoice = {\n name: string;\n enabled: boolean;\n disabled?: boolean | string;\n };\n\n type PromptContext = {\n choices: PromptChoice[];\n render(): void | Promise<void>;\n state: { submitted: boolean };\n selected: PromptChoice[];\n input: string;\n options: { multiple?: boolean };\n };\n\n let selectedFiles: string[] | symbol;\n try {\n const maxLen = Math.max((process.stdout.columns || 80) - 15, 20);\n const truncatePath = (path: string) =>\n path.length > maxLen ? `...${path.slice(-(maxLen - 3))}` : path;\n\n const { files: enquirerSelectedFiles } = await enquirer.prompt<{\n files: string[];\n }>({\n type: 'autocomplete',\n name: 'files',\n message: 'Select files to extract (Type to search):',\n multiple: true,\n // @ts-ignore limit exist but is not typed\n limit: 40,\n choices: [\n { name: SELECT_ALL, message: '────── Select all ──────' },\n ...choices.map((choice) => ({\n name: choice.value,\n message: truncatePath(choice.label),\n })),\n ],\n async toggle(\n this: PromptContext,\n choice: PromptChoice,\n enabled?: boolean\n ) {\n if (!choice || choice.disabled) return;\n choice.enabled = enabled == null ? !choice.enabled : enabled;\n\n if (choice.name === SELECT_ALL) {\n this.choices\n .filter((choiceEl) => choiceEl.name !== SELECT_ALL)\n .forEach((choiceEl) => {\n choiceEl.enabled = choice.enabled;\n });\n }\n\n return this.render();\n },\n format(this: PromptContext) {\n if (this.state?.submitted && this.options?.multiple) {\n return `${this.selected.filter((s) => s.name !== SELECT_ALL).length} file(s) selected`;\n }\n return this.input ?? '';\n },\n });\n\n selectedFiles = enquirerSelectedFiles.filter((f) => f !== SELECT_ALL);\n } catch {\n selectedFiles = Symbol('cancel');\n }\n\n if (typeof selectedFiles === 'symbol') {\n // User cancelled\n process.exit(0);\n }\n\n filesToExtract = selectedFiles as string[];\n }\n\n if (filesToExtract.length === 0) {\n appLogger('No files selected for extraction.');\n return;\n }\n\n const absoluteFiles = filesToExtract\n .map((file) => resolve(baseDir, file))\n .filter((file) => {\n if (!existsSync(file)) {\n appLogger(`File not found: ${formatPath(file)}`);\n return false;\n }\n return true;\n });\n\n if (absoluteFiles.length === 0) {\n return;\n }\n\n const unmergedDictionaries = getUnmergedDictionaries(configuration);\n\n await Promise.all(\n absoluteFiles.map(async (filePath) => {\n try {\n await extractContent(filePath, packageName, {\n unmergedDictionaries,\n configuration,\n codeOnly: options.codeOnly,\n declarationOnly: options.declarationOnly,\n });\n } catch (error) {\n appLogger(\n `Failed to transform ${filePath}: ${(error as Error).message}`\n );\n }\n })\n );\n\n await prepareIntlayer(configuration); // Prepare Intlayer to apply the changes\n};\n"],"mappings":"odAiCA,MAAa,EAAU,KAAO,IAA4B,CACxD,IAAM,GAAA,EAAA,EAAA,kBAAiC,EAAQ,cAAc,EAE7D,EAAA,EAAA,kBAAiB,GAAS,cAAc,CAExC,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAc,CAEvC,CAAE,WAAY,EAAc,OAC5B,CAAE,UAAW,EAAc,SAE3B,EAAc,IAElB,EAAA,EAAA,eAAA,EAAA,EAAA,UAD8B,EAAS,EAAK,CACX,CAGnC,GAAI,CAAC,EAAQ,CACX,EACE,GAAGA,EAAAA,EAAE,yCAAA,EAAA,EAAA,UAAiD,kBAAmBC,EAAAA,WAAW,KAAK,CAAC,yBAC1F,CACE,MAAO,QACR,CACF,CACD,OAIF,IAAM,GAAA,EAAA,EAAA,mBAA6C,EAAQ,CAEvD,EAAiB,EAAQ,OAAS,EAAE,CAExC,GAAI,EAAe,SAAW,EAAG,CAM/B,IAAM,GAAA,EAAA,EAAA,yBAJmC,EAAc,CAI9B,IAAK,IAErB,CACL,MAAO,EACP,OAAA,EAAA,EAAA,UAHuB,EAAS,EAAK,CAItC,EACD,CAEF,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAU,6CAA6C,CACvD,OAGF,IAAM,EAAa,iBAiBf,EACJ,GAAI,CACF,IAAM,EAAS,KAAK,KAAK,QAAQ,OAAO,SAAW,IAAM,GAAI,GAAG,CAC1D,EAAgB,GACpB,EAAK,OAAS,EAAS,MAAM,EAAK,MAAM,EAAE,EAAS,GAAG,GAAK,EAEvD,CAAE,MAAO,GAA0B,MAAM,EAAA,QAAS,OAErD,CACD,KAAM,eACN,KAAM,QACN,QAAS,4CACT,SAAU,GAEV,MAAO,GACP,QAAS,CACP,CAAE,KAAM,EAAY,QAAS,2BAA4B,CACzD,GAAG,EAAQ,IAAK,IAAY,CAC1B,KAAM,EAAO,MACb,QAAS,EAAa,EAAO,MAAM,CACpC,EAAE,CACJ,CACD,MAAM,OAEJ,EACA,EACA,CACI,MAAC,GAAU,EAAO,UAWtB,MAVA,GAAO,QAAU,GAAkB,CAAC,EAAO,QAEvC,EAAO,OAAS,GAClB,KAAK,QACF,OAAQ,GAAa,EAAS,OAAS,EAAW,CAClD,QAAS,GAAa,CACrB,EAAS,QAAU,EAAO,SAC1B,CAGC,KAAK,QAAQ,EAEtB,QAA4B,CAI1B,OAHI,KAAK,OAAO,WAAa,KAAK,SAAS,SAClC,GAAG,KAAK,SAAS,OAAQ,GAAM,EAAE,OAAS,EAAW,CAAC,OAAO,mBAE/D,KAAK,OAAS,IAExB,CAAC,CAEF,EAAgB,EAAsB,OAAQ,GAAM,IAAM,EAAW,MAC/D,CACN,EAAgB,OAAO,SAAS,CAG9B,OAAO,GAAkB,UAE3B,QAAQ,KAAK,EAAE,CAGjB,EAAiB,EAGnB,GAAI,EAAe,SAAW,EAAG,CAC/B,EAAU,oCAAoC,CAC9C,OAGF,IAAM,EAAgB,EACnB,IAAK,IAAA,EAAA,EAAA,SAAiB,EAAS,EAAK,CAAC,CACrC,OAAQ,IACH,EAAA,EAAA,YAAY,EAAK,CAId,IAHL,EAAU,mBAAmB,EAAW,EAAK,GAAG,CACzC,IAGT,CAEJ,GAAI,EAAc,SAAW,EAC3B,OAGF,IAAM,GAAA,EAAA,EAAA,yBAA+C,EAAc,CAEnE,MAAM,QAAQ,IACZ,EAAc,IAAI,KAAO,IAAa,CACpC,GAAI,CACF,MAAA,EAAA,EAAA,gBAAqB,EAAU,EAAa,CAC1C,uBACA,gBACA,SAAU,EAAQ,SAClB,gBAAiB,EAAQ,gBAC1B,CAAC,OACK,EAAO,CACd,EACE,uBAAuB,EAAS,IAAK,EAAgB,UACtD,GAEH,CACH,CAED,MAAA,EAAA,EAAA,iBAAsB,EAAc"}
|
package/dist/cjs/fill/fill.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../getTargetDictionary.cjs`),t=require(`../utils/setupAI.cjs`),n=require(`./listTranslationsTasks.cjs`),r=require(`./translateDictionary.cjs`),i=require(`./writeFill.cjs`);let a=require(`node:path`),o=require(`@intlayer/chokidar/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../getTargetDictionary.cjs`),t=require(`../utils/setupAI.cjs`),n=require(`./listTranslationsTasks.cjs`),r=require(`./translateDictionary.cjs`),i=require(`./writeFill.cjs`);let a=require(`node:path`),o=require(`@intlayer/chokidar/build`),s=require(`@intlayer/chokidar/cli`),c=require(`@intlayer/chokidar/utils`),l=require(`@intlayer/config/logger`),u=require(`@intlayer/config/node`);const d=async d=>{let f=(0,u.getConfiguration)(d?.configOptions);(0,s.logConfigDetails)(d?.configOptions);let p=(0,l.getAppLogger)(f);d?.build===!0?await(0,o.prepareIntlayer)(f,{forceRun:!0}):d?.build===void 0&&await(0,o.prepareIntlayer)(f);let{defaultLocale:m,locales:h}=f.internationalization,g=d?.mode??`complete`,_=d?.sourceLocale??m,v=d?.outputLocales?e.ensureArray(d.outputLocales):h,y=await t.setupAI(f,d?.aiOptions);if(!y?.hasAIAccess)return;let{aiClient:b,aiConfig:x}=y,S=await e.getTargetUnmergedDictionaries(d),C=new Set;S.forEach(e=>{C.add(e.key)});let w=Array.from(C);if(p([`Affected dictionary keys for processing:`,w.length>0?w.map(e=>(0,l.colorizeKey)(e)).join(`, `):(0,l.colorize)(`No keys found`,l.ANSIColors.YELLOW)]),w.length===0)return;let T=n.listTranslationsTasks(S.map(e=>e.localId),v,g,_,f),E=d?.nbConcurrentTranslations??7,D=(0,c.getGlobalLimiter)(E),O=(0,c.getTaskLimiter)(Math.max(1,Math.min(d?.nbConcurrentTasks??E,T.length))),k=T.map(e=>O(async()=>{let t=(0,a.relative)(f?.content?.baseDir??process.cwd(),e?.dictionaryFilePath??``);p(`${e.dictionaryPreset} Processing ${(0,l.colorizePath)((0,a.basename)(t))}`,{level:`info`});let n=await r.translateDictionary(e,f,{mode:g,aiOptions:d?.aiOptions,fillMetadata:!d?.skipMetadata,onHandle:D,aiClient:b,aiConfig:x});if(!n?.dictionaryOutput)return;let{dictionaryOutput:s,sourceLocale:u}=n,m=typeof s.fill==`string`||typeof s.fill==`object`,h=typeof s.locale==`string`,_=m?s.fill:h?f.dictionary?.fill??!0:!1;typeof _==`string`||typeof _==`object`?await i.writeFill({...s,fill:_},v,[u],f):(await(0,o.writeContentDeclaration)(s,f),s.filePath&&p(`${e.dictionaryPreset} Content declaration written to ${(0,c.formatPath)((0,a.basename)(s.filePath))}`,{level:`info`}))}));await Promise.all(k),await D.onIdle()};exports.fill=d;
|
|
2
2
|
//# sourceMappingURL=fill.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatFillData.cjs","names":[],"sources":["../../../src/fill/formatFillData.ts"],"sourcesContent":["import { basename, dirname, extname, relative } from 'node:path';\nimport {\n getFormatFromExtension,\n resolveRelativePath,\n} from '@intlayer/chokidar/utils';\nimport { parseStringPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { DictionaryKey, Fill } from '@intlayer/types/dictionary';\nimport type {\n FilePathPattern,\n FilePathPatternContext,\n} from '@intlayer/types/filePathPattern';\n\nexport type FillData = {\n localeList: Locale[];\n filePath: string;\n isPerLocale: boolean;\n};\n\nexport const formatFillData = async (\n fillField: Fill,\n localeList: Locale[],\n filePath: string,\n dictionaryKey: DictionaryKey,\n configuration: IntlayerConfig\n): Promise<FillData[]> => {\n if (!fillField || typeof fillField === 'boolean') return [];\n\n const { baseDir } = configuration.system;\n const { defaultLocale } = configuration.internationalization;\n\n const extension = extname(filePath);\n const base = basename(filePath);\n\n // Extract the original filename without extensions\n const cleanComponentFileName = base.includes('.content.')\n ? base.split('.content.')[0]\n : base.split('.')[0];\n\n const uncapitalizedName =\n cleanComponentFileName.charAt(0).toLowerCase() +\n cleanComponentFileName.slice(1);\n\n const componentFormat = getFormatFromExtension(extension
|
|
1
|
+
{"version":3,"file":"formatFillData.cjs","names":[],"sources":["../../../src/fill/formatFillData.ts"],"sourcesContent":["import { basename, dirname, extname, relative } from 'node:path';\nimport {\n getFormatFromExtension,\n resolveRelativePath,\n} from '@intlayer/chokidar/utils';\nimport { parseStringPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { DictionaryKey, Fill } from '@intlayer/types/dictionary';\nimport type {\n FilePathPattern,\n FilePathPatternContext,\n} from '@intlayer/types/filePathPattern';\n\nexport type FillData = {\n localeList: Locale[];\n filePath: string;\n isPerLocale: boolean;\n};\n\nexport const formatFillData = async (\n fillField: Fill,\n localeList: Locale[],\n filePath: string,\n dictionaryKey: DictionaryKey,\n configuration: IntlayerConfig\n): Promise<FillData[]> => {\n if (!fillField || typeof fillField === 'boolean') return [];\n\n const { baseDir } = configuration.system;\n const { defaultLocale } = configuration.internationalization;\n\n const extension = extname(filePath);\n const base = basename(filePath);\n\n // Extract the original filename without extensions\n const cleanComponentFileName = base.includes('.content.')\n ? base.split('.content.')[0]\n : base.split('.')[0];\n\n const uncapitalizedName =\n cleanComponentFileName.charAt(0).toLowerCase() +\n cleanComponentFileName.slice(1);\n\n const componentFormat = getFormatFromExtension(extension);\n\n const getContext = (\n locale: Locale,\n patternType?: FilePathPattern\n ): FilePathPatternContext => {\n let format: FilePathPatternContext['format'] = 'json';\n if (typeof patternType === 'string') {\n const extFormat = getFormatFromExtension(extname(patternType) as any);\n if (extFormat) {\n format = extFormat as any;\n }\n }\n\n return {\n key: dictionaryKey,\n componentDirPath: relative(baseDir, dirname(filePath)),\n componentFileName: cleanComponentFileName,\n fileName: uncapitalizedName,\n componentFormat:\n componentFormat as FilePathPatternContext['componentFormat'],\n componentExtension:\n extension as FilePathPatternContext['componentExtension'],\n format,\n locale,\n extension: configuration.content.fileExtensions[0],\n };\n };\n\n const processPattern = async (\n pattern: FilePathPattern,\n locales: Locale[]\n ): Promise<FillData[]> => {\n const dummyLocale = '###########locale###########' as Locale;\n let isPatternPerLocale = false;\n\n if (typeof pattern === 'string') {\n isPatternPerLocale = pattern.includes('{{locale}}');\n } else if (typeof pattern === 'function') {\n const pathWithDummy = await pattern(getContext(dummyLocale, pattern));\n isPatternPerLocale = pathWithDummy.includes(dummyLocale);\n }\n\n if (isPatternPerLocale) {\n const resolvedPaths: FillData[] = [];\n\n // Generate one path per locale\n for (const locale of locales) {\n const rawPath =\n typeof pattern === 'string'\n ? parseStringPattern(pattern, getContext(locale, pattern))\n : await pattern(getContext(locale, pattern));\n\n const absolutePath = resolveRelativePath(rawPath, filePath, baseDir);\n\n resolvedPaths.push({\n filePath: absolutePath,\n localeList: [locale],\n isPerLocale: true,\n });\n }\n\n // Group by filePath in case multiple locales resolve to the same path\n const groupedByFilePath = resolvedPaths.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n if (!existing.localeList.includes(curr.localeList[0])) {\n existing.localeList.push(...curr.localeList);\n }\n // If multiple locales share a path, it's no longer strictly per-locale\n existing.isPerLocale = false;\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n return groupedByFilePath;\n } else {\n // Single multi-lingual path using default locale for pattern resolution\n const rawPath =\n typeof pattern === 'string'\n ? parseStringPattern(pattern, getContext(defaultLocale, pattern))\n : await pattern(getContext(defaultLocale, pattern));\n\n const absolutePath = resolveRelativePath(rawPath, filePath, baseDir);\n\n return [\n {\n filePath: absolutePath,\n localeList: locales,\n isPerLocale: false,\n },\n ];\n }\n };\n\n // Handle Record of Locales\n if (typeof fillField === 'object' && fillField !== null) {\n const results: FillData[] = [];\n\n for (const locale of localeList) {\n const pattern = (fillField as Record<string, any>)[locale];\n if (pattern && typeof pattern !== 'boolean') {\n const res = await processPattern(pattern as FilePathPattern, [locale]);\n results.push(...res);\n }\n }\n\n // Merge identical file paths if they stem from different locales having the same output path\n const grouped = results.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n for (const loc of curr.localeList) {\n if (!existing.localeList.includes(loc)) {\n existing.localeList.push(loc);\n }\n }\n existing.isPerLocale = false;\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n return grouped;\n }\n\n // Handle static string or function patterns\n if (typeof fillField === 'string' || typeof fillField === 'function') {\n return processPattern(fillField as FilePathPattern, localeList);\n }\n\n return [];\n};\n"],"mappings":"qNAoBA,MAAa,EAAiB,MAC5B,EACA,EACA,EACA,EACA,IACwB,CACxB,GAAI,CAAC,GAAa,OAAO,GAAc,UAAW,MAAO,EAAE,CAE3D,GAAM,CAAE,WAAY,EAAc,OAC5B,CAAE,iBAAkB,EAAc,qBAElC,GAAA,EAAA,EAAA,SAAoB,EAAS,CAC7B,GAAA,EAAA,EAAA,UAAgB,EAAS,CAGzB,EAAyB,EAAK,SAAS,YAAY,CACrD,EAAK,MAAM,YAAY,CAAC,GACxB,EAAK,MAAM,IAAI,CAAC,GAEd,EACJ,EAAuB,OAAO,EAAE,CAAC,aAAa,CAC9C,EAAuB,MAAM,EAAE,CAE3B,GAAA,EAAA,EAAA,wBAAyC,EAAU,CAEnD,GACJ,EACA,IAC2B,CAC3B,IAAI,EAA2C,OAC/C,GAAI,OAAO,GAAgB,SAAU,CACnC,IAAM,GAAA,EAAA,EAAA,yBAAA,EAAA,EAAA,SAA2C,EAAY,CAAQ,CACjE,IACF,EAAS,GAIb,MAAO,CACL,IAAK,EACL,kBAAA,EAAA,EAAA,UAA2B,GAAA,EAAA,EAAA,SAAiB,EAAS,CAAC,CACtD,kBAAmB,EACnB,SAAU,EAER,kBACF,mBACE,EACF,SACA,SACA,UAAW,EAAc,QAAQ,eAAe,GACjD,EAGG,EAAiB,MACrB,EACA,IACwB,CACxB,IAAM,EAAc,+BAChB,EAAqB,GASzB,GAPI,OAAO,GAAY,SACrB,EAAqB,EAAQ,SAAS,aAAa,CAC1C,OAAO,GAAY,aAE5B,GADsB,MAAM,EAAQ,EAAW,EAAa,EAAQ,CAAC,EAClC,SAAS,EAAY,EAGtD,EAAoB,CACtB,IAAM,EAA4B,EAAE,CAGpC,IAAK,IAAM,KAAU,EAAS,CAM5B,IAAM,GAAA,EAAA,EAAA,qBAJJ,OAAO,GAAY,UAAA,EAAA,EAAA,oBACI,EAAS,EAAW,EAAQ,EAAQ,CAAC,CACxD,MAAM,EAAQ,EAAW,EAAQ,EAAQ,CAAC,CAEE,EAAU,EAAQ,CAEpE,EAAc,KAAK,CACjB,SAAU,EACV,WAAY,CAAC,EAAO,CACpB,YAAa,GACd,CAAC,CAkBJ,OAd0B,EAAc,QAAQ,EAAK,IAAS,CAC5D,IAAM,EAAW,EAAI,KAAM,GAAS,EAAK,WAAa,EAAK,SAAS,CAUpE,OATI,GACG,EAAS,WAAW,SAAS,EAAK,WAAW,GAAG,EACnD,EAAS,WAAW,KAAK,GAAG,EAAK,WAAW,CAG9C,EAAS,YAAc,IAEvB,EAAI,KAAK,EAAK,CAET,GACN,EAAE,CAAe,MAYpB,MAAO,CACL,CACE,UAAA,EAAA,EAAA,qBARF,OAAO,GAAY,UAAA,EAAA,EAAA,oBACI,EAAS,EAAW,EAAe,EAAQ,CAAC,CAC/D,MAAM,EAAQ,EAAW,EAAe,EAAQ,CAAC,CAEL,EAAU,EAAQ,CAKhE,WAAY,EACZ,YAAa,GACd,CACF,EAKL,GAAI,OAAO,GAAc,UAAY,EAAoB,CACvD,IAAM,EAAsB,EAAE,CAE9B,IAAK,IAAM,KAAU,EAAY,CAC/B,IAAM,EAAW,EAAkC,GACnD,GAAI,GAAW,OAAO,GAAY,UAAW,CAC3C,IAAM,EAAM,MAAM,EAAe,EAA4B,CAAC,EAAO,CAAC,CACtE,EAAQ,KAAK,GAAG,EAAI,EAoBxB,OAfgB,EAAQ,QAAQ,EAAK,IAAS,CAC5C,IAAM,EAAW,EAAI,KAAM,GAAS,EAAK,WAAa,EAAK,SAAS,CACpE,GAAI,EAAU,CACZ,IAAK,IAAM,KAAO,EAAK,WAChB,EAAS,WAAW,SAAS,EAAI,EACpC,EAAS,WAAW,KAAK,EAAI,CAGjC,EAAS,YAAc,QAEvB,EAAI,KAAK,EAAK,CAEhB,OAAO,GACN,EAAE,CAAe,CAUtB,OAJI,OAAO,GAAc,UAAY,OAAO,GAAc,WACjD,EAAe,EAA8B,EAAW,CAG1D,EAAE"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../test/listMissingTranslations.cjs`);let t=require(`node:path`),n=require(`@intlayer/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../test/listMissingTranslations.cjs`);let t=require(`node:path`),n=require(`@intlayer/chokidar/utils`),r=require(`@intlayer/config/logger`),i=require(`@intlayer/unmerged-dictionaries-entry`),a=require(`@intlayer/core/plugins`),o=require(`@intlayer/dictionaries-entry`);const s=(s,c,l,u,d)=>{let f=(0,r.getAppLogger)(d),p=(0,o.getDictionaries)(d),m=(0,i.getUnmergedDictionaries)(d),h=Object.values(m).flat().filter(e=>s.includes(e.localId)),{missingTranslations:g}=e.listMissingTranslationsWithConfig(d),_=Math.max(...h.map(e=>e.key.length)),v=[];for(let e of h){let i=(0,r.colon)([` - `,(0,r.colorize)(`[`,r.ANSIColors.GREY_DARK),(0,r.colorizeKey)(e.key),(0,r.colorize)(`]`,r.ANSIColors.GREY_DARK)].join(``),{colSize:_+6}),o=e.key,s=e.localId,m=p[o];if((e.filled??!1)===!0||(e.fill??d.dictionary?.fill??!1)===!1)continue;let h=e.locale??u;if(!m){f(`${i} Dictionary not found in dictionariesRecord. Skipping.`,{level:`warn`});continue}if(!e.filePath){f(`${i} Dictionary has no file path. Skipping.`,{level:`warn`});continue}let y=(0,a.getFilterTranslationsOnlyDictionary)(m,h);if(Object.keys(y).length===0){f(`${i} No content found for dictionary in source locale ${(0,n.formatLocale)(h)}. Skipping translation for this dictionary.`,{level:`warn`});continue}let b=c;if(l===`complete`&&(b=g.find(e=>e.key===o)?.locales.filter(e=>c.includes(e))??[]),b.length===0){f(`${i} ${(0,r.colorize)(`No locales to fill, Skipping`,r.ANSIColors.GREY_DARK)} ${(0,r.colorizePath)((0,t.basename)(e.filePath))}`,{level:`warn`});continue}v.push({dictionaryKey:o,dictionaryLocalId:s,sourceLocale:h,targetLocales:b,dictionaryPreset:i,dictionaryFilePath:e.filePath})}return v};exports.listTranslationsTasks=s;
|
|
2
2
|
//# sourceMappingURL=listTranslationsTasks.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./deepMergeContent.cjs`),t=require(`./getFilterMissingContentPerLocale.cjs`);let n=require(`node:path`),r=require(`@intlayer/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./deepMergeContent.cjs`),t=require(`./getFilterMissingContentPerLocale.cjs`);let n=require(`node:path`),r=require(`@intlayer/chokidar/utils`),i=require(`@intlayer/config/logger`),a=require(`@intlayer/unmerged-dictionaries-entry`),o=require(`@intlayer/core/plugins`),s=require(`@intlayer/api`),c=require(`@intlayer/config/utils`);const l=e=>!e.description||!e.title||!e.tags,u=e=>{if(typeof e!=`object`||!e||Array.isArray(e))return{content:e,nulls:void 0,hasNulls:!1};let t={},n={},r=!1;for(let[i,a]of Object.entries(e))if(a===null)n[i]=null,r=!0;else{let e=u(a);t[i]=e.content,e.hasNulls&&(n[i]=e.nulls,r=!0)}return{content:t,nulls:r?n:void 0,hasNulls:r}},d=1e3*10;let f=0;const p=async(p,m,h)=>{let g=(0,i.getAppLogger)(m),_=(0,s.getIntlayerAPIProxy)(void 0,m),{mode:v,aiOptions:y,fillMetadata:b,aiClient:x,aiConfig:S}={mode:`complete`,fillMetadata:!0,...h},C=()=>{f=0,h?.onSuccess?.()};return await(0,c.retryManager)(async()=>{let s=(0,a.getUnmergedDictionaries)(m),w=s[p.dictionaryKey].find(e=>e.localId===p.dictionaryLocalId);if(!w)return g(`${p.dictionaryPreset}Dictionary not found in unmergedDictionariesRecord. Skipping.`,{level:`warn`}),{...p,dictionaryOutput:null};let T;if(b&&(l(w)||v===`review`)){let e=(0,o.getPerLocaleDictionary)(w,m.internationalization.defaultLocale);g(`${p.dictionaryPreset} Filling missing metadata for ${(0,i.colorizePath)((0,n.basename)(w.filePath))}`,{level:`info`});let t=async()=>x&&S?{data:await x.auditDictionaryMetadata({fileContent:JSON.stringify(e),aiConfig:S})}:await _.ai.auditContentDeclarationMetadata({fileContent:JSON.stringify(e),aiOptions:y});T=(h?.onHandle?await h.onHandle(t):await t()).data?.fileContent}let E=await Promise.all(p.targetLocales.map(async a=>{let l=structuredClone(w),m;if(typeof w.locale==`string`){let e=w.filePath?.replace(RegExp(`/${p.sourceLocale}/`,`g`),`/${a}/`),n=e?s[p.dictionaryKey]?.find(t=>t.filePath===e&&t.locale===a):void 0;m=n??{key:w.key,content:{},filePath:e,locale:a},v===`complete`&&(l=t.getFilterMissingContentPerLocale(l,n))}else v===`complete`&&(l=(0,o.getFilterMissingTranslationsDictionary)(l,a)),l=(0,o.getPerLocaleDictionary)(l,p.sourceLocale),m=(0,o.getPerLocaleDictionary)(w,a);let b=(0,i.colon)([(0,i.colorize)(`[`,i.ANSIColors.GREY_DARK),(0,r.formatLocale)(a),(0,i.colorize)(`]`,i.ANSIColors.GREY_DARK)].join(``),{colSize:18}),E=(e,t)=>t<=1?``:(0,i.colon)([(0,i.colorize)(`[`,i.ANSIColors.GREY_DARK),(0,i.colorizeNumber)(e+1),(0,i.colorize)(`/${t}`,i.ANSIColors.GREY_DARK),(0,i.colorize)(`]`,i.ANSIColors.GREY_DARK)].join(``),{colSize:5});g(`${p.dictionaryPreset}${b} Preparing ${(0,i.colorizePath)((0,n.basename)(m.filePath))}`,{level:`info`});let D=typeof l.content==`object`&&l.content!==null||Array.isArray(l.content),{content:O,nulls:k}=u(D?l.content:{__INTLAYER_ROOT_PRIMITIVE_CONTENT__:l.content}),A=(0,r.chunkJSON)(O,7e3),j=A.length;j>1&&g(`${p.dictionaryPreset}${b} Split into ${(0,i.colorizeNumber)(j)} chunks for translation`,{level:`info`});let M=[],N=A.map(e=>{let t=E(e.index,e.total);j>1&&g(`${p.dictionaryPreset}${b}${t} Translating chunk`,{level:`info`});let n=(0,r.reconstructFromSingleChunk)(e),o=(0,r.reduceObjectFormat)(D?m.content:{__INTLAYER_ROOT_PRIMITIVE_CONTENT__:m.content},n),s=async()=>await(0,c.retryManager)(async()=>{let e;if(e=x&&S?await x.translateJSON({entryFileContent:n,presetOutputContent:o,dictionaryDescription:l.description??T?.description??``,entryLocale:p.sourceLocale,outputLocale:a,mode:v,aiConfig:S}):await _.ai.translateJSON({entryFileContent:n,presetOutputContent:o,dictionaryDescription:l.description??T?.description??``,entryLocale:p.sourceLocale,outputLocale:a,mode:v,aiOptions:y}).then(e=>e.data),!e?.fileContent)throw Error(`No content result`);let{isIdentic:t}=(0,r.verifyIdenticObjectFormat)(e.fileContent,n);if(!t)throw Error(`Translation result does not match expected format`);return C(),e.fileContent},{maxRetry:3,delay:d,onError:({error:t,attempt:n,maxRetry:r})=>{let a=E(e.index,e.total);g(`${p.dictionaryPreset}${b}${a} ${(0,i.colorize)(`Error filling:`,i.ANSIColors.RED)} ${(0,i.colorize)(typeof t==`string`?t:JSON.stringify(t),i.ANSIColors.GREY_DARK)} - Attempt ${(0,i.colorizeNumber)(n+1)} of ${(0,i.colorizeNumber)(r)}`,{level:`error`}),f+=1,f>=10&&(g(`There is something wrong.`,{level:`error`}),process.exit(1))}})();return(h?.onHandle?h.onHandle(s):s()).then(t=>({chunk:e,result:t}))});(await Promise.all(N)).sort((e,t)=>e.chunk.index-t.chunk.index).forEach(({result:e})=>{M.push(e)});let P=(0,r.mergeChunks)(M);k&&(P=e.deepMergeContent(P,k));let F={...l,content:P}.content;return D||(F=F?.__INTLAYER_ROOT_PRIMITIVE_CONTENT__),typeof w.locale==`string`&&(F=e.deepMergeContent(m.content??{},F)),[a,F]})),D=Object.fromEntries(E),O={...(0,o.getMultilingualDictionary)(w.locale?{...w,key:w.key,content:{}}:w),locale:void 0,...T};for(let e of p.targetLocales)D[e]&&(O=(0,o.insertContentInDictionary)(O,D[e],e));if(g(`${p.dictionaryPreset} ${(0,i.colorize)(`Translation completed successfully`,i.ANSIColors.GREEN)} for ${(0,i.colorizePath)((0,n.basename)(O.filePath))}`,{level:`info`}),w.locale&&(w.fill===!0||w.fill===void 0)&&w.location===`local`){let e=w.filePath.split(`.`).slice(0,-1),t=e[e.length-1];return JSON.parse(JSON.stringify({...p,dictionaryOutput:{...O,fill:void 0,filled:!0}}).replaceAll(RegExp(`\\.${t}\\.[a-zA-Z0-9]+`,`g`),`.filled.${t}.json`))}return{...p,dictionaryOutput:O}},{maxRetry:2,delay:d,onError:({error:e,attempt:t,maxRetry:n})=>g(`${p.dictionaryPreset} ${(0,i.colorize)(`Error:`,i.ANSIColors.RED)} ${(0,i.colorize)(typeof e==`string`?e:JSON.stringify(e),i.ANSIColors.GREY_DARK)} - Attempt ${(0,i.colorizeNumber)(t+1)} of ${(0,i.colorizeNumber)(n)}`,{level:`error`}),onMaxTryReached:({error:e})=>g(`${p.dictionaryPreset} ${(0,i.colorize)(`Maximum number of retries reached:`,i.ANSIColors.RED)} ${(0,i.colorize)(typeof e==`string`?e:JSON.stringify(e),i.ANSIColors.GREY_DARK)}`,{level:`error`})})()};exports.translateDictionary=p;
|
|
2
2
|
//# sourceMappingURL=translateDictionary.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./formatFillData.cjs`),t=require(`./getAvailableLocalesInDictionary.cjs`);let n=require(`node:path`),r=require(`@intlayer/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./formatFillData.cjs`),t=require(`./getAvailableLocalesInDictionary.cjs`);let n=require(`node:path`),r=require(`@intlayer/chokidar/build`),i=require(`@intlayer/chokidar/utils`),a=require(`@intlayer/config/logger`),o=require(`@intlayer/dictionaries-entry`);const s=async(s,c,l,u)=>{let d=(0,a.getAppLogger)(u),f=(0,o.getDictionaries)(u)[s.key],{filePath:p}=s;if(!p){d(`No file path found for dictionary`,{level:`error`});return}let m=s.fill??u.dictionary?.fill??!0;if(m===!1){d(`Auto fill is disabled for '${(0,a.colorizeKey)(f.key)}'`,{level:`info`});return}let h=(c??u.internationalization.locales).filter(e=>!l?.includes(e)),g=t.getAvailableLocalesInDictionary(s),_=h.filter(e=>g.includes(e));if(_.length===0){d(`No translations available for dictionary '${(0,a.colorizeKey)(f.key)}'`,{level:`info`});return}let v=await e.formatFillData(m,_,p,f.key,u);for await(let e of v){if(!e.filePath){d(`No file path found for auto filled content declaration for '${(0,a.colorizeKey)(f.key)}'`,{level:`error`});continue}let{fill:t,...o}=s,c=(0,n.relative)(u.system.baseDir,e.filePath);if(await(0,r.writeContentDeclaration)({...o,filled:!0,locale:e.isPerLocale?e.localeList[0]:void 0,localId:`${s.key}::local::${c}`,filePath:c},u,{localeList:e.localeList}),e.isPerLocale){let t=e.localeList[0];d(`Auto filled per-locale content declaration for '${(0,a.colorizeKey)(f.key)}' written to ${(0,i.formatPath)(e.filePath)} for locale ${(0,i.formatLocale)(t)}`,{level:`info`})}else d(`Auto filled content declaration for '${(0,a.colorizeKey)(f.key)}' written to ${(0,i.formatPath)(e.filePath)}`,{level:`info`})}};exports.writeFill=s;
|
|
2
2
|
//# sourceMappingURL=writeFill.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`node:path`),t=require(`@intlayer/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`node:path`),t=require(`@intlayer/chokidar/utils`),n=require(`@intlayer/config/logger`),r=require(`@intlayer/config/node`),i=require(`@intlayer/unmerged-dictionaries-entry`);const a=t=>{let n=(0,r.getConfiguration)(t?.configOptions),a=(0,i.getUnmergedDictionaries)(n);return Object.values(a).flat().map(r=>({key:r.key??``,path:t?.absolute?r.filePath??`Remote`:(0,e.relative)(n.system.baseDir,r.filePath??`Remote`)}))},o=e=>{let i=a(e);if(e?.json){console.log(JSON.stringify(i));return}let o=(0,n.getAppLogger)((0,r.getConfiguration)(e?.configOptions)),s=i.map(e=>[(0,n.colon)(` - ${(0,n.colorizeKey)(e.key)}`,{colSize:i.map(e=>e.key.length),maxSize:60}),` - `,(0,t.formatPath)(e.path)].join(``));o(`Content declaration files:`),s.forEach(e=>{o(e,{level:`info`})}),o(`Total content declaration files: ${(0,n.colorizeNumber)(i.length)}`)};exports.listContentDeclaration=o,exports.listContentDeclarationRows=a;
|
|
2
2
|
//# sourceMappingURL=listContentDeclaration.cjs.map
|
package/dist/cjs/liveSync.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./_virtual/_rolldown/runtime.cjs`),t=require(`./IntlayerEventListener.cjs`);let n=require(`@intlayer/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./_virtual/_rolldown/runtime.cjs`),t=require(`./IntlayerEventListener.cjs`);let n=require(`@intlayer/chokidar/build`),r=require(`@intlayer/chokidar/utils`),i=require(`@intlayer/config/logger`),a=require(`@intlayer/config/node`),o=require(`@intlayer/unmerged-dictionaries-entry`),s=require(`node:http`),c=require(`@intlayer/config/package.json`);c=e.__toESM(c);let l=require(`@intlayer/core/plugins`),u=require(`@intlayer/dictionaries-entry`);const d=async(e,t)=>{(0,i.getAppLogger)(t)(`Writing dictionary ${e.key}`),await(0,n.buildDictionary)([e],t)},f=async e=>{let n=(0,a.getConfiguration)(e?.configOptions),f=(0,i.getAppLogger)(n),{liveSyncPort:p,liveSyncURL:m}=n.editor,h=null,g=null;if(e?.with&&(h=(0,r.runParallel)(e.with),h.result.catch(()=>{})),n.editor.liveSync&&n.editor.backendURL&&n.editor.clientId&&n.editor.clientSecret){g=new t.IntlayerEventListener(n),g.onConnectionOpen=()=>{f(`Live sync connection established`)},g.onConnectionError=e=>{let t=e;f(`Live sync connection error: ${t.message??`Unknown error`}`,{level:`warn`}),(t.message?.includes(`terminated`)||t.message?.includes(`closed`))&&f(`Server connection was terminated, automatic reconnection will be attempted...`,{level:`info`})},g.onDictionaryAdded=e=>d(e,n),g.onDictionaryChange=e=>d(e,n),g.onDictionaryDeleted=e=>d(e,n);try{await g.initialize()}catch(e){f(`Failed to initialize IntlayerEventListener:`,{level:`error`}),f(`Error: ${e instanceof Error?e.message:String(e)}`,{level:`error`})}}else n.editor.liveSync?(!n.editor.clientId||!n.editor.clientSecret)&&f(`Missing client credentials for hot reload. Please configure clientId and clientSecret`):f(`Hot reload is disabled. Please enable it in the configuration (editor.liveSync).`);let _=(0,s.createServer)(async(e,t)=>{if(e.method===`OPTIONS`){t.writeHead(200,{"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`}),t.end();return}if(e.url?.startsWith(`/dictionaries`)){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`});let r=(0,u.getDictionaries)(n);if(e.url.startsWith(`/dictionaries/`)){let[n,i]=decodeURIComponent(e.url).slice(14).split(`/`),a=r[n]??null;if(i){let e=(0,l.getLocalizedContent)(a.content,i,{dictionaryKey:n,keyPath:[]});t.end(JSON.stringify(e));return}t.end(JSON.stringify(a));return}t.end(JSON.stringify(r));return}if(e.url?.startsWith(`/unmerged_dictionaries`)){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`});let r=(0,o.getUnmergedDictionaries)(n);if(e.url.startsWith(`/unmerged_dictionaries/`)){let n=r[decodeURIComponent(e.url.slice(23))]??null;t.end(JSON.stringify(n));return}t.end(JSON.stringify(r));return}if(e.url===`/configuration`){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`}),t.end(JSON.stringify(n));return}if(e.url===`/health`){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`}),t.end(JSON.stringify({status:`ok`}));return}t.end(`Not found`)}),v=()=>n.editor.liveSync?`\x1B[32m✓ Enabled\x1B[0m`:`\x1B[31m✗ Disabled\x1B[0m`;_.listen(p,()=>{console.log(`
|
|
2
2
|
\x1b[1;90mINTLAYER v${c.default.version}\x1b[0m
|
|
3
3
|
|
|
4
4
|
Live server running at: \x1b[90m${m}\x1b[0m
|
|
5
|
-
- Backend URL: \x1b[90m${
|
|
5
|
+
- Backend URL: \x1b[90m${n.editor.backendURL??`-`}\x1b[0m
|
|
6
6
|
- Live sync: ${v()}
|
|
7
7
|
- Parallel process: ${e?.with?`\x1b[90m${Array.isArray(e.with)?e.with.join(` `):e.with}\x1b[0m`:`-`}
|
|
8
|
-
- Access key: ${
|
|
8
|
+
- Access key: ${n.editor.clientId??`-`}
|
|
9
9
|
`)});let y=()=>{g&&(f(`Closing SSE connection...`),g.cleanup()),h&&h.kill(),_.close(()=>{f(`Live sync server stopped`),process.exit(0)})};process.on(`SIGINT`,y),process.on(`SIGTERM`,y),process.on(`exit`,y)};exports.liveSync=f;
|
|
10
10
|
//# sourceMappingURL=liveSync.cjs.map
|
package/dist/cjs/pull.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./utils/checkAccess.cjs`),t=require(`./push/pullLog.cjs`);let n=require(`node:fs`),r=require(`node:path`),i=require(`@intlayer/chokidar/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);const e=require(`./utils/checkAccess.cjs`),t=require(`./push/pullLog.cjs`);let n=require(`node:fs`),r=require(`node:path`),i=require(`@intlayer/chokidar/build`),a=require(`@intlayer/chokidar/cli`),o=require(`@intlayer/chokidar/utils`),s=require(`@intlayer/config/logger`),c=require(`@intlayer/config/node`),l=require(`@intlayer/unmerged-dictionaries-entry`),u=require(`@intlayer/api`),d=require(`@intlayer/config/utils`);const f=async f=>{let p=(0,s.getAppLogger)(f?.configOptions?.override);try{let m=(0,c.getConfiguration)(f?.configOptions);if((0,a.logConfigDetails)(f?.configOptions),!await e.checkCMSAuth(m))return;let h=(0,u.getIntlayerAPIProxy)(void 0,m),g=(0,l.getUnmergedDictionaries)(m),_=await h.dictionary.getDictionariesUpdateTimestamp();if(!_.data)throw Error(`No distant dictionaries found`);let v=_.data;f?.dictionaries&&(v=Object.fromEntries(Object.entries(v).filter(([e])=>f.dictionaries?.includes(e)))),v=Object.fromEntries(Object.entries(v).filter(([e])=>{let t=g[e]?.[0]?.location??m.dictionary?.location??`remote`;return t===`remote`||t===`hybrid`}));let y=(0,r.join)(m.system.mainDir,`remote_dictionaries.cjs`),b=m.build?.require??(0,d.getProjectRequire)(),x=(0,n.existsSync)(y)?b(y):{},S=Object.entries(v),C=S.filter(([e,t])=>{if(!t)return!0;let n=typeof t==`object`?t.updatedAt:t,r=x[e];if(!r)return!0;let i=r?.updatedAt,a=typeof i==`number`?i:i?new Date(i).getTime():void 0;return typeof a==`number`?n>a:!0}).map(([e])=>e),w=S.filter(([e,t])=>{let n=typeof t==`object`?t.updatedAt:t,r=x[e]?.updatedAt,i=typeof r==`number`?r:r?new Date(r).getTime():void 0;return typeof i==`number`&&typeof n==`number`&&i>=n}).map(([e])=>e);if(S.length===0){p(`No dictionaries to fetch`,{level:`error`});return}p(`Fetching dictionaries:`);let T=[...w.map(e=>({dictionaryKey:e,status:`imported`})),...C.map(e=>({dictionaryKey:e,status:`pending`}))],E=new t.PullLogger;E.update(T.map(e=>({dictionaryKey:e.dictionaryKey,status:e.status})));let D=[];await(0,o.parallelize)(T,async e=>{let t=e.status===`imported`||e.status===`up-to-date`;t||(e.status=`fetching`,E.update([{dictionaryKey:e.dictionaryKey,status:`fetching`}]));try{let n;if(t&&(n=x[e.dictionaryKey]),n||=(await h.dictionary.getDictionary(e.dictionaryKey)).data,!n)throw Error(`Dictionary ${e.dictionaryKey} not found on remote`);let r=g[e.dictionaryKey]?.find(e=>e.location===`hybrid`);r&&(n={...n,location:`hybrid`,filePath:r.filePath,localId:r.localId});let{status:a}=await(0,i.writeContentDeclaration)(n,m,f);e.status=a,E.update([{dictionaryKey:e.dictionaryKey,status:a}]),D.push(n)}catch(t){e.status=`error`,e.error=t,e.errorMessage=`Error fetching dictionary ${e.dictionaryKey}: ${t}`,E.update([{dictionaryKey:e.dictionaryKey,status:`error`}])}},5),E.finish();let O=e=>{switch(e){case`fetched`:case`imported`:case`updated`:case`up-to-date`:case`reimported in JSON`:case`new content file`:return`✔`;case`error`:return`✖`;default:return`⏲`}},k=e=>{switch(e){case`fetched`:case`imported`:case`updated`:case`up-to-date`:return s.ANSIColors.GREEN;case`reimported in JSON`:case`new content file`:return s.ANSIColors.YELLOW;case`error`:return s.ANSIColors.RED;default:return s.ANSIColors.BLUE}};for(let e of T){let t=O(e.status),n=k(e.status);p(` - ${e.dictionaryKey} ${s.ANSIColors.GREY}[${n}${t} ${e.status}${s.ANSIColors.GREY}]${s.ANSIColors.RESET}`)}for(let e of T)e.errorMessage&&p(e.errorMessage,{level:`error`})}catch(e){p(e,{level:`error`})}};exports.pull=f;
|
|
2
2
|
//# sourceMappingURL=pull.cjs.map
|
package/dist/cjs/push/push.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/checkAccess.cjs`),n=require(`../pushLog.cjs`);let r=require(`node:path`),i=require(`@intlayer/chokidar/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/checkAccess.cjs`),n=require(`../pushLog.cjs`);let r=require(`node:path`),i=require(`@intlayer/chokidar/build`),a=require(`@intlayer/chokidar/cli`),o=require(`@intlayer/chokidar/utils`),s=require(`@intlayer/config/logger`),c=require(`@intlayer/config/node`),l=require(`@intlayer/unmerged-dictionaries-entry`),u=require(`@intlayer/api`),d=require(`node:fs/promises`);d=e.__toESM(d);const f={pushed:{icon:`✔`,color:s.ANSIColors.GREEN},modified:{icon:`✔`,color:s.ANSIColors.GREEN},error:{icon:`✖`,color:s.ANSIColors.RED},default:{icon:`⏲`,color:s.ANSIColors.BLUE}},p=e=>f[e]??f.default,m=async e=>{let d=(0,c.getConfiguration)(e?.configOptions);(0,a.logConfigDetails)(e?.configOptions);let f=(0,s.getAppLogger)(d);e?.build===!0?await(0,i.prepareIntlayer)(d,{forceRun:!0}):e?.build===void 0&&await(0,i.prepareIntlayer)(d);try{if(!await t.checkCMSAuth(d))return;let c=(0,u.getIntlayerAPIProxy)(void 0,d),m=(0,l.getUnmergedDictionaries)(d),g=Object.values(m).flat(),_=Array.from(new Set(g.map(e=>e.location).filter(e=>e&&![`remote`,`local`,`hybrid`].includes(e)))),v=[];if(_.length>0){let{multiselect:e,confirm:t,isCancel:n}=await import(`@clack/prompts`);if(_.length===1){let e=await t({message:`Do you want to push dictionaries with custom location ${(0,s.colorize)(_[0],s.ANSIColors.BLUE,s.ANSIColors.RESET)}?`,initialValue:!1});if(n(e))return;e&&(v=[_[0]])}else{let t=await e({message:`Select custom locations to push:`,options:_.map(e=>({value:e,label:e})),required:!1});if(n(t))return;v=t}}let y=g.filter(e=>{let t=e.location??d.dictionary?.location??`local`;return t===`remote`||t===`hybrid`||v.includes(t)});if(y.length===0){f(`No dictionaries found to push. Only dictionaries with location ${(0,s.colorize)(`remote`,s.ANSIColors.BLUE,s.ANSIColors.RESET)}, ${(0,s.colorize)(`hybrid`,s.ANSIColors.BLUE,s.ANSIColors.RESET)} or selected custom locations are pushed.`,{level:`warn`}),f(`You can set the location in your dictionary file (e.g. ${(0,s.colorize)(`{ key: 'my-key', location: 'hybrid', ... }`,s.ANSIColors.BLUE,s.ANSIColors.RESET)} or globally in your intlayer.config.ts file (e.g. ${(0,s.colorize)(`{ dictionary: { location: 'hybrid' } }`,s.ANSIColors.BLUE,s.ANSIColors.RESET)}).`,{level:`info`});return}let b=Object.keys(m);if(e?.dictionaries){let t=e.dictionaries.filter(e=>!b.includes(e));t.length>0&&f(`The following dictionaries do not exist: ${t.join(`, `)} and have been ignored.`,{level:`error`}),y=y.filter(t=>e.dictionaries?.includes(t.key))}if(e?.gitOptions){let t=await(0,a.listGitFiles)(e.gitOptions);y=y.filter(e=>t.includes((0,r.join)(d.system.baseDir,e.filePath??``)))}if(y.length===0){f(`No local dictionaries found`,{level:`error`});return}f(`Pushing dictionaries:`);let x=y.map(e=>({dictionary:e,status:`pending`})),S=new n.PushLogger;S.update(x.map(e=>({dictionaryKey:e.dictionary.key,status:`pending`})));let C=[];await(0,o.parallelize)(x,async e=>{e.status=`pushing`,S.update([{dictionaryKey:e.dictionary.key,status:`pushing`}]);try{let t=await c.dictionary.pushDictionaries([e.dictionary]),n=t.data?.updatedDictionaries??[],r=t.data?.newDictionaries??[],a=[...n,...r];for(let e of a){let t=m[e.key]?.find(t=>t.localId===e.localId);t&&await(0,i.writeContentDeclaration)({...t,id:e.id},d)}n.some(t=>t.key===e.dictionary.key)?(e.status=`modified`,C.push(e.dictionary),S.update([{dictionaryKey:e.dictionary.key,status:`modified`}])):r.some(t=>t.key===e.dictionary.key)?(e.status=`pushed`,C.push(e.dictionary),S.update([{dictionaryKey:e.dictionary.key,status:`pushed`}])):e.status=`unknown`}catch(t){e.status=`error`,e.error=t,e.errorMessage=`Error pushing dictionary ${e.dictionary.key}: ${t}`,S.update([{dictionaryKey:e.dictionary.key,status:`error`}])}},5),S.finish();for(let e of x){let{icon:t,color:n}=p(e.status);f(` - ${(0,s.colorizeKey)(e.dictionary.key)} ${s.ANSIColors.GREY}[${n}${t} ${e.status}${s.ANSIColors.GREY}]${s.ANSIColors.RESET}`)}for(let e of x)e.errorMessage&&f(e.errorMessage,{level:`error`});let w=e?.deleteLocaleDictionary,T=e?.keepLocaleDictionary;if(w&&T)throw Error(`Cannot specify both --deleteLocaleDictionary and --keepLocaleDictionary options.`);if(w)await h(C,e);else if(!T){let t=C.filter(e=>e.location===`remote`),n=t.map(e=>e.key);if(t.length>0){let{confirm:r,isCancel:i}=await import(`@clack/prompts`),a=await r({message:`Do you want to delete the local dictionaries that were successfully pushed? ${(0,s.colorize)(`(Dictionaries:`,s.ANSIColors.GREY,s.ANSIColors.RESET)} ${(0,s.colorizeKey)(n)}${(0,s.colorize)(`)`,s.ANSIColors.GREY,s.ANSIColors.RESET)}`,initialValue:!1});if(i(a))return;a&&await h(t,e)}}}catch(e){f(e,{level:`error`})}},h=async(e,t)=>{let n=(0,s.getAppLogger)((0,c.getConfiguration)(t?.configOptions)),r=new Set;for(let t of e){let{filePath:e}=t;if(!e){n(`Dictionary ${(0,s.colorizeKey)(t.key)} does not have a file path`,{level:`error`});continue}r.add(e)}for(let e of r)try{let t=await d.lstat(e);t.isFile()?(await d.unlink(e),n(`Deleted file ${(0,o.formatPath)(e)}`,{})):t.isDirectory()?n(`Path is a directory ${(0,o.formatPath)(e)}, skipping.`,{}):n(`Unknown file type for ${(0,o.formatPath)(e)}, skipping.`,{})}catch(t){n(`Error deleting ${(0,o.formatPath)(e)}: ${t}`,{level:`error`})}};exports.push=m;
|
|
2
2
|
//# sourceMappingURL=push.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/setupAI.cjs`),n=require(`../utils/checkFileModifiedRange.cjs`),r=require(`../utils/getOutputFilePath.cjs`),i=require(`./reviewDocBlockAware.cjs`);let a=require(`node:fs`),o=require(`node:path`),s=require(`@intlayer/chokidar/cli`),c=require(`@intlayer/config/logger`),
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/setupAI.cjs`),n=require(`../utils/checkFileModifiedRange.cjs`),r=require(`../utils/getOutputFilePath.cjs`),i=require(`./reviewDocBlockAware.cjs`);let a=require(`node:fs`),o=require(`node:path`),s=require(`@intlayer/chokidar/cli`),c=require(`@intlayer/chokidar/utils`),l=require(`@intlayer/config/logger`),u=require(`@intlayer/config/node`),d=require(`fast-glob`);d=e.__toESM(d);const f=async({docPattern:e,locales:f,excludedGlobPattern:p,baseLocale:m,aiOptions:h,nbSimultaneousFileProcessed:g,configOptions:_,customInstructions:v,skipIfModifiedBefore:y,skipIfModifiedAfter:b,skipIfExists:x,gitOptions:S})=>{let C=(0,u.getConfiguration)(_);(0,s.logConfigDetails)(_);let w=(0,l.getAppLogger)(C),T=await t.setupAI(C,h);if(!T?.hasAIAccess)return;let{aiClient:E,aiConfig:D}=T;g&&g>10&&(w(`Warning: nbSimultaneousFileProcessed is set to ${g}, which is greater than 10. Setting it to 10.`),g=10);let O=await(0,d.default)(e,{ignore:p});if(S){let e=await(0,s.listGitFiles)(S);e&&(O=O.filter(t=>e.some(e=>(0,o.join)(process.cwd(),t)===e)))}w(`Base locale is ${(0,c.formatLocale)(m)}`),w(`Reviewing ${(0,l.colorizeNumber)(f.length)} locales: [ ${(0,c.formatLocale)(f)} ]`),w(`Reviewing ${(0,l.colorizeNumber)(O.length)} files:`),w(O.map(e=>` - ${(0,c.formatPath)(e)}\n`)),await(0,c.parallelize)(O.flatMap(e=>f.map(t=>async()=>{w(`Reviewing file: ${(0,c.formatPath)(e)} to ${(0,c.formatLocale)(t)}`);let u=(0,o.join)(C.system.baseDir,e),d=r.getOutputFilePath(u,t,m);if(x&&(0,a.existsSync)(d)){let e=(0,o.relative)(C.system.baseDir,d);w(`${(0,l.colorize)(`⊘`,l.ANSIColors.YELLOW)} File ${(0,c.formatPath)(e)} already exists, skipping.`);return}if((0,a.existsSync)(d)){let e=n.checkFileModifiedRange(d,{skipIfModifiedBefore:y,skipIfModifiedAfter:b});if(e.isSkipped){w(e.message);return}}else (y||b)&&w(`${(0,l.colorize)(`!`,l.ANSIColors.YELLOW)} File ${(0,c.formatPath)(d)} does not exist, skipping modification date check.`);let f;if(S){let e=await(0,s.listGitLines)(u,S);w(`Git changed lines: ${e.join(`, `)}`),f=e}await i.reviewFileBlockAware(u,d,t,m,h,_,v,f,E,D)})),e=>e(),g??3)};exports.reviewDoc=f;
|
|
2
2
|
//# sourceMappingURL=reviewDoc.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reviewDoc.cjs","names":["setupAI","getOutputFilePath","ANSIColors","checkFileModifiedRange","reviewFileBlockAware"],"sources":["../../../src/reviewDoc/reviewDoc.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { join, relative } from 'node:path';\nimport type { AIOptions } from '@intlayer/api';\nimport {\n type ListGitFilesOptions,\n listGitFiles,\n listGitLines,\n logConfigDetails,\n} from '@intlayer/chokidar/cli';\nimport {\n formatLocale,\n formatPath,\n parallelize,\n} from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizeNumber,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport fg from 'fast-glob';\nimport { checkFileModifiedRange } from '../utils/checkFileModifiedRange';\nimport { getOutputFilePath } from '../utils/getOutputFilePath';\nimport { setupAI } from '../utils/setupAI';\nimport { reviewFileBlockAware } from './reviewDocBlockAware';\n\ntype ReviewDocOptions = {\n docPattern: string[];\n locales: Locale[];\n excludedGlobPattern: string[];\n baseLocale: Locale;\n aiOptions?: AIOptions;\n nbSimultaneousFileProcessed?: number;\n configOptions?: GetConfigurationOptions;\n customInstructions?: string;\n skipIfModifiedBefore?: number | string | Date;\n skipIfModifiedAfter?: number | string | Date;\n skipIfExists?: boolean;\n gitOptions?: ListGitFilesOptions;\n};\n\n/**\n * Main audit function: scans all .md files in \"en/\" (unless you specified DOC_LIST),\n * then audits them to each locale in LOCALE_LIST.\n */\nexport const reviewDoc = async ({\n docPattern,\n locales,\n excludedGlobPattern,\n baseLocale,\n aiOptions,\n nbSimultaneousFileProcessed,\n configOptions,\n customInstructions,\n skipIfModifiedBefore,\n skipIfModifiedAfter,\n skipIfExists,\n gitOptions,\n}: ReviewDocOptions) => {\n const configuration = getConfiguration(configOptions);\n logConfigDetails(configOptions);\n\n const appLogger = getAppLogger(configuration);\n\n const aiResult = await setupAI(configuration, aiOptions);\n\n if (!aiResult?.hasAIAccess) return;\n\n const { aiClient, aiConfig } = aiResult;\n\n if (nbSimultaneousFileProcessed && nbSimultaneousFileProcessed > 10) {\n appLogger(\n `Warning: nbSimultaneousFileProcessed is set to ${nbSimultaneousFileProcessed}, which is greater than 10. Setting it to 10.`\n );\n nbSimultaneousFileProcessed = 10; // Limit the number of simultaneous file processed to 10\n }\n\n let docList: string[] = await fg(docPattern, {\n ignore: excludedGlobPattern,\n });\n\n if (gitOptions) {\n const gitChangedFiles = await listGitFiles(gitOptions);\n\n if (gitChangedFiles) {\n // Convert dictionary file paths to be relative to git root for comparison\n\n // Filter dictionaries based on git changed files\n docList = docList.filter((path) =>\n gitChangedFiles.some((gitFile) => join(process.cwd(), path) === gitFile)\n );\n }\n }\n\n // OAuth handled by API proxy internally\n\n appLogger(`Base locale is ${formatLocale(baseLocale)}`);\n appLogger(\n `Reviewing ${colorizeNumber(locales.length)} locales: [ ${formatLocale(locales)} ]`\n );\n\n appLogger(`Reviewing ${colorizeNumber(docList.length)} files:`);\n appLogger(docList.map((path) => ` - ${formatPath(path)}\\n`));\n\n // Create all tasks to be processed\n const allTasks = docList.flatMap((docPath) =>\n locales.map((locale) => async () => {\n appLogger(\n `Reviewing file: ${formatPath(docPath)} to ${formatLocale(locale)}`\n );\n\n const absoluteBaseFilePath = join(configuration.system.baseDir, docPath);\n const outputFilePath = getOutputFilePath(\n absoluteBaseFilePath,\n locale,\n baseLocale\n );\n\n // Skip if file exists and skipIfExists option is enabled\n if (skipIfExists && existsSync(outputFilePath)) {\n const relativePath = relative(\n configuration.system.baseDir,\n outputFilePath\n );\n appLogger(\n `${colorize('⊘', ANSIColors.YELLOW)} File ${formatPath(relativePath)} already exists, skipping.`\n );\n return;\n }\n\n // Check modification range only if the file exists\n if (existsSync(outputFilePath)) {\n const fileModificationData = checkFileModifiedRange(outputFilePath, {\n skipIfModifiedBefore,\n skipIfModifiedAfter,\n });\n\n if (fileModificationData.isSkipped) {\n appLogger(fileModificationData.message);\n return;\n }\n } else if (skipIfModifiedBefore || skipIfModifiedAfter) {\n // Log if we intended to check modification time but couldn't because the file doesn't exist\n appLogger(\n `${colorize('!', ANSIColors.YELLOW)} File ${formatPath(outputFilePath)} does not exist, skipping modification date check.`\n );\n }\n\n let changedLines: number[] | undefined;\n // FIXED: Enable git optimization that was previously commented out\n if (gitOptions) {\n const gitChangedLines = await listGitLines(\n absoluteBaseFilePath,\n gitOptions\n );\n\n appLogger(`Git changed lines: ${gitChangedLines.join(', ')}`);\n changedLines = gitChangedLines;\n }\n\n await reviewFileBlockAware(\n absoluteBaseFilePath,\n outputFilePath,\n locale as Locale,\n baseLocale,\n aiOptions,\n configOptions,\n customInstructions,\n changedLines,\n aiClient,\n aiConfig\n );\n })\n );\n\n await parallelize(\n allTasks,\n (task) => task(),\n nbSimultaneousFileProcessed ?? 3\n );\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"reviewDoc.cjs","names":["setupAI","getOutputFilePath","ANSIColors","checkFileModifiedRange","reviewFileBlockAware"],"sources":["../../../src/reviewDoc/reviewDoc.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { join, relative } from 'node:path';\nimport type { AIOptions } from '@intlayer/api';\nimport {\n type ListGitFilesOptions,\n listGitFiles,\n listGitLines,\n logConfigDetails,\n} from '@intlayer/chokidar/cli';\nimport {\n formatLocale,\n formatPath,\n parallelize,\n} from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizeNumber,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport fg from 'fast-glob';\nimport { checkFileModifiedRange } from '../utils/checkFileModifiedRange';\nimport { getOutputFilePath } from '../utils/getOutputFilePath';\nimport { setupAI } from '../utils/setupAI';\nimport { reviewFileBlockAware } from './reviewDocBlockAware';\n\ntype ReviewDocOptions = {\n docPattern: string[];\n locales: Locale[];\n excludedGlobPattern: string[];\n baseLocale: Locale;\n aiOptions?: AIOptions;\n nbSimultaneousFileProcessed?: number;\n configOptions?: GetConfigurationOptions;\n customInstructions?: string;\n skipIfModifiedBefore?: number | string | Date;\n skipIfModifiedAfter?: number | string | Date;\n skipIfExists?: boolean;\n gitOptions?: ListGitFilesOptions;\n};\n\n/**\n * Main audit function: scans all .md files in \"en/\" (unless you specified DOC_LIST),\n * then audits them to each locale in LOCALE_LIST.\n */\nexport const reviewDoc = async ({\n docPattern,\n locales,\n excludedGlobPattern,\n baseLocale,\n aiOptions,\n nbSimultaneousFileProcessed,\n configOptions,\n customInstructions,\n skipIfModifiedBefore,\n skipIfModifiedAfter,\n skipIfExists,\n gitOptions,\n}: ReviewDocOptions) => {\n const configuration = getConfiguration(configOptions);\n logConfigDetails(configOptions);\n\n const appLogger = getAppLogger(configuration);\n\n const aiResult = await setupAI(configuration, aiOptions);\n\n if (!aiResult?.hasAIAccess) return;\n\n const { aiClient, aiConfig } = aiResult;\n\n if (nbSimultaneousFileProcessed && nbSimultaneousFileProcessed > 10) {\n appLogger(\n `Warning: nbSimultaneousFileProcessed is set to ${nbSimultaneousFileProcessed}, which is greater than 10. Setting it to 10.`\n );\n nbSimultaneousFileProcessed = 10; // Limit the number of simultaneous file processed to 10\n }\n\n let docList: string[] = await fg(docPattern, {\n ignore: excludedGlobPattern,\n });\n\n if (gitOptions) {\n const gitChangedFiles = await listGitFiles(gitOptions);\n\n if (gitChangedFiles) {\n // Convert dictionary file paths to be relative to git root for comparison\n\n // Filter dictionaries based on git changed files\n docList = docList.filter((path) =>\n gitChangedFiles.some((gitFile) => join(process.cwd(), path) === gitFile)\n );\n }\n }\n\n // OAuth handled by API proxy internally\n\n appLogger(`Base locale is ${formatLocale(baseLocale)}`);\n appLogger(\n `Reviewing ${colorizeNumber(locales.length)} locales: [ ${formatLocale(locales)} ]`\n );\n\n appLogger(`Reviewing ${colorizeNumber(docList.length)} files:`);\n appLogger(docList.map((path) => ` - ${formatPath(path)}\\n`));\n\n // Create all tasks to be processed\n const allTasks = docList.flatMap((docPath) =>\n locales.map((locale) => async () => {\n appLogger(\n `Reviewing file: ${formatPath(docPath)} to ${formatLocale(locale)}`\n );\n\n const absoluteBaseFilePath = join(configuration.system.baseDir, docPath);\n const outputFilePath = getOutputFilePath(\n absoluteBaseFilePath,\n locale,\n baseLocale\n );\n\n // Skip if file exists and skipIfExists option is enabled\n if (skipIfExists && existsSync(outputFilePath)) {\n const relativePath = relative(\n configuration.system.baseDir,\n outputFilePath\n );\n appLogger(\n `${colorize('⊘', ANSIColors.YELLOW)} File ${formatPath(relativePath)} already exists, skipping.`\n );\n return;\n }\n\n // Check modification range only if the file exists\n if (existsSync(outputFilePath)) {\n const fileModificationData = checkFileModifiedRange(outputFilePath, {\n skipIfModifiedBefore,\n skipIfModifiedAfter,\n });\n\n if (fileModificationData.isSkipped) {\n appLogger(fileModificationData.message);\n return;\n }\n } else if (skipIfModifiedBefore || skipIfModifiedAfter) {\n // Log if we intended to check modification time but couldn't because the file doesn't exist\n appLogger(\n `${colorize('!', ANSIColors.YELLOW)} File ${formatPath(outputFilePath)} does not exist, skipping modification date check.`\n );\n }\n\n let changedLines: number[] | undefined;\n // FIXED: Enable git optimization that was previously commented out\n if (gitOptions) {\n const gitChangedLines = await listGitLines(\n absoluteBaseFilePath,\n gitOptions\n );\n\n appLogger(`Git changed lines: ${gitChangedLines.join(', ')}`);\n changedLines = gitChangedLines;\n }\n\n await reviewFileBlockAware(\n absoluteBaseFilePath,\n outputFilePath,\n locale as Locale,\n baseLocale,\n aiOptions,\n configOptions,\n customInstructions,\n changedLines,\n aiClient,\n aiConfig\n );\n })\n );\n\n await parallelize(\n allTasks,\n (task) => task(),\n nbSimultaneousFileProcessed ?? 3\n );\n};\n"],"mappings":"sgBAkDA,MAAa,EAAY,MAAO,CAC9B,aACA,UACA,sBACA,aACA,YACA,8BACA,gBACA,qBACA,uBACA,sBACA,eACA,gBACsB,CACtB,IAAM,GAAA,EAAA,EAAA,kBAAiC,EAAc,EACrD,EAAA,EAAA,kBAAiB,EAAc,CAE/B,IAAM,GAAA,EAAA,EAAA,cAAyB,EAAc,CAEvC,EAAW,MAAMA,EAAAA,QAAQ,EAAe,EAAU,CAExD,GAAI,CAAC,GAAU,YAAa,OAE5B,GAAM,CAAE,WAAU,YAAa,EAE3B,GAA+B,EAA8B,KAC/D,EACE,kDAAkD,EAA4B,+CAC/E,CACD,EAA8B,IAGhC,IAAI,EAAoB,MAAA,EAAA,EAAA,SAAS,EAAY,CAC3C,OAAQ,EACT,CAAC,CAEF,GAAI,EAAY,CACd,IAAM,EAAkB,MAAA,EAAA,EAAA,cAAmB,EAAW,CAElD,IAIF,EAAU,EAAQ,OAAQ,GACxB,EAAgB,KAAM,IAAA,EAAA,EAAA,MAAiB,QAAQ,KAAK,CAAE,EAAK,GAAK,EAAQ,CACzE,EAML,EAAU,mBAAA,EAAA,EAAA,cAA+B,EAAW,GAAG,CACvD,EACE,cAAA,EAAA,EAAA,gBAA4B,EAAQ,OAAO,CAAC,eAAA,EAAA,EAAA,cAA2B,EAAQ,CAAC,IACjF,CAED,EAAU,cAAA,EAAA,EAAA,gBAA4B,EAAQ,OAAO,CAAC,SAAS,CAC/D,EAAU,EAAQ,IAAK,GAAS,OAAA,EAAA,EAAA,YAAiB,EAAK,CAAC,IAAI,CAAC,CAyE5D,MAAA,EAAA,EAAA,aAtEiB,EAAQ,QAAS,GAChC,EAAQ,IAAK,GAAW,SAAY,CAClC,EACE,oBAAA,EAAA,EAAA,YAA8B,EAAQ,CAAC,OAAA,EAAA,EAAA,cAAmB,EAAO,GAClE,CAED,IAAM,GAAA,EAAA,EAAA,MAA4B,EAAc,OAAO,QAAS,EAAQ,CAClE,EAAiBC,EAAAA,kBACrB,EACA,EACA,EACD,CAGD,GAAI,IAAA,EAAA,EAAA,YAA2B,EAAe,CAAE,CAC9C,IAAM,GAAA,EAAA,EAAA,UACJ,EAAc,OAAO,QACrB,EACD,CACD,EACE,IAAA,EAAA,EAAA,UAAY,IAAKC,EAAAA,WAAW,OAAO,CAAC,SAAA,EAAA,EAAA,YAAmB,EAAa,CAAC,4BACtE,CACD,OAIF,IAAA,EAAA,EAAA,YAAe,EAAe,CAAE,CAC9B,IAAM,EAAuBC,EAAAA,uBAAuB,EAAgB,CAClE,uBACA,sBACD,CAAC,CAEF,GAAI,EAAqB,UAAW,CAClC,EAAU,EAAqB,QAAQ,CACvC,cAEO,GAAwB,IAEjC,EACE,IAAA,EAAA,EAAA,UAAY,IAAKD,EAAAA,WAAW,OAAO,CAAC,SAAA,EAAA,EAAA,YAAmB,EAAe,CAAC,oDACxE,CAGH,IAAI,EAEJ,GAAI,EAAY,CACd,IAAM,EAAkB,MAAA,EAAA,EAAA,cACtB,EACA,EACD,CAED,EAAU,sBAAsB,EAAgB,KAAK,KAAK,GAAG,CAC7D,EAAe,EAGjB,MAAME,EAAAA,qBACJ,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACD,EACD,CACH,CAIE,GAAS,GAAM,CAChB,GAA+B,EAChC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../_virtual/_utils_asset.cjs`),n=require(`../translateDoc/validation.cjs`),r=require(`../translation-alignment/rebuildDocument.cjs`),i=require(`../translation-alignment/pipeline.cjs`),a=require(`../utils/chunkInference.cjs`),o=require(`../utils/fixChunkStartEndChars.cjs`);let s=require(`node:fs`),c=require(`node:path`),l=require(`@intlayer/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../_virtual/_utils_asset.cjs`),n=require(`../translateDoc/validation.cjs`),r=require(`../translation-alignment/rebuildDocument.cjs`),i=require(`../translation-alignment/pipeline.cjs`),a=require(`../utils/chunkInference.cjs`),o=require(`../utils/fixChunkStartEndChars.cjs`);let s=require(`node:fs`),c=require(`node:path`),l=require(`@intlayer/chokidar/utils`),u=require(`@intlayer/config/logger`),d=require(`@intlayer/config/node`),f=require(`@intlayer/config/utils`),p=require(`node:fs/promises`),m=require(`@intlayer/core/localization`),h=require(`@intlayer/types/locales`);h=e.__toESM(h);const g=async(e,g,_,v,y,b,x,S,C,w)=>{let T=(0,d.getConfiguration)(b),E=(0,u.getAppLogger)(T),D=await(0,p.readFile)(e,`utf-8`),O=await(0,p.readFile)(g,`utf-8`).catch(()=>``),k=t.readAsset(`./prompts/REVIEW_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${(0,l.formatLocale)(_,!1)}`).replaceAll(`{{baseLocaleName}}`,`${(0,l.formatLocale)(v,!1)}`).replace(`{{applicationContext}}`,y?.applicationContext??`-`).replace(`{{customInstructions}}`,x??`-`),A=[(0,u.colon)(`${u.ANSIColors.GREY_DARK}[${(0,l.formatPath)(e)}${u.ANSIColors.GREY_DARK}] `,{colSize:40}),`→ ${u.ANSIColors.RESET}`].join(``),j=[(0,u.colon)(`${u.ANSIColors.GREY_DARK}[${(0,l.formatPath)(e)}${u.ANSIColors.GREY_DARK}][${(0,l.formatLocale)(_)}${u.ANSIColors.GREY_DARK}] `,{colSize:40}),`→ ${u.ANSIColors.RESET}`].join(``),{englishBlocks:M,frenchBlocks:N,plan:P,segmentsToReview:F}=i.buildAlignmentPlan({englishText:D,frenchText:O,changedLines:S});if(E(`${A}Block-aware alignment complete. Total blocks: EN=${(0,u.colorizeNumber)(M.length)}, FR=${(0,u.colorizeNumber)(N.length)}`),E(`${A}Actions: reuse=${(0,u.colorizeNumber)(P.actions.filter(e=>e.kind===`reuse`).length)}, review=${(0,u.colorizeNumber)(P.actions.filter(e=>e.kind===`review`).length)}, new=${(0,u.colorizeNumber)(P.actions.filter(e=>e.kind===`insert_new`).length)}, delete=${(0,u.colorizeNumber)(P.actions.filter(e=>e.kind===`delete`).length)}`),F.length===0){E(`${A}No segments need review, reusing existing translation`),(0,s.mkdirSync)((0,c.dirname)(g),{recursive:!0}),(0,s.writeFileSync)(g,r.mergeReviewedSegments(P,N,new Map)),E(`${(0,u.colorize)(`✔`,u.ANSIColors.GREEN)} File ${(0,l.formatPath)(g)} updated successfully (no changes needed).`);return}E(`${A}Segments to review: ${(0,u.colorizeNumber)(F.length)}`);let I=new Map;for(let e of F){let t=F.indexOf(e)+1,r=e.englishBlock,i=()=>`**BLOCK ${t} of ${F.length}** is the base block in ${(0,l.formatLocale)(v,!1)} as reference.\n///chunksStart///\n`+r.content+`///chunksEnd///`,s=()=>`**BLOCK ${t} of ${F.length}** is the current block to review in ${(0,l.formatLocale)(_,!1)}.\n///chunksStart///\n`+(e.frenchBlockText??``)+`///chunksEnd///`,c=await(0,f.retryManager)(async()=>{let e=await a.chunkInference([{role:`system`,content:k},{role:`system`,content:i()},{role:`system`,content:s()},{role:`system`,content:`The next user message will be the **BLOCK ${(0,u.colorizeNumber)(t)} of ${(0,u.colorizeNumber)(F.length)}** that should be translated in ${(0,m.getLocaleName)(_,h.ENGLISH)} (${_}).`},{role:`user`,content:r.content}],y,T,C,w);E(`${j}${(0,u.colorizeNumber)(e.tokenUsed)} tokens used - Block ${(0,u.colorizeNumber)(t)} of ${(0,u.colorizeNumber)(F.length)}`);let c=n.sanitizeChunk(e?.fileContent,r.content);if(c=o.fixChunkStartEndChars(c,r.content),!n.validateTranslation(r.content,c,E))throw Error(`Validation failed for chunk (structure or length mismatch). Retrying...`);return c})();I.set(e.actionIndex,c)}let L=r.mergeReviewedSegments(P,N,I);(0,s.mkdirSync)((0,c.dirname)(g),{recursive:!0}),(0,s.writeFileSync)(g,L),E(`${(0,u.colorize)(`✔`,u.ANSIColors.GREEN)} File ${(0,l.formatPath)(g)} created/updated successfully.`)};exports.reviewFileBlockAware=g;
|
|
2
2
|
//# sourceMappingURL=reviewDocBlockAware.cjs.map
|
package/dist/cjs/test/test.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./listMissingTranslations.cjs`);let t=require(`@intlayer/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`./listMissingTranslations.cjs`);let t=require(`@intlayer/chokidar/build`),n=require(`@intlayer/chokidar/utils`),r=require(`@intlayer/config/logger`),i=require(`@intlayer/config/node`);const a=async a=>{let o=(0,i.getConfiguration)(a?.configOptions),{locales:s,requiredLocales:c}=o.internationalization,l=(0,r.getAppLogger)(o);a?.build===!0?await(0,t.prepareIntlayer)(o,{forceRun:!0}):a?.build===void 0&&await(0,t.prepareIntlayer)(o);let u=e.listMissingTranslations(a?.configOptions),d=u.missingTranslations.map(e=>` - ${e.key}`).reduce((e,t)=>Math.max(e,t.length),0),f=u.missingTranslations.map(e=>(0,n.formatLocale)(e.locales,!1)).reduce((e,t)=>Math.max(e,t.length),0),p=u.missingTranslations.map(e=>[(0,r.colon)(` - ${(0,r.colorizeKey)(e.key)}`,{colSize:d,maxSize:40}),` - `,(0,r.colon)((0,n.formatLocale)(e.locales,r.ANSIColors.RED),{colSize:f,maxSize:40}),e.filePath?` - ${(0,n.formatPath)(e.filePath)}`:``,e.id?` - remote`:``].join(``));l(`Missing translations:`,{level:`info`}),p.forEach(e=>{l(e,{level:`info`})}),l(`Locales: ${(0,n.formatLocale)(s)}`),l(`Required locales: ${(0,n.formatLocale)(c??s)}`),l(`Missing locales: ${u.missingLocales.length===0?(0,r.colorize)(`-`,r.ANSIColors.GREEN):(0,n.formatLocale)(u.missingLocales,r.ANSIColors.RED)}`),l(`Missing required locales: ${u.missingRequiredLocales.length===0?(0,r.colorize)(`-`,r.ANSIColors.GREEN):(0,n.formatLocale)(u.missingRequiredLocales,r.ANSIColors.RED)}`),l(`Total missing locales: ${(0,r.colorizeNumber)(u.missingLocales.length,{one:r.ANSIColors.RED,other:r.ANSIColors.RED,zero:r.ANSIColors.GREEN})}`),l(`Total missing required locales: ${(0,r.colorizeNumber)(u.missingRequiredLocales.length,{one:r.ANSIColors.RED,other:r.ANSIColors.RED,zero:r.ANSIColors.GREEN})}`),u.missingRequiredLocales.length>0&&process.exit(1)};exports.testMissingTranslations=a;
|
|
2
2
|
//# sourceMappingURL=test.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/setupAI.cjs`),n=require(`../utils/checkFileModifiedRange.cjs`),r=require(`../utils/getOutputFilePath.cjs`),i=require(`./translateFile.cjs`);let a=require(`node:fs`),o=require(`node:path`),s=require(`@intlayer/chokidar/cli`),c=require(`@intlayer/config/logger`),
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../_virtual/_rolldown/runtime.cjs`),t=require(`../utils/setupAI.cjs`),n=require(`../utils/checkFileModifiedRange.cjs`),r=require(`../utils/getOutputFilePath.cjs`),i=require(`./translateFile.cjs`);let a=require(`node:fs`),o=require(`node:path`),s=require(`@intlayer/chokidar/cli`),c=require(`@intlayer/chokidar/utils`),l=require(`@intlayer/config/logger`),u=require(`@intlayer/config/node`),d=require(`fast-glob`);d=e.__toESM(d);let f=require(`node:perf_hooks`);const p=async({docPattern:e,locales:p,excludedGlobPattern:m,baseLocale:h,aiOptions:g,nbSimultaneousFileProcessed:_=20,configOptions:v,customInstructions:y,skipIfModifiedBefore:b,skipIfModifiedAfter:x,skipIfExists:S,gitOptions:C,flushStrategy:w=`incremental`})=>{let T=(0,u.getConfiguration)(v);(0,s.logConfigDetails)(v);let E=(0,l.getAppLogger)(T),D=_,O=(0,c.pLimit)(D),k=await(0,d.default)(e,{ignore:m}),A=await t.setupAI(T,g);if(!A?.hasAIAccess)return;let{aiClient:j,aiConfig:M}=A;if(C){let e=await(0,s.listGitFiles)(C);e&&(k=k.filter(t=>e.some(e=>(0,o.join)(process.cwd(),t)===e)))}let N=f.performance.now();E(`Translating ${(0,l.colorizeNumber)(k.length)} files to ${(0,l.colorizeNumber)(p.length)} locales. \nGlobal Concurrency: ${(0,l.colorizeNumber)(D)} chunks in parallel.`);let P={count:0,maxErrors:5,shouldStop:!1};await(0,c.parallelize)(k.flatMap(e=>p.map(t=>async()=>{if(P.shouldStop)return;let s=(0,o.join)(T.system.baseDir,e),c=r.getOutputFilePath(s,t,h);if(S&&(0,a.existsSync)(c))return;w===`incremental`&&!(0,a.existsSync)(c)&&((0,a.mkdirSync)((0,o.dirname)(c),{recursive:!0}),(0,a.writeFileSync)(c,``));let l=n.checkFileModifiedRange(c,{skipIfModifiedBefore:b,skipIfModifiedAfter:x});if(l.isSkipped){E(l.message);return}await i.translateFile({baseFilePath:s,outputFilePath:c,locale:t,baseLocale:h,configuration:T,errorState:P,aiOptions:g,customInstructions:y,aiClient:j,aiConfig:M,flushStrategy:w,limit:O})})),e=>e(),50);let F=((f.performance.now()-N)/1e3).toFixed(2);P.count>0?E(`Finished with ${P.count} errors in ${F}s.`):E(`${(0,l.colorize)(`✔`,l.ANSIColors.GREEN)} Batch completed successfully in ${(0,l.colorizeNumber)(F)}s.`)};exports.translateDoc=p;
|
|
2
2
|
//# sourceMappingURL=translateDoc.cjs.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../_virtual/_utils_asset.cjs`),t=require(`./validation.cjs`),n=require(`../utils/chunkInference.cjs`),r=require(`../utils/fixChunkStartEndChars.cjs`),i=require(`../utils/calculateChunks.cjs`);let a=require(`node:fs`),o=require(`node:path`),s=require(`@intlayer/
|
|
2
|
-
`)},{role:`user`,content:`>>> TARGET CHUNK START <<<\n${m}\n>>> TARGET CHUNK END <<<`}],v,g,b,x),a=t.sanitizeChunk(e?.fileContent,m);if(a=r.fixChunkStartEndChars(a,m),!t.validateTranslation(m,a,
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../_virtual/_rolldown/runtime.cjs`);const e=require(`../_virtual/_utils_asset.cjs`),t=require(`./validation.cjs`),n=require(`../utils/chunkInference.cjs`),r=require(`../utils/fixChunkStartEndChars.cjs`),i=require(`../utils/calculateChunks.cjs`);let a=require(`node:fs`),o=require(`node:path`),s=require(`@intlayer/chokidar/utils`),c=require(`@intlayer/config/logger`),l=require(`@intlayer/config/utils`),u=require(`node:fs/promises`),d=require(`node:perf_hooks`);const f=async({baseFilePath:f,outputFilePath:p,locale:m,baseLocale:h,configuration:g,errorState:_,aiOptions:v,customInstructions:y,aiClient:b,aiConfig:x,flushStrategy:S=`incremental`,onChunkReceive:C,limit:w})=>{if(_.shouldStop)return null;let T=(0,c.getAppLogger)(g,{config:{prefix:``}}),E=d.performance.now();try{let D=i.chunkText(await(0,u.readFile)(f,`utf-8`)),O=D.length,k=`${(0,c.colon)(`${c.ANSIColors.GREY_DARK}[${(0,s.formatPath)(f)}${c.ANSIColors.GREY_DARK}] `,{colSize:40})}${c.ANSIColors.RESET}`,A=`${(0,c.colon)(`${c.ANSIColors.GREY_DARK}[${(0,s.formatPath)(f)}${c.ANSIColors.GREY_DARK}][${(0,s.formatLocale)(m)}${c.ANSIColors.GREY_DARK}] `,{colSize:40})}${c.ANSIColors.RESET}`;T(`${k}Split into ${(0,c.colorizeNumber)(O)} chunks. Queuing...`);let j=e.readAsset(`./prompts/TRANSLATE_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${(0,s.formatLocale)(m,!1)}`).replaceAll(`{{baseLocaleName}}`,`${(0,s.formatLocale)(h,!1)}`).replace(`{{applicationContext}}`,v?.applicationContext??`-`).replace(`{{customInstructions}}`,y??`-`),M=Array(O).fill(``),N=w??(e=>e()),P=D.map((e,i)=>N(async()=>{if(_.shouldStop)return null;let s=(0,c.getAppLogger)(g,{config:{prefix:`${A} ${c.ANSIColors.GREY_DARK}[${i+1}/${O}] ${c.ANSIColors.RESET}`}}),u=d.performance.now(),f=i===0,m=e.content,h=()=>">>> CONTEXT: PREVIOUS SOURCE CONTENT <<<\n```\n"+(D[i-1]?.content??``)+"\n```\n>>> END PREVIOUS CONTEXT <<<",y=()=>">>> CONTEXT: NEXT CONTENT <<<\n```\n"+(D[i+1]?.content??``)+"\n```\n>>> END NEXT CONTEXT <<<";s(`Process started`);let{content:w,tokens:T}=await(0,l.retryManager)(async()=>{let e=await n.chunkInference([{role:`system`,content:j},...D[i+1]?[{role:`system`,content:y()}]:[],...f?[]:[{role:`system`,content:h()}],{role:`system`,content:[`You are translating TARGET CHUNK (${i+1}/${O}).`,`Translate ONLY the target chunk. Preserve frontmatter/code exactly.`].join(`
|
|
2
|
+
`)},{role:`user`,content:`>>> TARGET CHUNK START <<<\n${m}\n>>> TARGET CHUNK END <<<`}],v,g,b,x),a=t.sanitizeChunk(e?.fileContent,m);if(a=r.fixChunkStartEndChars(a,m),!t.validateTranslation(m,a,s))throw Error(`Validation failed for chunk ${i+1}/${O}`);return{content:a,tokens:e.tokenUsed}})(),E=(d.performance.now()-u).toFixed(0);if(M[i]=w,C&&C(w,i,O),S===`incremental`&&M.slice(0,i+1).every(e=>e&&e!==``)){let e=0;for(;e<O&&M[e]&&M[e]!==``;)e++;let t=M.slice(0,e).join(``);(0,a.mkdirSync)((0,o.dirname)(p),{recursive:!0}),(0,a.writeFileSync)(p,t)}s([`${(0,c.colorizeNumber)(T)} tokens used `,`${c.ANSIColors.GREY_DARK}in ${(0,c.colorizeNumber)(E)}ms${c.ANSIColors.RESET}`].join(``))}));await Promise.all(P);let F=M.join(``);(S===`end`||S===`incremental`)&&((0,a.mkdirSync)((0,o.dirname)(p),{recursive:!0}),(0,a.writeFileSync)(p,F));let I=((d.performance.now()-E)/1e3).toFixed(2),L=(0,o.relative)(g.system.baseDir,p);return T(`${(0,c.colorize)(`✔`,c.ANSIColors.GREEN)} File ${(0,s.formatPath)(L)} completed in ${(0,c.colorizeNumber)(I)}s.`),F}catch(e){_.count++;let t=e?.message??JSON.stringify(e);return T(`${(0,c.colorize)(`✖`,c.ANSIColors.RED)} Error: ${t}`),_.count>=_.maxErrors&&(_.shouldStop=!0),null}};exports.translateFile=f;
|
|
3
3
|
//# sourceMappingURL=translateFile.cjs.map
|
package/dist/cjs/watch.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`@intlayer/chokidar/cli`),t=require(`@intlayer/
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`@intlayer/chokidar/cli`),t=require(`@intlayer/chokidar/utils`),n=require(`@intlayer/config/logger`),r=require(`@intlayer/config/node`),i=require(`@intlayer/chokidar/watcher`);const a=async a=>{let o=(0,r.getConfiguration)(a?.configOptions);(0,e.logConfigDetails)(a?.configOptions);let s=(0,n.getAppLogger)(o),c;a?.with&&(c=(0,t.runParallel)(a.with),c.result.catch(()=>{process.exit(1)}));let l=(0,i.watch)({persistent:!0,skipPrepare:a?.skipPrepare??!1}),u=async()=>{process.off(`SIGINT`,u),process.off(`SIGTERM`,u),s(`Stopping Intlayer watcher...`);try{await l.close(),c&&`child`in c&&c.child?.kill(`SIGTERM`)}catch(e){console.error(`Error during shutdown:`,e)}finally{process.exit(0)}};process.on(`SIGINT`,u),process.on(`SIGTERM`,u)};exports.watchContentDeclaration=a;
|
|
2
2
|
//# sourceMappingURL=watch.cjs.map
|
package/dist/esm/build.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{logConfigDetails as e}from"@intlayer/chokidar/cli";import{
|
|
1
|
+
import{logConfigDetails as e}from"@intlayer/chokidar/cli";import{runParallel as t}from"@intlayer/chokidar/utils";import{getConfiguration as n}from"@intlayer/config/node";import{buildAndWatchIntlayer as r}from"@intlayer/chokidar/watcher";const i=async i=>{let a=n(i?.configOptions);e(i?.configOptions);let o=null;i?.with&&(o=t(i.with),o.result.catch(()=>{})),await r({persistent:i?.watch??!1,skipPrepare:i?.skipPrepare??!1,configuration:a}),!i?.watch&&o&&o.kill()};export{i as build};
|
|
2
2
|
//# sourceMappingURL=build.mjs.map
|
package/dist/esm/extract.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{existsSync as e}from"node:fs";import{relative as t,resolve as n}from"node:path";import{detectPackageName as r,extractContent as i}from"@intlayer/babel";import{
|
|
1
|
+
import{existsSync as e}from"node:fs";import{relative as t,resolve as n}from"node:path";import{detectPackageName as r,extractContent as i}from"@intlayer/babel";import{prepareIntlayer as a}from"@intlayer/chokidar/build";import{logConfigDetails as o}from"@intlayer/chokidar/cli";import{buildComponentFilesList as s}from"@intlayer/chokidar/utils";import{ANSIColors as c,colorize as l,colorizePath as u,getAppLogger as d,x as f}from"@intlayer/config/logger";import{getConfiguration as p}from"@intlayer/config/node";import{getUnmergedDictionaries as m}from"@intlayer/unmerged-dictionaries-entry";import h from"enquirer";const g=async g=>{let _=p(g.configOptions);o(g?.configOptions);let v=d(_),{baseDir:y}=_.system,{output:b}=_.compiler,x=e=>u(t(y,e));if(!b){v(`${f} No output configuration found. Add a ${l(`compiler.output`,c.BLUE)} in your configuration.`,{level:`error`});return}let S=r(y),C=g.files??[];if(C.length===0){let e=s(_).map(e=>({value:e,label:t(y,e)}));if(e.length===0){v(`No extractable files found in the project.`);return}let n=`__select_all__`,r;try{let t=Math.max((process.stdout.columns||80)-15,20),i=e=>e.length>t?`...${e.slice(-(t-3))}`:e,{files:a}=await h.prompt({type:`autocomplete`,name:`files`,message:`Select files to extract (Type to search):`,multiple:!0,limit:40,choices:[{name:n,message:`────── Select all ──────`},...e.map(e=>({name:e.value,message:i(e.label)}))],async toggle(e,t){if(!(!e||e.disabled))return e.enabled=t??!e.enabled,e.name===n&&this.choices.filter(e=>e.name!==n).forEach(t=>{t.enabled=e.enabled}),this.render()},format(){return this.state?.submitted&&this.options?.multiple?`${this.selected.filter(e=>e.name!==n).length} file(s) selected`:this.input??``}});r=a.filter(e=>e!==n)}catch{r=Symbol(`cancel`)}typeof r==`symbol`&&process.exit(0),C=r}if(C.length===0){v(`No files selected for extraction.`);return}let w=C.map(e=>n(y,e)).filter(t=>e(t)?!0:(v(`File not found: ${x(t)}`),!1));if(w.length===0)return;let T=m(_);await Promise.all(w.map(async e=>{try{await i(e,S,{unmergedDictionaries:T,configuration:_,codeOnly:g.codeOnly,declarationOnly:g.declarationOnly})}catch(t){v(`Failed to transform ${e}: ${t.message}`)}})),await a(_)};export{g as extract};
|
|
2
2
|
//# sourceMappingURL=extract.mjs.map
|
package/dist/esm/extract.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.mjs","names":[],"sources":["../../src/extract.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport {
|
|
1
|
+
{"version":3,"file":"extract.mjs","names":[],"sources":["../../src/extract.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\nimport {\n detectPackageName,\n extractContent,\n type PackageName,\n} from '@intlayer/babel';\nimport { prepareIntlayer } from '@intlayer/chokidar/build';\nimport { logConfigDetails } from '@intlayer/chokidar/cli';\nimport { buildComponentFilesList } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizePath,\n getAppLogger,\n x,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { FilePathPattern } from '@intlayer/types/filePathPattern';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport enquirer from 'enquirer';\n\ntype ExtractOptions = {\n files?: string[];\n output?: FilePathPattern;\n configOptions?: GetConfigurationOptions;\n codeOnly?: boolean;\n declarationOnly?: boolean;\n};\n\nexport const extract = async (options: ExtractOptions) => {\n const configuration = getConfiguration(options.configOptions);\n\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(configuration);\n\n const { baseDir } = configuration.system;\n const { output } = configuration.compiler;\n\n const formatPath = (path: string) => {\n const relativePath = relative(baseDir, path);\n return colorizePath(relativePath);\n };\n\n if (!output) {\n appLogger(\n `${x} No output configuration found. Add a ${colorize('compiler.output', ANSIColors.BLUE)} in your configuration.`,\n {\n level: 'error',\n }\n );\n return;\n }\n\n // Detect package\n const packageName: PackageName = detectPackageName(baseDir);\n\n let filesToExtract = options.files ?? [];\n\n if (filesToExtract.length === 0) {\n // Await all promises simultaneously\n const fileList = buildComponentFilesList(configuration);\n\n // Flatten the nested arrays and remove duplicates\n // Relative paths for selection\n const choices = fileList.map((file) => {\n const relPath = relative(baseDir, file);\n return {\n value: file,\n label: relPath,\n };\n });\n\n if (choices.length === 0) {\n appLogger('No extractable files found in the project.');\n return;\n }\n\n const SELECT_ALL = '__select_all__';\n\n type PromptChoice = {\n name: string;\n enabled: boolean;\n disabled?: boolean | string;\n };\n\n type PromptContext = {\n choices: PromptChoice[];\n render(): void | Promise<void>;\n state: { submitted: boolean };\n selected: PromptChoice[];\n input: string;\n options: { multiple?: boolean };\n };\n\n let selectedFiles: string[] | symbol;\n try {\n const maxLen = Math.max((process.stdout.columns || 80) - 15, 20);\n const truncatePath = (path: string) =>\n path.length > maxLen ? `...${path.slice(-(maxLen - 3))}` : path;\n\n const { files: enquirerSelectedFiles } = await enquirer.prompt<{\n files: string[];\n }>({\n type: 'autocomplete',\n name: 'files',\n message: 'Select files to extract (Type to search):',\n multiple: true,\n // @ts-ignore limit exist but is not typed\n limit: 40,\n choices: [\n { name: SELECT_ALL, message: '────── Select all ──────' },\n ...choices.map((choice) => ({\n name: choice.value,\n message: truncatePath(choice.label),\n })),\n ],\n async toggle(\n this: PromptContext,\n choice: PromptChoice,\n enabled?: boolean\n ) {\n if (!choice || choice.disabled) return;\n choice.enabled = enabled == null ? !choice.enabled : enabled;\n\n if (choice.name === SELECT_ALL) {\n this.choices\n .filter((choiceEl) => choiceEl.name !== SELECT_ALL)\n .forEach((choiceEl) => {\n choiceEl.enabled = choice.enabled;\n });\n }\n\n return this.render();\n },\n format(this: PromptContext) {\n if (this.state?.submitted && this.options?.multiple) {\n return `${this.selected.filter((s) => s.name !== SELECT_ALL).length} file(s) selected`;\n }\n return this.input ?? '';\n },\n });\n\n selectedFiles = enquirerSelectedFiles.filter((f) => f !== SELECT_ALL);\n } catch {\n selectedFiles = Symbol('cancel');\n }\n\n if (typeof selectedFiles === 'symbol') {\n // User cancelled\n process.exit(0);\n }\n\n filesToExtract = selectedFiles as string[];\n }\n\n if (filesToExtract.length === 0) {\n appLogger('No files selected for extraction.');\n return;\n }\n\n const absoluteFiles = filesToExtract\n .map((file) => resolve(baseDir, file))\n .filter((file) => {\n if (!existsSync(file)) {\n appLogger(`File not found: ${formatPath(file)}`);\n return false;\n }\n return true;\n });\n\n if (absoluteFiles.length === 0) {\n return;\n }\n\n const unmergedDictionaries = getUnmergedDictionaries(configuration);\n\n await Promise.all(\n absoluteFiles.map(async (filePath) => {\n try {\n await extractContent(filePath, packageName, {\n unmergedDictionaries,\n configuration,\n codeOnly: options.codeOnly,\n declarationOnly: options.declarationOnly,\n });\n } catch (error) {\n appLogger(\n `Failed to transform ${filePath}: ${(error as Error).message}`\n );\n }\n })\n );\n\n await prepareIntlayer(configuration); // Prepare Intlayer to apply the changes\n};\n"],"mappings":"smBAiCA,MAAa,EAAU,KAAO,IAA4B,CACxD,IAAM,EAAgB,EAAiB,EAAQ,cAAc,CAE7D,EAAiB,GAAS,cAAc,CAExC,IAAM,EAAY,EAAa,EAAc,CAEvC,CAAE,WAAY,EAAc,OAC5B,CAAE,UAAW,EAAc,SAE3B,EAAc,GAEX,EADc,EAAS,EAAS,EAAK,CACX,CAGnC,GAAI,CAAC,EAAQ,CACX,EACE,GAAG,EAAE,wCAAwC,EAAS,kBAAmB,EAAW,KAAK,CAAC,yBAC1F,CACE,MAAO,QACR,CACF,CACD,OAIF,IAAM,EAA2B,EAAkB,EAAQ,CAEvD,EAAiB,EAAQ,OAAS,EAAE,CAExC,GAAI,EAAe,SAAW,EAAG,CAM/B,IAAM,EAJW,EAAwB,EAAc,CAI9B,IAAK,IAErB,CACL,MAAO,EACP,MAHc,EAAS,EAAS,EAAK,CAItC,EACD,CAEF,GAAI,EAAQ,SAAW,EAAG,CACxB,EAAU,6CAA6C,CACvD,OAGF,IAAM,EAAa,iBAiBf,EACJ,GAAI,CACF,IAAM,EAAS,KAAK,KAAK,QAAQ,OAAO,SAAW,IAAM,GAAI,GAAG,CAC1D,EAAgB,GACpB,EAAK,OAAS,EAAS,MAAM,EAAK,MAAM,EAAE,EAAS,GAAG,GAAK,EAEvD,CAAE,MAAO,GAA0B,MAAM,EAAS,OAErD,CACD,KAAM,eACN,KAAM,QACN,QAAS,4CACT,SAAU,GAEV,MAAO,GACP,QAAS,CACP,CAAE,KAAM,EAAY,QAAS,2BAA4B,CACzD,GAAG,EAAQ,IAAK,IAAY,CAC1B,KAAM,EAAO,MACb,QAAS,EAAa,EAAO,MAAM,CACpC,EAAE,CACJ,CACD,MAAM,OAEJ,EACA,EACA,CACI,MAAC,GAAU,EAAO,UAWtB,MAVA,GAAO,QAAU,GAAkB,CAAC,EAAO,QAEvC,EAAO,OAAS,GAClB,KAAK,QACF,OAAQ,GAAa,EAAS,OAAS,EAAW,CAClD,QAAS,GAAa,CACrB,EAAS,QAAU,EAAO,SAC1B,CAGC,KAAK,QAAQ,EAEtB,QAA4B,CAI1B,OAHI,KAAK,OAAO,WAAa,KAAK,SAAS,SAClC,GAAG,KAAK,SAAS,OAAQ,GAAM,EAAE,OAAS,EAAW,CAAC,OAAO,mBAE/D,KAAK,OAAS,IAExB,CAAC,CAEF,EAAgB,EAAsB,OAAQ,GAAM,IAAM,EAAW,MAC/D,CACN,EAAgB,OAAO,SAAS,CAG9B,OAAO,GAAkB,UAE3B,QAAQ,KAAK,EAAE,CAGjB,EAAiB,EAGnB,GAAI,EAAe,SAAW,EAAG,CAC/B,EAAU,oCAAoC,CAC9C,OAGF,IAAM,EAAgB,EACnB,IAAK,GAAS,EAAQ,EAAS,EAAK,CAAC,CACrC,OAAQ,GACF,EAAW,EAAK,CAId,IAHL,EAAU,mBAAmB,EAAW,EAAK,GAAG,CACzC,IAGT,CAEJ,GAAI,EAAc,SAAW,EAC3B,OAGF,IAAM,EAAuB,EAAwB,EAAc,CAEnE,MAAM,QAAQ,IACZ,EAAc,IAAI,KAAO,IAAa,CACpC,GAAI,CACF,MAAM,EAAe,EAAU,EAAa,CAC1C,uBACA,gBACA,SAAU,EAAQ,SAClB,gBAAiB,EAAQ,gBAC1B,CAAC,OACK,EAAO,CACd,EACE,uBAAuB,EAAS,IAAK,EAAgB,UACtD,GAEH,CACH,CAED,MAAM,EAAgB,EAAc"}
|
package/dist/esm/fill/fill.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ensureArray as e,getTargetUnmergedDictionaries as t}from"../getTargetDictionary.mjs";import{setupAI as n}from"../utils/setupAI.mjs";import{listTranslationsTasks as r}from"./listTranslationsTasks.mjs";import{translateDictionary as i}from"./translateDictionary.mjs";import{writeFill as a}from"./writeFill.mjs";import{basename as o,relative as s}from"node:path";import{
|
|
1
|
+
import{ensureArray as e,getTargetUnmergedDictionaries as t}from"../getTargetDictionary.mjs";import{setupAI as n}from"../utils/setupAI.mjs";import{listTranslationsTasks as r}from"./listTranslationsTasks.mjs";import{translateDictionary as i}from"./translateDictionary.mjs";import{writeFill as a}from"./writeFill.mjs";import{basename as o,relative as s}from"node:path";import{prepareIntlayer as c,writeContentDeclaration as l}from"@intlayer/chokidar/build";import{logConfigDetails as u}from"@intlayer/chokidar/cli";import{formatPath as d,getGlobalLimiter as f,getTaskLimiter as p}from"@intlayer/chokidar/utils";import{ANSIColors as m,colorize as h,colorizeKey as g,colorizePath as _,getAppLogger as v}from"@intlayer/config/logger";import{getConfiguration as y}from"@intlayer/config/node";const b=async b=>{let x=y(b?.configOptions);u(b?.configOptions);let S=v(x);b?.build===!0?await c(x,{forceRun:!0}):b?.build===void 0&&await c(x);let{defaultLocale:C,locales:w}=x.internationalization,T=b?.mode??`complete`,E=b?.sourceLocale??C,D=b?.outputLocales?e(b.outputLocales):w,O=await n(x,b?.aiOptions);if(!O?.hasAIAccess)return;let{aiClient:k,aiConfig:A}=O,j=await t(b),M=new Set;j.forEach(e=>{M.add(e.key)});let N=Array.from(M);if(S([`Affected dictionary keys for processing:`,N.length>0?N.map(e=>g(e)).join(`, `):h(`No keys found`,m.YELLOW)]),N.length===0)return;let P=r(j.map(e=>e.localId),D,T,E,x),F=b?.nbConcurrentTranslations??7,I=f(F),L=p(Math.max(1,Math.min(b?.nbConcurrentTasks??F,P.length))),R=P.map(e=>L(async()=>{let t=s(x?.content?.baseDir??process.cwd(),e?.dictionaryFilePath??``);S(`${e.dictionaryPreset} Processing ${_(o(t))}`,{level:`info`});let n=await i(e,x,{mode:T,aiOptions:b?.aiOptions,fillMetadata:!b?.skipMetadata,onHandle:I,aiClient:k,aiConfig:A});if(!n?.dictionaryOutput)return;let{dictionaryOutput:r,sourceLocale:c}=n,u=typeof r.fill==`string`||typeof r.fill==`object`,f=typeof r.locale==`string`,p=u?r.fill:f?x.dictionary?.fill??!0:!1;typeof p==`string`||typeof p==`object`?await a({...r,fill:p},D,[c],x):(await l(r,x),r.filePath&&S(`${e.dictionaryPreset} Content declaration written to ${d(o(r.filePath))}`,{level:`info`}))}));await Promise.all(R),await I.onIdle()};export{b as fill};
|
|
2
2
|
//# sourceMappingURL=fill.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatFillData.mjs","names":[],"sources":["../../../src/fill/formatFillData.ts"],"sourcesContent":["import { basename, dirname, extname, relative } from 'node:path';\nimport {\n getFormatFromExtension,\n resolveRelativePath,\n} from '@intlayer/chokidar/utils';\nimport { parseStringPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { DictionaryKey, Fill } from '@intlayer/types/dictionary';\nimport type {\n FilePathPattern,\n FilePathPatternContext,\n} from '@intlayer/types/filePathPattern';\n\nexport type FillData = {\n localeList: Locale[];\n filePath: string;\n isPerLocale: boolean;\n};\n\nexport const formatFillData = async (\n fillField: Fill,\n localeList: Locale[],\n filePath: string,\n dictionaryKey: DictionaryKey,\n configuration: IntlayerConfig\n): Promise<FillData[]> => {\n if (!fillField || typeof fillField === 'boolean') return [];\n\n const { baseDir } = configuration.system;\n const { defaultLocale } = configuration.internationalization;\n\n const extension = extname(filePath);\n const base = basename(filePath);\n\n // Extract the original filename without extensions\n const cleanComponentFileName = base.includes('.content.')\n ? base.split('.content.')[0]\n : base.split('.')[0];\n\n const uncapitalizedName =\n cleanComponentFileName.charAt(0).toLowerCase() +\n cleanComponentFileName.slice(1);\n\n const componentFormat = getFormatFromExtension(extension
|
|
1
|
+
{"version":3,"file":"formatFillData.mjs","names":[],"sources":["../../../src/fill/formatFillData.ts"],"sourcesContent":["import { basename, dirname, extname, relative } from 'node:path';\nimport {\n getFormatFromExtension,\n resolveRelativePath,\n} from '@intlayer/chokidar/utils';\nimport { parseStringPattern } from '@intlayer/config/utils';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { DictionaryKey, Fill } from '@intlayer/types/dictionary';\nimport type {\n FilePathPattern,\n FilePathPatternContext,\n} from '@intlayer/types/filePathPattern';\n\nexport type FillData = {\n localeList: Locale[];\n filePath: string;\n isPerLocale: boolean;\n};\n\nexport const formatFillData = async (\n fillField: Fill,\n localeList: Locale[],\n filePath: string,\n dictionaryKey: DictionaryKey,\n configuration: IntlayerConfig\n): Promise<FillData[]> => {\n if (!fillField || typeof fillField === 'boolean') return [];\n\n const { baseDir } = configuration.system;\n const { defaultLocale } = configuration.internationalization;\n\n const extension = extname(filePath);\n const base = basename(filePath);\n\n // Extract the original filename without extensions\n const cleanComponentFileName = base.includes('.content.')\n ? base.split('.content.')[0]\n : base.split('.')[0];\n\n const uncapitalizedName =\n cleanComponentFileName.charAt(0).toLowerCase() +\n cleanComponentFileName.slice(1);\n\n const componentFormat = getFormatFromExtension(extension);\n\n const getContext = (\n locale: Locale,\n patternType?: FilePathPattern\n ): FilePathPatternContext => {\n let format: FilePathPatternContext['format'] = 'json';\n if (typeof patternType === 'string') {\n const extFormat = getFormatFromExtension(extname(patternType) as any);\n if (extFormat) {\n format = extFormat as any;\n }\n }\n\n return {\n key: dictionaryKey,\n componentDirPath: relative(baseDir, dirname(filePath)),\n componentFileName: cleanComponentFileName,\n fileName: uncapitalizedName,\n componentFormat:\n componentFormat as FilePathPatternContext['componentFormat'],\n componentExtension:\n extension as FilePathPatternContext['componentExtension'],\n format,\n locale,\n extension: configuration.content.fileExtensions[0],\n };\n };\n\n const processPattern = async (\n pattern: FilePathPattern,\n locales: Locale[]\n ): Promise<FillData[]> => {\n const dummyLocale = '###########locale###########' as Locale;\n let isPatternPerLocale = false;\n\n if (typeof pattern === 'string') {\n isPatternPerLocale = pattern.includes('{{locale}}');\n } else if (typeof pattern === 'function') {\n const pathWithDummy = await pattern(getContext(dummyLocale, pattern));\n isPatternPerLocale = pathWithDummy.includes(dummyLocale);\n }\n\n if (isPatternPerLocale) {\n const resolvedPaths: FillData[] = [];\n\n // Generate one path per locale\n for (const locale of locales) {\n const rawPath =\n typeof pattern === 'string'\n ? parseStringPattern(pattern, getContext(locale, pattern))\n : await pattern(getContext(locale, pattern));\n\n const absolutePath = resolveRelativePath(rawPath, filePath, baseDir);\n\n resolvedPaths.push({\n filePath: absolutePath,\n localeList: [locale],\n isPerLocale: true,\n });\n }\n\n // Group by filePath in case multiple locales resolve to the same path\n const groupedByFilePath = resolvedPaths.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n if (!existing.localeList.includes(curr.localeList[0])) {\n existing.localeList.push(...curr.localeList);\n }\n // If multiple locales share a path, it's no longer strictly per-locale\n existing.isPerLocale = false;\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n return groupedByFilePath;\n } else {\n // Single multi-lingual path using default locale for pattern resolution\n const rawPath =\n typeof pattern === 'string'\n ? parseStringPattern(pattern, getContext(defaultLocale, pattern))\n : await pattern(getContext(defaultLocale, pattern));\n\n const absolutePath = resolveRelativePath(rawPath, filePath, baseDir);\n\n return [\n {\n filePath: absolutePath,\n localeList: locales,\n isPerLocale: false,\n },\n ];\n }\n };\n\n // Handle Record of Locales\n if (typeof fillField === 'object' && fillField !== null) {\n const results: FillData[] = [];\n\n for (const locale of localeList) {\n const pattern = (fillField as Record<string, any>)[locale];\n if (pattern && typeof pattern !== 'boolean') {\n const res = await processPattern(pattern as FilePathPattern, [locale]);\n results.push(...res);\n }\n }\n\n // Merge identical file paths if they stem from different locales having the same output path\n const grouped = results.reduce((acc, curr) => {\n const existing = acc.find((item) => item.filePath === curr.filePath);\n if (existing) {\n for (const loc of curr.localeList) {\n if (!existing.localeList.includes(loc)) {\n existing.localeList.push(loc);\n }\n }\n existing.isPerLocale = false;\n } else {\n acc.push(curr);\n }\n return acc;\n }, [] as FillData[]);\n\n return grouped;\n }\n\n // Handle static string or function patterns\n if (typeof fillField === 'string' || typeof fillField === 'function') {\n return processPattern(fillField as FilePathPattern, localeList);\n }\n\n return [];\n};\n"],"mappings":"oOAoBA,MAAa,EAAiB,MAC5B,EACA,EACA,EACA,EACA,IACwB,CACxB,GAAI,CAAC,GAAa,OAAO,GAAc,UAAW,MAAO,EAAE,CAE3D,GAAM,CAAE,WAAY,EAAc,OAC5B,CAAE,iBAAkB,EAAc,qBAElC,EAAY,EAAQ,EAAS,CAC7B,EAAO,EAAS,EAAS,CAGzB,EAAyB,EAAK,SAAS,YAAY,CACrD,EAAK,MAAM,YAAY,CAAC,GACxB,EAAK,MAAM,IAAI,CAAC,GAEd,EACJ,EAAuB,OAAO,EAAE,CAAC,aAAa,CAC9C,EAAuB,MAAM,EAAE,CAE3B,EAAkB,EAAuB,EAAU,CAEnD,GACJ,EACA,IAC2B,CAC3B,IAAI,EAA2C,OAC/C,GAAI,OAAO,GAAgB,SAAU,CACnC,IAAM,EAAY,EAAuB,EAAQ,EAAY,CAAQ,CACjE,IACF,EAAS,GAIb,MAAO,CACL,IAAK,EACL,iBAAkB,EAAS,EAAS,EAAQ,EAAS,CAAC,CACtD,kBAAmB,EACnB,SAAU,EAER,kBACF,mBACE,EACF,SACA,SACA,UAAW,EAAc,QAAQ,eAAe,GACjD,EAGG,EAAiB,MACrB,EACA,IACwB,CACxB,IAAM,EAAc,+BAChB,EAAqB,GASzB,GAPI,OAAO,GAAY,SACrB,EAAqB,EAAQ,SAAS,aAAa,CAC1C,OAAO,GAAY,aAE5B,GADsB,MAAM,EAAQ,EAAW,EAAa,EAAQ,CAAC,EAClC,SAAS,EAAY,EAGtD,EAAoB,CACtB,IAAM,EAA4B,EAAE,CAGpC,IAAK,IAAM,KAAU,EAAS,CAM5B,IAAM,EAAe,EAJnB,OAAO,GAAY,SACf,EAAmB,EAAS,EAAW,EAAQ,EAAQ,CAAC,CACxD,MAAM,EAAQ,EAAW,EAAQ,EAAQ,CAAC,CAEE,EAAU,EAAQ,CAEpE,EAAc,KAAK,CACjB,SAAU,EACV,WAAY,CAAC,EAAO,CACpB,YAAa,GACd,CAAC,CAkBJ,OAd0B,EAAc,QAAQ,EAAK,IAAS,CAC5D,IAAM,EAAW,EAAI,KAAM,GAAS,EAAK,WAAa,EAAK,SAAS,CAUpE,OATI,GACG,EAAS,WAAW,SAAS,EAAK,WAAW,GAAG,EACnD,EAAS,WAAW,KAAK,GAAG,EAAK,WAAW,CAG9C,EAAS,YAAc,IAEvB,EAAI,KAAK,EAAK,CAET,GACN,EAAE,CAAe,MAYpB,MAAO,CACL,CACE,SAJiB,EAJnB,OAAO,GAAY,SACf,EAAmB,EAAS,EAAW,EAAe,EAAQ,CAAC,CAC/D,MAAM,EAAQ,EAAW,EAAe,EAAQ,CAAC,CAEL,EAAU,EAAQ,CAKhE,WAAY,EACZ,YAAa,GACd,CACF,EAKL,GAAI,OAAO,GAAc,UAAY,EAAoB,CACvD,IAAM,EAAsB,EAAE,CAE9B,IAAK,IAAM,KAAU,EAAY,CAC/B,IAAM,EAAW,EAAkC,GACnD,GAAI,GAAW,OAAO,GAAY,UAAW,CAC3C,IAAM,EAAM,MAAM,EAAe,EAA4B,CAAC,EAAO,CAAC,CACtE,EAAQ,KAAK,GAAG,EAAI,EAoBxB,OAfgB,EAAQ,QAAQ,EAAK,IAAS,CAC5C,IAAM,EAAW,EAAI,KAAM,GAAS,EAAK,WAAa,EAAK,SAAS,CACpE,GAAI,EAAU,CACZ,IAAK,IAAM,KAAO,EAAK,WAChB,EAAS,WAAW,SAAS,EAAI,EACpC,EAAS,WAAW,KAAK,EAAI,CAGjC,EAAS,YAAc,QAEvB,EAAI,KAAK,EAAK,CAEhB,OAAO,GACN,EAAE,CAAe,CAUtB,OAJI,OAAO,GAAc,UAAY,OAAO,GAAc,WACjD,EAAe,EAA8B,EAAW,CAG1D,EAAE"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{listMissingTranslationsWithConfig as e}from"../test/listMissingTranslations.mjs";import{basename as t}from"node:path";import{ANSIColors as
|
|
1
|
+
import{listMissingTranslationsWithConfig as e}from"../test/listMissingTranslations.mjs";import{basename as t}from"node:path";import{formatLocale as n}from"@intlayer/chokidar/utils";import{ANSIColors as r,colon as i,colorize as a,colorizeKey as o,colorizePath as s,getAppLogger as c}from"@intlayer/config/logger";import{getUnmergedDictionaries as l}from"@intlayer/unmerged-dictionaries-entry";import{getFilterTranslationsOnlyDictionary as u}from"@intlayer/core/plugins";import{getDictionaries as d}from"@intlayer/dictionaries-entry";const f=(f,p,m,h,g)=>{let _=c(g),v=d(g),y=l(g),b=Object.values(y).flat().filter(e=>f.includes(e.localId)),{missingTranslations:x}=e(g),S=Math.max(...b.map(e=>e.key.length)),C=[];for(let e of b){let c=i([` - `,a(`[`,r.GREY_DARK),o(e.key),a(`]`,r.GREY_DARK)].join(``),{colSize:S+6}),l=e.key,d=e.localId,f=v[l];if((e.filled??!1)===!0||(e.fill??g.dictionary?.fill??!1)===!1)continue;let y=e.locale??h;if(!f){_(`${c} Dictionary not found in dictionariesRecord. Skipping.`,{level:`warn`});continue}if(!e.filePath){_(`${c} Dictionary has no file path. Skipping.`,{level:`warn`});continue}let b=u(f,y);if(Object.keys(b).length===0){_(`${c} No content found for dictionary in source locale ${n(y)}. Skipping translation for this dictionary.`,{level:`warn`});continue}let w=p;if(m===`complete`&&(w=x.find(e=>e.key===l)?.locales.filter(e=>p.includes(e))??[]),w.length===0){_(`${c} ${a(`No locales to fill, Skipping`,r.GREY_DARK)} ${s(t(e.filePath))}`,{level:`warn`});continue}C.push({dictionaryKey:l,dictionaryLocalId:d,sourceLocale:y,targetLocales:w,dictionaryPreset:c,dictionaryFilePath:e.filePath})}return C};export{f as listTranslationsTasks};
|
|
2
2
|
//# sourceMappingURL=listTranslationsTasks.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{deepMergeContent as e}from"./deepMergeContent.mjs";import{getFilterMissingContentPerLocale as t}from"./getFilterMissingContentPerLocale.mjs";import{basename as n}from"node:path";import{
|
|
1
|
+
import{deepMergeContent as e}from"./deepMergeContent.mjs";import{getFilterMissingContentPerLocale as t}from"./getFilterMissingContentPerLocale.mjs";import{basename as n}from"node:path";import{chunkJSON as r,formatLocale as i,mergeChunks as a,reconstructFromSingleChunk as o,reduceObjectFormat as s,verifyIdenticObjectFormat as c}from"@intlayer/chokidar/utils";import{ANSIColors as l,colon as u,colorize as d,colorizeNumber as f,colorizePath as p,getAppLogger as m}from"@intlayer/config/logger";import{getUnmergedDictionaries as h}from"@intlayer/unmerged-dictionaries-entry";import{getFilterMissingTranslationsDictionary as g,getMultilingualDictionary as _,getPerLocaleDictionary as v,insertContentInDictionary as y}from"@intlayer/core/plugins";import{getIntlayerAPIProxy as b}from"@intlayer/api";import{retryManager as x}from"@intlayer/config/utils";const S=e=>!e.description||!e.title||!e.tags,C=e=>{if(typeof e!=`object`||!e||Array.isArray(e))return{content:e,nulls:void 0,hasNulls:!1};let t={},n={},r=!1;for(let[i,a]of Object.entries(e))if(a===null)n[i]=null,r=!0;else{let e=C(a);t[i]=e.content,e.hasNulls&&(n[i]=e.nulls,r=!0)}return{content:t,nulls:r?n:void 0,hasNulls:r}},w=1e3*10;let T=0;const E=async(E,D,O)=>{let k=m(D),A=b(void 0,D),{mode:j,aiOptions:M,fillMetadata:N,aiClient:P,aiConfig:F}={mode:`complete`,fillMetadata:!0,...O},I=()=>{T=0,O?.onSuccess?.()};return await x(async()=>{let m=h(D),b=m[E.dictionaryKey].find(e=>e.localId===E.dictionaryLocalId);if(!b)return k(`${E.dictionaryPreset}Dictionary not found in unmergedDictionariesRecord. Skipping.`,{level:`warn`}),{...E,dictionaryOutput:null};let L;if(N&&(S(b)||j===`review`)){let e=v(b,D.internationalization.defaultLocale);k(`${E.dictionaryPreset} Filling missing metadata for ${p(n(b.filePath))}`,{level:`info`});let t=async()=>P&&F?{data:await P.auditDictionaryMetadata({fileContent:JSON.stringify(e),aiConfig:F})}:await A.ai.auditContentDeclarationMetadata({fileContent:JSON.stringify(e),aiOptions:M});L=(O?.onHandle?await O.onHandle(t):await t()).data?.fileContent}let R=await Promise.all(E.targetLocales.map(async h=>{let _=structuredClone(b),y;if(typeof b.locale==`string`){let e=b.filePath?.replace(RegExp(`/${E.sourceLocale}/`,`g`),`/${h}/`),n=e?m[E.dictionaryKey]?.find(t=>t.filePath===e&&t.locale===h):void 0;y=n??{key:b.key,content:{},filePath:e,locale:h},j===`complete`&&(_=t(_,n))}else j===`complete`&&(_=g(_,h)),_=v(_,E.sourceLocale),y=v(b,h);let S=u([d(`[`,l.GREY_DARK),i(h),d(`]`,l.GREY_DARK)].join(``),{colSize:18}),D=(e,t)=>t<=1?``:u([d(`[`,l.GREY_DARK),f(e+1),d(`/${t}`,l.GREY_DARK),d(`]`,l.GREY_DARK)].join(``),{colSize:5});k(`${E.dictionaryPreset}${S} Preparing ${p(n(y.filePath))}`,{level:`info`});let N=typeof _.content==`object`&&_.content!==null||Array.isArray(_.content),{content:R,nulls:z}=C(N?_.content:{__INTLAYER_ROOT_PRIMITIVE_CONTENT__:_.content}),B=r(R,7e3),V=B.length;V>1&&k(`${E.dictionaryPreset}${S} Split into ${f(V)} chunks for translation`,{level:`info`});let H=[],U=B.map(e=>{let t=D(e.index,e.total);V>1&&k(`${E.dictionaryPreset}${S}${t} Translating chunk`,{level:`info`});let n=o(e),r=s(N?y.content:{__INTLAYER_ROOT_PRIMITIVE_CONTENT__:y.content},n),i=async()=>await x(async()=>{let e;if(e=P&&F?await P.translateJSON({entryFileContent:n,presetOutputContent:r,dictionaryDescription:_.description??L?.description??``,entryLocale:E.sourceLocale,outputLocale:h,mode:j,aiConfig:F}):await A.ai.translateJSON({entryFileContent:n,presetOutputContent:r,dictionaryDescription:_.description??L?.description??``,entryLocale:E.sourceLocale,outputLocale:h,mode:j,aiOptions:M}).then(e=>e.data),!e?.fileContent)throw Error(`No content result`);let{isIdentic:t}=c(e.fileContent,n);if(!t)throw Error(`Translation result does not match expected format`);return I(),e.fileContent},{maxRetry:3,delay:w,onError:({error:t,attempt:n,maxRetry:r})=>{let i=D(e.index,e.total);k(`${E.dictionaryPreset}${S}${i} ${d(`Error filling:`,l.RED)} ${d(typeof t==`string`?t:JSON.stringify(t),l.GREY_DARK)} - Attempt ${f(n+1)} of ${f(r)}`,{level:`error`}),T+=1,T>=10&&(k(`There is something wrong.`,{level:`error`}),process.exit(1))}})();return(O?.onHandle?O.onHandle(i):i()).then(t=>({chunk:e,result:t}))});(await Promise.all(U)).sort((e,t)=>e.chunk.index-t.chunk.index).forEach(({result:e})=>{H.push(e)});let W=a(H);z&&(W=e(W,z));let G={..._,content:W}.content;return N||(G=G?.__INTLAYER_ROOT_PRIMITIVE_CONTENT__),typeof b.locale==`string`&&(G=e(y.content??{},G)),[h,G]})),z=Object.fromEntries(R),B={..._(b.locale?{...b,key:b.key,content:{}}:b),locale:void 0,...L};for(let e of E.targetLocales)z[e]&&(B=y(B,z[e],e));if(k(`${E.dictionaryPreset} ${d(`Translation completed successfully`,l.GREEN)} for ${p(n(B.filePath))}`,{level:`info`}),b.locale&&(b.fill===!0||b.fill===void 0)&&b.location===`local`){let e=b.filePath.split(`.`).slice(0,-1),t=e[e.length-1];return JSON.parse(JSON.stringify({...E,dictionaryOutput:{...B,fill:void 0,filled:!0}}).replaceAll(RegExp(`\\.${t}\\.[a-zA-Z0-9]+`,`g`),`.filled.${t}.json`))}return{...E,dictionaryOutput:B}},{maxRetry:2,delay:w,onError:({error:e,attempt:t,maxRetry:n})=>k(`${E.dictionaryPreset} ${d(`Error:`,l.RED)} ${d(typeof e==`string`?e:JSON.stringify(e),l.GREY_DARK)} - Attempt ${f(t+1)} of ${f(n)}`,{level:`error`}),onMaxTryReached:({error:e})=>k(`${E.dictionaryPreset} ${d(`Maximum number of retries reached:`,l.RED)} ${d(typeof e==`string`?e:JSON.stringify(e),l.GREY_DARK)}`,{level:`error`})})()};export{E as translateDictionary};
|
|
2
2
|
//# sourceMappingURL=translateDictionary.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{formatFillData as e}from"./formatFillData.mjs";import{getAvailableLocalesInDictionary as t}from"./getAvailableLocalesInDictionary.mjs";import{relative as n}from"node:path";import{
|
|
1
|
+
import{formatFillData as e}from"./formatFillData.mjs";import{getAvailableLocalesInDictionary as t}from"./getAvailableLocalesInDictionary.mjs";import{relative as n}from"node:path";import{writeContentDeclaration as r}from"@intlayer/chokidar/build";import{formatLocale as i,formatPath as a}from"@intlayer/chokidar/utils";import{colorizeKey as o,getAppLogger as s}from"@intlayer/config/logger";import{getDictionaries as c}from"@intlayer/dictionaries-entry";const l=async(l,u,d,f)=>{let p=s(f),m=c(f)[l.key],{filePath:h}=l;if(!h){p(`No file path found for dictionary`,{level:`error`});return}let g=l.fill??f.dictionary?.fill??!0;if(g===!1){p(`Auto fill is disabled for '${o(m.key)}'`,{level:`info`});return}let _=(u??f.internationalization.locales).filter(e=>!d?.includes(e)),v=t(l),y=_.filter(e=>v.includes(e));if(y.length===0){p(`No translations available for dictionary '${o(m.key)}'`,{level:`info`});return}let b=await e(g,y,h,m.key,f);for await(let e of b){if(!e.filePath){p(`No file path found for auto filled content declaration for '${o(m.key)}'`,{level:`error`});continue}let{fill:t,...s}=l,c=n(f.system.baseDir,e.filePath);if(await r({...s,filled:!0,locale:e.isPerLocale?e.localeList[0]:void 0,localId:`${l.key}::local::${c}`,filePath:c},f,{localeList:e.localeList}),e.isPerLocale){let t=e.localeList[0];p(`Auto filled per-locale content declaration for '${o(m.key)}' written to ${a(e.filePath)} for locale ${i(t)}`,{level:`info`})}else p(`Auto filled content declaration for '${o(m.key)}' written to ${a(e.filePath)}`,{level:`info`})}};export{l as writeFill};
|
|
2
2
|
//# sourceMappingURL=writeFill.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{relative as e}from"node:path";import{colon as
|
|
1
|
+
import{relative as e}from"node:path";import{formatPath as t}from"@intlayer/chokidar/utils";import{colon as n,colorizeKey as r,colorizeNumber as i,getAppLogger as a}from"@intlayer/config/logger";import{getConfiguration as o}from"@intlayer/config/node";import{getUnmergedDictionaries as s}from"@intlayer/unmerged-dictionaries-entry";const c=t=>{let n=o(t?.configOptions),r=s(n);return Object.values(r).flat().map(r=>({key:r.key??``,path:t?.absolute?r.filePath??`Remote`:e(n.system.baseDir,r.filePath??`Remote`)}))},l=e=>{let s=c(e);if(e?.json){console.log(JSON.stringify(s));return}let l=a(o(e?.configOptions)),u=s.map(e=>[n(` - ${r(e.key)}`,{colSize:s.map(e=>e.key.length),maxSize:60}),` - `,t(e.path)].join(``));l(`Content declaration files:`),u.forEach(e=>{l(e,{level:`info`})}),l(`Total content declaration files: ${i(s.length)}`)};export{l as listContentDeclaration,c as listContentDeclarationRows};
|
|
2
2
|
//# sourceMappingURL=listContentDeclaration.mjs.map
|
package/dist/esm/liveSync.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import{IntlayerEventListener as e}from"./IntlayerEventListener.mjs";import{
|
|
1
|
+
import{IntlayerEventListener as e}from"./IntlayerEventListener.mjs";import{buildDictionary as t}from"@intlayer/chokidar/build";import{runParallel as n}from"@intlayer/chokidar/utils";import{getAppLogger as r}from"@intlayer/config/logger";import{getConfiguration as i}from"@intlayer/config/node";import{getUnmergedDictionaries as a}from"@intlayer/unmerged-dictionaries-entry";import{createServer as o}from"node:http";import s from"@intlayer/config/package.json"with{type:"json"};import{getLocalizedContent as c}from"@intlayer/core/plugins";import{getDictionaries as l}from"@intlayer/dictionaries-entry";const u=async(e,n)=>{r(n)(`Writing dictionary ${e.key}`),await t([e],n)},d=async t=>{let d=i(t?.configOptions),f=r(d),{liveSyncPort:p,liveSyncURL:m}=d.editor,h=null,g=null;if(t?.with&&(h=n(t.with),h.result.catch(()=>{})),d.editor.liveSync&&d.editor.backendURL&&d.editor.clientId&&d.editor.clientSecret){g=new e(d),g.onConnectionOpen=()=>{f(`Live sync connection established`)},g.onConnectionError=e=>{let t=e;f(`Live sync connection error: ${t.message??`Unknown error`}`,{level:`warn`}),(t.message?.includes(`terminated`)||t.message?.includes(`closed`))&&f(`Server connection was terminated, automatic reconnection will be attempted...`,{level:`info`})},g.onDictionaryAdded=e=>u(e,d),g.onDictionaryChange=e=>u(e,d),g.onDictionaryDeleted=e=>u(e,d);try{await g.initialize()}catch(e){f(`Failed to initialize IntlayerEventListener:`,{level:`error`}),f(`Error: ${e instanceof Error?e.message:String(e)}`,{level:`error`})}}else d.editor.liveSync?(!d.editor.clientId||!d.editor.clientSecret)&&f(`Missing client credentials for hot reload. Please configure clientId and clientSecret`):f(`Hot reload is disabled. Please enable it in the configuration (editor.liveSync).`);let _=o(async(e,t)=>{if(e.method===`OPTIONS`){t.writeHead(200,{"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`}),t.end();return}if(e.url?.startsWith(`/dictionaries`)){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`});let n=l(d);if(e.url.startsWith(`/dictionaries/`)){let[r,i]=decodeURIComponent(e.url).slice(14).split(`/`),a=n[r]??null;if(i){let e=c(a.content,i,{dictionaryKey:r,keyPath:[]});t.end(JSON.stringify(e));return}t.end(JSON.stringify(a));return}t.end(JSON.stringify(n));return}if(e.url?.startsWith(`/unmerged_dictionaries`)){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`});let n=a(d);if(e.url.startsWith(`/unmerged_dictionaries/`)){let r=n[decodeURIComponent(e.url.slice(23))]??null;t.end(JSON.stringify(r));return}t.end(JSON.stringify(n));return}if(e.url===`/configuration`){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`,"Cache-Control":`no-store`,"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Methods":`GET, POST, PUT, DELETE, OPTIONS`,"Access-Control-Allow-Headers":`Content-Type, Authorization`}),t.end(JSON.stringify(d));return}if(e.url===`/health`){t.writeHead(200,{"Content-Type":`application/json; charset=utf-8`}),t.end(JSON.stringify({status:`ok`}));return}t.end(`Not found`)}),v=()=>d.editor.liveSync?`\x1B[32m✓ Enabled\x1B[0m`:`\x1B[31m✗ Disabled\x1B[0m`;_.listen(p,()=>{console.log(`
|
|
2
2
|
\x1b[1;90mINTLAYER v${s.version}\x1b[0m
|
|
3
3
|
|
|
4
4
|
Live server running at: \x1b[90m${m}\x1b[0m
|
|
5
5
|
- Backend URL: \x1b[90m${d.editor.backendURL??`-`}\x1b[0m
|
|
6
6
|
- Live sync: ${v()}
|
|
7
|
-
- Parallel process: ${
|
|
7
|
+
- Parallel process: ${t?.with?`\x1b[90m${Array.isArray(t.with)?t.with.join(` `):t.with}\x1b[0m`:`-`}
|
|
8
8
|
- Access key: ${d.editor.clientId??`-`}
|
|
9
9
|
`)});let y=()=>{g&&(f(`Closing SSE connection...`),g.cleanup()),h&&h.kill(),_.close(()=>{f(`Live sync server stopped`),process.exit(0)})};process.on(`SIGINT`,y),process.on(`SIGTERM`,y),process.on(`exit`,y)};export{d as liveSync};
|
|
10
10
|
//# sourceMappingURL=liveSync.mjs.map
|
package/dist/esm/pull.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{checkCMSAuth as e}from"./utils/checkAccess.mjs";import{PullLogger as t}from"./push/pullLog.mjs";import{existsSync as n}from"node:fs";import{join as r}from"node:path";import{
|
|
1
|
+
import{checkCMSAuth as e}from"./utils/checkAccess.mjs";import{PullLogger as t}from"./push/pullLog.mjs";import{existsSync as n}from"node:fs";import{join as r}from"node:path";import{writeContentDeclaration as i}from"@intlayer/chokidar/build";import{logConfigDetails as a}from"@intlayer/chokidar/cli";import{parallelize as o}from"@intlayer/chokidar/utils";import{ANSIColors as s,getAppLogger as c}from"@intlayer/config/logger";import{getConfiguration as l}from"@intlayer/config/node";import{getUnmergedDictionaries as u}from"@intlayer/unmerged-dictionaries-entry";import{getIntlayerAPIProxy as d}from"@intlayer/api";import{getProjectRequire as f}from"@intlayer/config/utils";const p=async p=>{let m=c(p?.configOptions?.override);try{let c=l(p?.configOptions);if(a(p?.configOptions),!await e(c))return;let h=d(void 0,c),g=u(c),_=await h.dictionary.getDictionariesUpdateTimestamp();if(!_.data)throw Error(`No distant dictionaries found`);let v=_.data;p?.dictionaries&&(v=Object.fromEntries(Object.entries(v).filter(([e])=>p.dictionaries?.includes(e)))),v=Object.fromEntries(Object.entries(v).filter(([e])=>{let t=g[e]?.[0]?.location??c.dictionary?.location??`remote`;return t===`remote`||t===`hybrid`}));let y=r(c.system.mainDir,`remote_dictionaries.cjs`),b=c.build?.require??f(),x=n(y)?b(y):{},S=Object.entries(v),C=S.filter(([e,t])=>{if(!t)return!0;let n=typeof t==`object`?t.updatedAt:t,r=x[e];if(!r)return!0;let i=r?.updatedAt,a=typeof i==`number`?i:i?new Date(i).getTime():void 0;return typeof a==`number`?n>a:!0}).map(([e])=>e),w=S.filter(([e,t])=>{let n=typeof t==`object`?t.updatedAt:t,r=x[e]?.updatedAt,i=typeof r==`number`?r:r?new Date(r).getTime():void 0;return typeof i==`number`&&typeof n==`number`&&i>=n}).map(([e])=>e);if(S.length===0){m(`No dictionaries to fetch`,{level:`error`});return}m(`Fetching dictionaries:`);let T=[...w.map(e=>({dictionaryKey:e,status:`imported`})),...C.map(e=>({dictionaryKey:e,status:`pending`}))],E=new t;E.update(T.map(e=>({dictionaryKey:e.dictionaryKey,status:e.status})));let D=[];await o(T,async e=>{let t=e.status===`imported`||e.status===`up-to-date`;t||(e.status=`fetching`,E.update([{dictionaryKey:e.dictionaryKey,status:`fetching`}]));try{let n;if(t&&(n=x[e.dictionaryKey]),n||=(await h.dictionary.getDictionary(e.dictionaryKey)).data,!n)throw Error(`Dictionary ${e.dictionaryKey} not found on remote`);let r=g[e.dictionaryKey]?.find(e=>e.location===`hybrid`);r&&(n={...n,location:`hybrid`,filePath:r.filePath,localId:r.localId});let{status:a}=await i(n,c,p);e.status=a,E.update([{dictionaryKey:e.dictionaryKey,status:a}]),D.push(n)}catch(t){e.status=`error`,e.error=t,e.errorMessage=`Error fetching dictionary ${e.dictionaryKey}: ${t}`,E.update([{dictionaryKey:e.dictionaryKey,status:`error`}])}},5),E.finish();let O=e=>{switch(e){case`fetched`:case`imported`:case`updated`:case`up-to-date`:case`reimported in JSON`:case`new content file`:return`✔`;case`error`:return`✖`;default:return`⏲`}},k=e=>{switch(e){case`fetched`:case`imported`:case`updated`:case`up-to-date`:return s.GREEN;case`reimported in JSON`:case`new content file`:return s.YELLOW;case`error`:return s.RED;default:return s.BLUE}};for(let e of T){let t=O(e.status),n=k(e.status);m(` - ${e.dictionaryKey} ${s.GREY}[${n}${t} ${e.status}${s.GREY}]${s.RESET}`)}for(let e of T)e.errorMessage&&m(e.errorMessage,{level:`error`})}catch(e){m(e,{level:`error`})}};export{p as pull};
|
|
2
2
|
//# sourceMappingURL=pull.mjs.map
|
package/dist/esm/push/push.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{checkCMSAuth as e}from"../utils/checkAccess.mjs";import{PushLogger as t}from"../pushLog.mjs";import{join as n}from"node:path";import{
|
|
1
|
+
import{checkCMSAuth as e}from"../utils/checkAccess.mjs";import{PushLogger as t}from"../pushLog.mjs";import{join as n}from"node:path";import{prepareIntlayer as r,writeContentDeclaration as i}from"@intlayer/chokidar/build";import{listGitFiles as a,logConfigDetails as o}from"@intlayer/chokidar/cli";import{formatPath as s,parallelize as c}from"@intlayer/chokidar/utils";import{ANSIColors as l,colorize as u,colorizeKey as d,getAppLogger as f}from"@intlayer/config/logger";import{getConfiguration as p}from"@intlayer/config/node";import{getUnmergedDictionaries as m}from"@intlayer/unmerged-dictionaries-entry";import{getIntlayerAPIProxy as h}from"@intlayer/api";import*as g from"node:fs/promises";const _={pushed:{icon:`✔`,color:l.GREEN},modified:{icon:`✔`,color:l.GREEN},error:{icon:`✖`,color:l.RED},default:{icon:`⏲`,color:l.BLUE}},v=e=>_[e]??_.default,y=async s=>{let g=p(s?.configOptions);o(s?.configOptions);let _=f(g);s?.build===!0?await r(g,{forceRun:!0}):s?.build===void 0&&await r(g);try{if(!await e(g))return;let r=h(void 0,g),o=m(g),f=Object.values(o).flat(),p=Array.from(new Set(f.map(e=>e.location).filter(e=>e&&![`remote`,`local`,`hybrid`].includes(e)))),y=[];if(p.length>0){let{multiselect:e,confirm:t,isCancel:n}=await import(`@clack/prompts`);if(p.length===1){let e=await t({message:`Do you want to push dictionaries with custom location ${u(p[0],l.BLUE,l.RESET)}?`,initialValue:!1});if(n(e))return;e&&(y=[p[0]])}else{let t=await e({message:`Select custom locations to push:`,options:p.map(e=>({value:e,label:e})),required:!1});if(n(t))return;y=t}}let x=f.filter(e=>{let t=e.location??g.dictionary?.location??`local`;return t===`remote`||t===`hybrid`||y.includes(t)});if(x.length===0){_(`No dictionaries found to push. Only dictionaries with location ${u(`remote`,l.BLUE,l.RESET)}, ${u(`hybrid`,l.BLUE,l.RESET)} or selected custom locations are pushed.`,{level:`warn`}),_(`You can set the location in your dictionary file (e.g. ${u(`{ key: 'my-key', location: 'hybrid', ... }`,l.BLUE,l.RESET)} or globally in your intlayer.config.ts file (e.g. ${u(`{ dictionary: { location: 'hybrid' } }`,l.BLUE,l.RESET)}).`,{level:`info`});return}let S=Object.keys(o);if(s?.dictionaries){let e=s.dictionaries.filter(e=>!S.includes(e));e.length>0&&_(`The following dictionaries do not exist: ${e.join(`, `)} and have been ignored.`,{level:`error`}),x=x.filter(e=>s.dictionaries?.includes(e.key))}if(s?.gitOptions){let e=await a(s.gitOptions);x=x.filter(t=>e.includes(n(g.system.baseDir,t.filePath??``)))}if(x.length===0){_(`No local dictionaries found`,{level:`error`});return}_(`Pushing dictionaries:`);let C=x.map(e=>({dictionary:e,status:`pending`})),w=new t;w.update(C.map(e=>({dictionaryKey:e.dictionary.key,status:`pending`})));let T=[];await c(C,async e=>{e.status=`pushing`,w.update([{dictionaryKey:e.dictionary.key,status:`pushing`}]);try{let t=await r.dictionary.pushDictionaries([e.dictionary]),n=t.data?.updatedDictionaries??[],a=t.data?.newDictionaries??[],s=[...n,...a];for(let e of s){let t=o[e.key]?.find(t=>t.localId===e.localId);t&&await i({...t,id:e.id},g)}n.some(t=>t.key===e.dictionary.key)?(e.status=`modified`,T.push(e.dictionary),w.update([{dictionaryKey:e.dictionary.key,status:`modified`}])):a.some(t=>t.key===e.dictionary.key)?(e.status=`pushed`,T.push(e.dictionary),w.update([{dictionaryKey:e.dictionary.key,status:`pushed`}])):e.status=`unknown`}catch(t){e.status=`error`,e.error=t,e.errorMessage=`Error pushing dictionary ${e.dictionary.key}: ${t}`,w.update([{dictionaryKey:e.dictionary.key,status:`error`}])}},5),w.finish();for(let e of C){let{icon:t,color:n}=v(e.status);_(` - ${d(e.dictionary.key)} ${l.GREY}[${n}${t} ${e.status}${l.GREY}]${l.RESET}`)}for(let e of C)e.errorMessage&&_(e.errorMessage,{level:`error`});let E=s?.deleteLocaleDictionary,D=s?.keepLocaleDictionary;if(E&&D)throw Error(`Cannot specify both --deleteLocaleDictionary and --keepLocaleDictionary options.`);if(E)await b(T,s);else if(!D){let e=T.filter(e=>e.location===`remote`),t=e.map(e=>e.key);if(e.length>0){let{confirm:n,isCancel:r}=await import(`@clack/prompts`),i=await n({message:`Do you want to delete the local dictionaries that were successfully pushed? ${u(`(Dictionaries:`,l.GREY,l.RESET)} ${d(t)}${u(`)`,l.GREY,l.RESET)}`,initialValue:!1});if(r(i))return;i&&await b(e,s)}}}catch(e){_(e,{level:`error`})}},b=async(e,t)=>{let n=f(p(t?.configOptions)),r=new Set;for(let t of e){let{filePath:e}=t;if(!e){n(`Dictionary ${d(t.key)} does not have a file path`,{level:`error`});continue}r.add(e)}for(let e of r)try{let t=await g.lstat(e);t.isFile()?(await g.unlink(e),n(`Deleted file ${s(e)}`,{})):t.isDirectory()?n(`Path is a directory ${s(e)}, skipping.`,{}):n(`Unknown file type for ${s(e)}, skipping.`,{})}catch(t){n(`Error deleting ${s(e)}: ${t}`,{level:`error`})}};export{y as push};
|
|
2
2
|
//# sourceMappingURL=push.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{setupAI as e}from"../utils/setupAI.mjs";import{checkFileModifiedRange as t}from"../utils/checkFileModifiedRange.mjs";import{getOutputFilePath as n}from"../utils/getOutputFilePath.mjs";import{reviewFileBlockAware as r}from"./reviewDocBlockAware.mjs";import{existsSync as i}from"node:fs";import{join as a,relative as o}from"node:path";import{listGitFiles as s,listGitLines as c,logConfigDetails as l}from"@intlayer/chokidar/cli";import{
|
|
1
|
+
import{setupAI as e}from"../utils/setupAI.mjs";import{checkFileModifiedRange as t}from"../utils/checkFileModifiedRange.mjs";import{getOutputFilePath as n}from"../utils/getOutputFilePath.mjs";import{reviewFileBlockAware as r}from"./reviewDocBlockAware.mjs";import{existsSync as i}from"node:fs";import{join as a,relative as o}from"node:path";import{listGitFiles as s,listGitLines as c,logConfigDetails as l}from"@intlayer/chokidar/cli";import{formatLocale as u,formatPath as d,parallelize as f}from"@intlayer/chokidar/utils";import{ANSIColors as p,colorize as m,colorizeNumber as h,getAppLogger as g}from"@intlayer/config/logger";import{getConfiguration as _}from"@intlayer/config/node";import v from"fast-glob";const y=async({docPattern:y,locales:b,excludedGlobPattern:x,baseLocale:S,aiOptions:C,nbSimultaneousFileProcessed:w,configOptions:T,customInstructions:E,skipIfModifiedBefore:D,skipIfModifiedAfter:O,skipIfExists:k,gitOptions:A})=>{let j=_(T);l(T);let M=g(j),N=await e(j,C);if(!N?.hasAIAccess)return;let{aiClient:P,aiConfig:F}=N;w&&w>10&&(M(`Warning: nbSimultaneousFileProcessed is set to ${w}, which is greater than 10. Setting it to 10.`),w=10);let I=await v(y,{ignore:x});if(A){let e=await s(A);e&&(I=I.filter(t=>e.some(e=>a(process.cwd(),t)===e)))}M(`Base locale is ${u(S)}`),M(`Reviewing ${h(b.length)} locales: [ ${u(b)} ]`),M(`Reviewing ${h(I.length)} files:`),M(I.map(e=>` - ${d(e)}\n`)),await f(I.flatMap(e=>b.map(s=>async()=>{M(`Reviewing file: ${d(e)} to ${u(s)}`);let l=a(j.system.baseDir,e),f=n(l,s,S);if(k&&i(f)){let e=o(j.system.baseDir,f);M(`${m(`⊘`,p.YELLOW)} File ${d(e)} already exists, skipping.`);return}if(i(f)){let e=t(f,{skipIfModifiedBefore:D,skipIfModifiedAfter:O});if(e.isSkipped){M(e.message);return}}else (D||O)&&M(`${m(`!`,p.YELLOW)} File ${d(f)} does not exist, skipping modification date check.`);let h;if(A){let e=await c(l,A);M(`Git changed lines: ${e.join(`, `)}`),h=e}await r(l,f,s,S,C,T,E,h,P,F)})),e=>e(),w??3)};export{y as reviewDoc};
|
|
2
2
|
//# sourceMappingURL=reviewDoc.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readAsset as e}from"../_virtual/_utils_asset.mjs";import{sanitizeChunk as t,validateTranslation as n}from"../translateDoc/validation.mjs";import{mergeReviewedSegments as r}from"../translation-alignment/rebuildDocument.mjs";import{buildAlignmentPlan as i}from"../translation-alignment/pipeline.mjs";import{chunkInference as a}from"../utils/chunkInference.mjs";import{fixChunkStartEndChars as o}from"../utils/fixChunkStartEndChars.mjs";import{mkdirSync as s,writeFileSync as c}from"node:fs";import{dirname as l}from"node:path";import{
|
|
1
|
+
import{readAsset as e}from"../_virtual/_utils_asset.mjs";import{sanitizeChunk as t,validateTranslation as n}from"../translateDoc/validation.mjs";import{mergeReviewedSegments as r}from"../translation-alignment/rebuildDocument.mjs";import{buildAlignmentPlan as i}from"../translation-alignment/pipeline.mjs";import{chunkInference as a}from"../utils/chunkInference.mjs";import{fixChunkStartEndChars as o}from"../utils/fixChunkStartEndChars.mjs";import{mkdirSync as s,writeFileSync as c}from"node:fs";import{dirname as l}from"node:path";import{formatLocale as u,formatPath as d}from"@intlayer/chokidar/utils";import{ANSIColors as f,colon as p,colorize as m,colorizeNumber as h,getAppLogger as g}from"@intlayer/config/logger";import{getConfiguration as _}from"@intlayer/config/node";import{retryManager as v}from"@intlayer/config/utils";import{readFile as y}from"node:fs/promises";import{getLocaleName as b}from"@intlayer/core/localization";import*as x from"@intlayer/types/locales";const S=async(S,C,w,T,E,D,O,k,A,j)=>{let M=_(D),N=g(M),P=await y(S,`utf-8`),F=await y(C,`utf-8`).catch(()=>``),I=e(`./prompts/REVIEW_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${u(w,!1)}`).replaceAll(`{{baseLocaleName}}`,`${u(T,!1)}`).replace(`{{applicationContext}}`,E?.applicationContext??`-`).replace(`{{customInstructions}}`,O??`-`),L=[p(`${f.GREY_DARK}[${d(S)}${f.GREY_DARK}] `,{colSize:40}),`→ ${f.RESET}`].join(``),R=[p(`${f.GREY_DARK}[${d(S)}${f.GREY_DARK}][${u(w)}${f.GREY_DARK}] `,{colSize:40}),`→ ${f.RESET}`].join(``),{englishBlocks:z,frenchBlocks:B,plan:V,segmentsToReview:H}=i({englishText:P,frenchText:F,changedLines:k});if(N(`${L}Block-aware alignment complete. Total blocks: EN=${h(z.length)}, FR=${h(B.length)}`),N(`${L}Actions: reuse=${h(V.actions.filter(e=>e.kind===`reuse`).length)}, review=${h(V.actions.filter(e=>e.kind===`review`).length)}, new=${h(V.actions.filter(e=>e.kind===`insert_new`).length)}, delete=${h(V.actions.filter(e=>e.kind===`delete`).length)}`),H.length===0){N(`${L}No segments need review, reusing existing translation`),s(l(C),{recursive:!0}),c(C,r(V,B,new Map)),N(`${m(`✔`,f.GREEN)} File ${d(C)} updated successfully (no changes needed).`);return}N(`${L}Segments to review: ${h(H.length)}`);let U=new Map;for(let e of H){let r=H.indexOf(e)+1,i=e.englishBlock,s=()=>`**BLOCK ${r} of ${H.length}** is the base block in ${u(T,!1)} as reference.\n///chunksStart///\n`+i.content+`///chunksEnd///`,c=()=>`**BLOCK ${r} of ${H.length}** is the current block to review in ${u(w,!1)}.\n///chunksStart///\n`+(e.frenchBlockText??``)+`///chunksEnd///`,l=await v(async()=>{let e=await a([{role:`system`,content:I},{role:`system`,content:s()},{role:`system`,content:c()},{role:`system`,content:`The next user message will be the **BLOCK ${h(r)} of ${h(H.length)}** that should be translated in ${b(w,x.ENGLISH)} (${w}).`},{role:`user`,content:i.content}],E,M,A,j);N(`${R}${h(e.tokenUsed)} tokens used - Block ${h(r)} of ${h(H.length)}`);let l=t(e?.fileContent,i.content);if(l=o(l,i.content),!n(i.content,l,N))throw Error(`Validation failed for chunk (structure or length mismatch). Retrying...`);return l})();U.set(e.actionIndex,l)}let W=r(V,B,U);s(l(C),{recursive:!0}),c(C,W),N(`${m(`✔`,f.GREEN)} File ${d(C)} created/updated successfully.`)};export{S as reviewFileBlockAware};
|
|
2
2
|
//# sourceMappingURL=reviewDocBlockAware.mjs.map
|
package/dist/esm/test/test.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{listMissingTranslations as e}from"./listMissingTranslations.mjs";import{
|
|
1
|
+
import{listMissingTranslations as e}from"./listMissingTranslations.mjs";import{prepareIntlayer as t}from"@intlayer/chokidar/build";import{formatLocale as n,formatPath as r}from"@intlayer/chokidar/utils";import{ANSIColors as i,colon as a,colorize as o,colorizeKey as s,colorizeNumber as c,getAppLogger as l}from"@intlayer/config/logger";import{getConfiguration as u}from"@intlayer/config/node";const d=async d=>{let f=u(d?.configOptions),{locales:p,requiredLocales:m}=f.internationalization,h=l(f);d?.build===!0?await t(f,{forceRun:!0}):d?.build===void 0&&await t(f);let g=e(d?.configOptions),_=g.missingTranslations.map(e=>` - ${e.key}`).reduce((e,t)=>Math.max(e,t.length),0),v=g.missingTranslations.map(e=>n(e.locales,!1)).reduce((e,t)=>Math.max(e,t.length),0),y=g.missingTranslations.map(e=>[a(` - ${s(e.key)}`,{colSize:_,maxSize:40}),` - `,a(n(e.locales,i.RED),{colSize:v,maxSize:40}),e.filePath?` - ${r(e.filePath)}`:``,e.id?` - remote`:``].join(``));h(`Missing translations:`,{level:`info`}),y.forEach(e=>{h(e,{level:`info`})}),h(`Locales: ${n(p)}`),h(`Required locales: ${n(m??p)}`),h(`Missing locales: ${g.missingLocales.length===0?o(`-`,i.GREEN):n(g.missingLocales,i.RED)}`),h(`Missing required locales: ${g.missingRequiredLocales.length===0?o(`-`,i.GREEN):n(g.missingRequiredLocales,i.RED)}`),h(`Total missing locales: ${c(g.missingLocales.length,{one:i.RED,other:i.RED,zero:i.GREEN})}`),h(`Total missing required locales: ${c(g.missingRequiredLocales.length,{one:i.RED,other:i.RED,zero:i.GREEN})}`),g.missingRequiredLocales.length>0&&process.exit(1)};export{d as testMissingTranslations};
|
|
2
2
|
//# sourceMappingURL=test.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{setupAI as e}from"../utils/setupAI.mjs";import{checkFileModifiedRange as t}from"../utils/checkFileModifiedRange.mjs";import{getOutputFilePath as n}from"../utils/getOutputFilePath.mjs";import{translateFile as r}from"./translateFile.mjs";import{existsSync as i,mkdirSync as a,writeFileSync as o}from"node:fs";import{dirname as s,join as c}from"node:path";import{listGitFiles as l,logConfigDetails as u}from"@intlayer/chokidar/cli";import{
|
|
1
|
+
import{setupAI as e}from"../utils/setupAI.mjs";import{checkFileModifiedRange as t}from"../utils/checkFileModifiedRange.mjs";import{getOutputFilePath as n}from"../utils/getOutputFilePath.mjs";import{translateFile as r}from"./translateFile.mjs";import{existsSync as i,mkdirSync as a,writeFileSync as o}from"node:fs";import{dirname as s,join as c}from"node:path";import{listGitFiles as l,logConfigDetails as u}from"@intlayer/chokidar/cli";import{pLimit as d,parallelize as f}from"@intlayer/chokidar/utils";import{ANSIColors as p,colorize as m,colorizeNumber as h,getAppLogger as g}from"@intlayer/config/logger";import{getConfiguration as _}from"@intlayer/config/node";import v from"fast-glob";import{performance as y}from"node:perf_hooks";const b=async({docPattern:b,locales:x,excludedGlobPattern:S,baseLocale:C,aiOptions:w,nbSimultaneousFileProcessed:T=20,configOptions:E,customInstructions:D,skipIfModifiedBefore:O,skipIfModifiedAfter:k,skipIfExists:A,gitOptions:j,flushStrategy:M=`incremental`})=>{let N=_(E);u(E);let P=g(N),F=T,I=d(F),L=await v(b,{ignore:S}),R=await e(N,w);if(!R?.hasAIAccess)return;let{aiClient:z,aiConfig:B}=R;if(j){let e=await l(j);e&&(L=L.filter(t=>e.some(e=>c(process.cwd(),t)===e)))}let V=y.now();P(`Translating ${h(L.length)} files to ${h(x.length)} locales. \nGlobal Concurrency: ${h(F)} chunks in parallel.`);let H={count:0,maxErrors:5,shouldStop:!1};await f(L.flatMap(e=>x.map(l=>async()=>{if(H.shouldStop)return;let u=c(N.system.baseDir,e),d=n(u,l,C);if(A&&i(d))return;M===`incremental`&&!i(d)&&(a(s(d),{recursive:!0}),o(d,``));let f=t(d,{skipIfModifiedBefore:O,skipIfModifiedAfter:k});if(f.isSkipped){P(f.message);return}await r({baseFilePath:u,outputFilePath:d,locale:l,baseLocale:C,configuration:N,errorState:H,aiOptions:w,customInstructions:D,aiClient:z,aiConfig:B,flushStrategy:M,limit:I})})),e=>e(),50);let U=((y.now()-V)/1e3).toFixed(2);H.count>0?P(`Finished with ${H.count} errors in ${U}s.`):P(`${m(`✔`,p.GREEN)} Batch completed successfully in ${h(U)}s.`)};export{b as translateDoc};
|
|
2
2
|
//# sourceMappingURL=translateDoc.mjs.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{readAsset as e}from"../_virtual/_utils_asset.mjs";import{sanitizeChunk as t,validateTranslation as n}from"./validation.mjs";import{chunkInference as r}from"../utils/chunkInference.mjs";import{fixChunkStartEndChars as i}from"../utils/fixChunkStartEndChars.mjs";import{chunkText as a}from"../utils/calculateChunks.mjs";import{mkdirSync as o,writeFileSync as s}from"node:fs";import{dirname as c,relative as l}from"node:path";import{
|
|
2
|
-
`)},{role:`user`,content:`>>> TARGET CHUNK START <<<\n${
|
|
1
|
+
import{readAsset as e}from"../_virtual/_utils_asset.mjs";import{sanitizeChunk as t,validateTranslation as n}from"./validation.mjs";import{chunkInference as r}from"../utils/chunkInference.mjs";import{fixChunkStartEndChars as i}from"../utils/fixChunkStartEndChars.mjs";import{chunkText as a}from"../utils/calculateChunks.mjs";import{mkdirSync as o,writeFileSync as s}from"node:fs";import{dirname as c,relative as l}from"node:path";import{formatLocale as u,formatPath as d}from"@intlayer/chokidar/utils";import{ANSIColors as f,colon as p,colorize as m,colorizeNumber as h,getAppLogger as g}from"@intlayer/config/logger";import{retryManager as _}from"@intlayer/config/utils";import{readFile as v}from"node:fs/promises";import{performance as y}from"node:perf_hooks";const b=async({baseFilePath:b,outputFilePath:x,locale:S,baseLocale:C,configuration:w,errorState:T,aiOptions:E,customInstructions:D,aiClient:O,aiConfig:k,flushStrategy:A=`incremental`,onChunkReceive:j,limit:M})=>{if(T.shouldStop)return null;let N=g(w,{config:{prefix:``}}),P=y.now();try{let F=a(await v(b,`utf-8`)),I=F.length,L=`${p(`${f.GREY_DARK}[${d(b)}${f.GREY_DARK}] `,{colSize:40})}${f.RESET}`,R=`${p(`${f.GREY_DARK}[${d(b)}${f.GREY_DARK}][${u(S)}${f.GREY_DARK}] `,{colSize:40})}${f.RESET}`;N(`${L}Split into ${h(I)} chunks. Queuing...`);let z=e(`./prompts/TRANSLATE_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${u(S,!1)}`).replaceAll(`{{baseLocaleName}}`,`${u(C,!1)}`).replace(`{{applicationContext}}`,E?.applicationContext??`-`).replace(`{{customInstructions}}`,D??`-`),B=Array(I).fill(``),V=M??(e=>e()),H=F.map((e,a)=>V(async()=>{if(T.shouldStop)return null;let l=g(w,{config:{prefix:`${R} ${f.GREY_DARK}[${a+1}/${I}] ${f.RESET}`}}),u=y.now(),d=a===0,p=e.content,m=()=>">>> CONTEXT: PREVIOUS SOURCE CONTENT <<<\n```\n"+(F[a-1]?.content??``)+"\n```\n>>> END PREVIOUS CONTEXT <<<",v=()=>">>> CONTEXT: NEXT CONTENT <<<\n```\n"+(F[a+1]?.content??``)+"\n```\n>>> END NEXT CONTEXT <<<";l(`Process started`);let{content:b,tokens:S}=await _(async()=>{let e=await r([{role:`system`,content:z},...F[a+1]?[{role:`system`,content:v()}]:[],...d?[]:[{role:`system`,content:m()}],{role:`system`,content:[`You are translating TARGET CHUNK (${a+1}/${I}).`,`Translate ONLY the target chunk. Preserve frontmatter/code exactly.`].join(`
|
|
2
|
+
`)},{role:`user`,content:`>>> TARGET CHUNK START <<<\n${p}\n>>> TARGET CHUNK END <<<`}],E,w,O,k),o=t(e?.fileContent,p);if(o=i(o,p),!n(p,o,l))throw Error(`Validation failed for chunk ${a+1}/${I}`);return{content:o,tokens:e.tokenUsed}})(),C=(y.now()-u).toFixed(0);if(B[a]=b,j&&j(b,a,I),A===`incremental`&&B.slice(0,a+1).every(e=>e&&e!==``)){let e=0;for(;e<I&&B[e]&&B[e]!==``;)e++;let t=B.slice(0,e).join(``);o(c(x),{recursive:!0}),s(x,t)}l([`${h(S)} tokens used `,`${f.GREY_DARK}in ${h(C)}ms${f.RESET}`].join(``))}));await Promise.all(H);let U=B.join(``);(A===`end`||A===`incremental`)&&(o(c(x),{recursive:!0}),s(x,U));let W=((y.now()-P)/1e3).toFixed(2),G=l(w.system.baseDir,x);return N(`${m(`✔`,f.GREEN)} File ${d(G)} completed in ${h(W)}s.`),U}catch(e){T.count++;let t=e?.message??JSON.stringify(e);return N(`${m(`✖`,f.RED)} Error: ${t}`),T.count>=T.maxErrors&&(T.shouldStop=!0),null}};export{b as translateFile};
|
|
3
3
|
//# sourceMappingURL=translateFile.mjs.map
|
package/dist/esm/watch.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{logConfigDetails as e}from"@intlayer/chokidar/cli";import{
|
|
1
|
+
import{logConfigDetails as e}from"@intlayer/chokidar/cli";import{runParallel as t}from"@intlayer/chokidar/utils";import{getAppLogger as n}from"@intlayer/config/logger";import{getConfiguration as r}from"@intlayer/config/node";import{watch as i}from"@intlayer/chokidar/watcher";const a=async a=>{let o=r(a?.configOptions);e(a?.configOptions);let s=n(o),c;a?.with&&(c=t(a.with),c.result.catch(()=>{process.exit(1)}));let l=i({persistent:!0,skipPrepare:a?.skipPrepare??!1}),u=async()=>{process.off(`SIGINT`,u),process.off(`SIGTERM`,u),s(`Stopping Intlayer watcher...`);try{await l.close(),c&&`child`in c&&c.child?.kill(`SIGTERM`)}catch(e){console.error(`Error during shutdown:`,e)}finally{process.exit(0)}};process.on(`SIGINT`,u),process.on(`SIGTERM`,u)};export{a as watchContentDeclaration};
|
|
2
2
|
//# sourceMappingURL=watch.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract.d.ts","names":[],"sources":["../../src/extract.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"extract.d.ts","names":[],"sources":["../../src/extract.ts"],"mappings":";;;;KAyBK,cAAA;EACH,KAAA;EACA,MAAA,GAAS,eAAA;EACT,aAAA,GAAgB,uBAAA;EAChB,QAAA;EACA,eAAA;AAAA;AAAA,cAGW,OAAA,GAAiB,OAAA,EAAS,cAAA,KAAc,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/cli",
|
|
3
|
-
"version": "8.3.
|
|
3
|
+
"version": "8.3.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Provides uniform command-line interface scripts for Intlayer, used in packages like intlayer-cli and intlayer.",
|
|
6
6
|
"keywords": [
|
|
@@ -67,16 +67,16 @@
|
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@clack/prompts": "0.11.0",
|
|
70
|
-
"@intlayer/ai": "8.3.
|
|
71
|
-
"@intlayer/api": "8.3.
|
|
72
|
-
"@intlayer/babel": "8.3.
|
|
73
|
-
"@intlayer/chokidar": "8.3.
|
|
74
|
-
"@intlayer/config": "8.3.
|
|
75
|
-
"@intlayer/core": "8.3.
|
|
76
|
-
"@intlayer/dictionaries-entry": "8.3.
|
|
77
|
-
"@intlayer/remote-dictionaries-entry": "8.3.
|
|
78
|
-
"@intlayer/types": "8.3.
|
|
79
|
-
"@intlayer/unmerged-dictionaries-entry": "8.3.
|
|
70
|
+
"@intlayer/ai": "8.3.1",
|
|
71
|
+
"@intlayer/api": "8.3.1",
|
|
72
|
+
"@intlayer/babel": "8.3.1",
|
|
73
|
+
"@intlayer/chokidar": "8.3.1",
|
|
74
|
+
"@intlayer/config": "8.3.1",
|
|
75
|
+
"@intlayer/core": "8.3.1",
|
|
76
|
+
"@intlayer/dictionaries-entry": "8.3.1",
|
|
77
|
+
"@intlayer/remote-dictionaries-entry": "8.3.1",
|
|
78
|
+
"@intlayer/types": "8.3.1",
|
|
79
|
+
"@intlayer/unmerged-dictionaries-entry": "8.3.1",
|
|
80
80
|
"commander": "14.0.3",
|
|
81
81
|
"enquirer": "^2.4.1",
|
|
82
82
|
"eventsource": "4.1.0",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"vitest": "4.0.18"
|
|
94
94
|
},
|
|
95
95
|
"peerDependencies": {
|
|
96
|
-
"@intlayer/ai": "8.3.
|
|
96
|
+
"@intlayer/ai": "8.3.1"
|
|
97
97
|
},
|
|
98
98
|
"peerDependenciesMeta": {
|
|
99
99
|
"@intlayer/ai": {
|