@intlayer/cli 8.3.0-canary.0 → 8.3.0-canary.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/ci.cjs +1 -1
- package/dist/cjs/ci.cjs.map +1 -1
- package/dist/cjs/extract.cjs +1 -1
- package/dist/cjs/extract.cjs.map +1 -1
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/push/push.cjs +1 -1
- package/dist/cjs/push/push.cjs.map +1 -1
- package/dist/cjs/reviewDoc/reviewDocBlockAware.cjs +1 -1
- package/dist/cjs/translateDoc/translateFile.cjs +2 -2
- package/dist/esm/ci.mjs +1 -1
- package/dist/esm/ci.mjs.map +1 -1
- package/dist/esm/extract.mjs +1 -1
- package/dist/esm/extract.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/push/push.mjs +1 -1
- package/dist/esm/reviewDoc/reviewDocBlockAware.mjs +1 -1
- package/dist/esm/translateDoc/translateFile.mjs +2 -2
- package/dist/types/extract.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/package.json +14 -14
package/dist/cjs/ci.cjs
CHANGED
|
@@ -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/chokidar/cli`),n=require(`@intlayer/config/logger`),r=require(`node:child_process`);const i=()=>{let e=process.env.npm_config_user_agent;return e?.startsWith(`bun`)?{command:`bun`,args:[`intlayer`]}:e?.startsWith(`pnpm`)?{command:`pnpm`,args:[`exec`,`intlayer`]}:e?.startsWith(`yarn`)?{command:`yarn`,args:[`run`,`intlayer`]}:{command:`npx`,args:[`intlayer`]}},a=async a=>{let o=process.env.INTLAYER_PROJECT_CREDENTIALS,s={};if(o)try{s=JSON.parse(o)}catch{(0,n.logger)(`INTLAYER_PROJECT_CREDENTIALS is not valid JSON. Proceeding without credentials.`,{level:`warn`})}let c=process.cwd(),{projectsPath:l}=await(0,t.listProjects)();if(l.length===0){(0,n.logger)(`No Intlayer projects found.`,{level:`warn`});return}let u=l.find(e=>c===e),d=u?[u]:l,{command:f,args:p}=i(),m=[...p,...a];(0,n.logger)(`CI: Using package manager: ${f}`,{level:`
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`./_virtual/_rolldown/runtime.cjs`);let e=require(`node:path`),t=require(`@intlayer/chokidar/cli`),n=require(`@intlayer/config/logger`),r=require(`node:child_process`);const i=()=>{let e=process.env.npm_config_user_agent;return e?.startsWith(`bun`)?{command:`bun`,args:[`intlayer`]}:e?.startsWith(`pnpm`)?{command:`pnpm`,args:[`exec`,`intlayer`]}:e?.startsWith(`yarn`)?{command:`yarn`,args:[`run`,`intlayer`]}:{command:`npx`,args:[`intlayer`]}},a=async a=>{let o=process.env.INTLAYER_PROJECT_CREDENTIALS,s={};if(o)try{s=JSON.parse(o)}catch{(0,n.logger)(`INTLAYER_PROJECT_CREDENTIALS is not valid JSON. Proceeding without credentials.`,{level:`warn`})}let c=process.cwd(),{projectsPath:l}=await(0,t.listProjects)();if(l.length===0){(0,n.logger)(`No Intlayer projects found.`,{level:`warn`});return}let u=l.find(e=>c===e),d=u?[u]:l,{command:f,args:p}=i(),m=[...p,...a];(0,n.logger)(`CI: Using package manager: ${f}`,{level:`info`,isVerbose:!0}),u?(0,n.logger)(`CI: Detected project context: ${u}`,{level:`info`}):(0,n.logger)(`CI: No specific project context detected. Iterating over ${d.length} discovered projects...`,{level:`info`});let h=!1;for(let t of d){let i=Object.entries(s).find(([n])=>(0,e.resolve)(n)===t||t.endsWith((0,e.normalize)(n)))?.[1];(0,n.logger)(`\nCI: Executing for ${t}...`,{level:`info`});let a={...process.env};i?(a.INTLAYER_CLIENT_ID=i.clientId,a.INTLAYER_CLIENT_SECRET=i.clientSecret):o&&(0,n.logger)(`CI: No matching credentials found for ${t} in INTLAYER_PROJECT_CREDENTIALS.`,{isVerbose:!0}),(0,r.spawnSync)(f,m,{cwd:t,stdio:`inherit`,env:a}).status!==0&&((0,n.logger)(`CI: Failed for ${t}`,{level:`error`}),h=!0)}h&&process.exit(1)};exports.runCI=a;
|
|
2
2
|
//# sourceMappingURL=ci.cjs.map
|
package/dist/cjs/ci.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ci.cjs","names":[],"sources":["../../src/ci.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport { normalize, resolve } from 'node:path';\nimport { listProjects } from '@intlayer/chokidar/cli';\nimport { logger } from '@intlayer/config/logger';\n\n// Helper to detect the package manager used to run the command\nconst getPackageManagerCommand = () => {\n const userAgent = process.env.npm_config_user_agent;\n\n if (userAgent?.startsWith('bun')) {\n return { command: 'bun', args: ['intlayer'] }; // Bun runs local bins natively\n }\n if (userAgent?.startsWith('pnpm')) {\n return { command: 'pnpm', args: ['exec', 'intlayer'] }; // pnpm requires 'exec'\n }\n if (userAgent?.startsWith('yarn')) {\n return { command: 'yarn', args: ['run', 'intlayer'] }; // yarn requires 'run' or 'exec'\n }\n\n // Default fallback\n return { command: 'npx', args: ['intlayer'] };\n};\n\nexport const runCI = async (commands: string[]) => {\n const credentialsEnv = process.env.INTLAYER_PROJECT_CREDENTIALS;\n let credentials: Record<string, { clientId: string; clientSecret: string }> =\n {};\n\n // Parse Credentials (Optional now)\n if (credentialsEnv) {\n try {\n credentials = JSON.parse(credentialsEnv);\n } catch {\n logger(\n 'INTLAYER_PROJECT_CREDENTIALS is not valid JSON. Proceeding without credentials.',\n {\n level: 'warn',\n }\n );\n }\n }\n\n const cwd = process.cwd();\n\n // Discover Projects\n const { projectsPath } = await listProjects();\n\n if (projectsPath.length === 0) {\n logger('No Intlayer projects found.', { level: 'warn' });\n return;\n }\n\n // 3. Determine Context: Single Project vs All Projects\n // Check if the current directory matches one of the discovered project paths\n const currentProject = projectsPath.find((p) => cwd === p);\n const projectsToRun = currentProject ? [currentProject] : projectsPath;\n\n const { command, args: pmArgs } = getPackageManagerCommand();\n const finalArgs = [...pmArgs, ...commands];\n\n logger(`CI: Using package manager: ${command}`, {
|
|
1
|
+
{"version":3,"file":"ci.cjs","names":[],"sources":["../../src/ci.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport { normalize, resolve } from 'node:path';\nimport { listProjects } from '@intlayer/chokidar/cli';\nimport { logger } from '@intlayer/config/logger';\n\n// Helper to detect the package manager used to run the command\nconst getPackageManagerCommand = () => {\n const userAgent = process.env.npm_config_user_agent;\n\n if (userAgent?.startsWith('bun')) {\n return { command: 'bun', args: ['intlayer'] }; // Bun runs local bins natively\n }\n if (userAgent?.startsWith('pnpm')) {\n return { command: 'pnpm', args: ['exec', 'intlayer'] }; // pnpm requires 'exec'\n }\n if (userAgent?.startsWith('yarn')) {\n return { command: 'yarn', args: ['run', 'intlayer'] }; // yarn requires 'run' or 'exec'\n }\n\n // Default fallback\n return { command: 'npx', args: ['intlayer'] };\n};\n\nexport const runCI = async (commands: string[]) => {\n const credentialsEnv = process.env.INTLAYER_PROJECT_CREDENTIALS;\n let credentials: Record<string, { clientId: string; clientSecret: string }> =\n {};\n\n // Parse Credentials (Optional now)\n if (credentialsEnv) {\n try {\n credentials = JSON.parse(credentialsEnv);\n } catch {\n logger(\n 'INTLAYER_PROJECT_CREDENTIALS is not valid JSON. Proceeding without credentials.',\n {\n level: 'warn',\n }\n );\n }\n }\n\n const cwd = process.cwd();\n\n // Discover Projects\n const { projectsPath } = await listProjects();\n\n if (projectsPath.length === 0) {\n logger('No Intlayer projects found.', { level: 'warn' });\n return;\n }\n\n // 3. Determine Context: Single Project vs All Projects\n // Check if the current directory matches one of the discovered project paths\n const currentProject = projectsPath.find((p) => cwd === p);\n const projectsToRun = currentProject ? [currentProject] : projectsPath;\n\n const { command, args: pmArgs } = getPackageManagerCommand();\n const finalArgs = [...pmArgs, ...commands];\n\n logger(`CI: Using package manager: ${command}`, {\n level: 'info',\n isVerbose: true,\n });\n\n if (currentProject) {\n logger(`CI: Detected project context: ${currentProject}`, {\n level: 'info',\n });\n } else {\n logger(\n `CI: No specific project context detected. Iterating over ${projectsToRun.length} discovered projects...`,\n {\n level: 'info',\n }\n );\n }\n\n let hasError = false;\n\n // Iterate and Execute\n for (const projectPath of projectsToRun) {\n // Attempt to match credentials to the project path\n // We check if the key (relative or absolute) matches the resolved project path\n const credsEntry = Object.entries(credentials).find(([key]) => {\n const absKey = resolve(key);\n return absKey === projectPath || projectPath.endsWith(normalize(key));\n });\n\n const creds = credsEntry?.[1];\n\n logger(`\\nCI: Executing for ${projectPath}...`, {\n level: 'info',\n });\n\n const envVars = { ...process.env };\n\n if (creds) {\n envVars.INTLAYER_CLIENT_ID = creds.clientId;\n envVars.INTLAYER_CLIENT_SECRET = creds.clientSecret;\n } else if (credentialsEnv) {\n logger(\n `CI: No matching credentials found for ${projectPath} in INTLAYER_PROJECT_CREDENTIALS.`,\n { isVerbose: true }\n );\n }\n\n const result = spawnSync(command, finalArgs, {\n cwd: projectPath,\n stdio: 'inherit',\n env: envVars,\n });\n\n if (result.status !== 0) {\n logger(`CI: Failed for ${projectPath}`, {\n level: 'error',\n });\n hasError = true;\n }\n }\n\n if (hasError) process.exit(1);\n};\n"],"mappings":"mPAMA,MAAM,MAAiC,CACrC,IAAM,EAAY,QAAQ,IAAI,sBAa9B,OAXI,GAAW,WAAW,MAAM,CACvB,CAAE,QAAS,MAAO,KAAM,CAAC,WAAW,CAAE,CAE3C,GAAW,WAAW,OAAO,CACxB,CAAE,QAAS,OAAQ,KAAM,CAAC,OAAQ,WAAW,CAAE,CAEpD,GAAW,WAAW,OAAO,CACxB,CAAE,QAAS,OAAQ,KAAM,CAAC,MAAO,WAAW,CAAE,CAIhD,CAAE,QAAS,MAAO,KAAM,CAAC,WAAW,CAAE,EAGlC,EAAQ,KAAO,IAAuB,CACjD,IAAM,EAAiB,QAAQ,IAAI,6BAC/B,EACF,EAAE,CAGJ,GAAI,EACF,GAAI,CACF,EAAc,KAAK,MAAM,EAAe,MAClC,EACN,EAAA,EAAA,QACE,kFACA,CACE,MAAO,OACR,CACF,CAIL,IAAM,EAAM,QAAQ,KAAK,CAGnB,CAAE,gBAAiB,MAAA,EAAA,EAAA,eAAoB,CAE7C,GAAI,EAAa,SAAW,EAAG,EAC7B,EAAA,EAAA,QAAO,8BAA+B,CAAE,MAAO,OAAQ,CAAC,CACxD,OAKF,IAAM,EAAiB,EAAa,KAAM,GAAM,IAAQ,EAAE,CACpD,EAAgB,EAAiB,CAAC,EAAe,CAAG,EAEpD,CAAE,UAAS,KAAM,GAAW,GAA0B,CACtD,EAAY,CAAC,GAAG,EAAQ,GAAG,EAAS,EAE1C,EAAA,EAAA,QAAO,8BAA8B,IAAW,CAC9C,MAAO,OACP,UAAW,GACZ,CAAC,CAEE,GACF,EAAA,EAAA,QAAO,iCAAiC,IAAkB,CACxD,MAAO,OACR,CAAC,EAEF,EAAA,EAAA,QACE,4DAA4D,EAAc,OAAO,yBACjF,CACE,MAAO,OACR,CACF,CAGH,IAAI,EAAW,GAGf,IAAK,IAAM,KAAe,EAAe,CAQvC,IAAM,EALa,OAAO,QAAQ,EAAY,CAAC,MAAM,CAAC,MAEpD,EAAA,EAAA,SADuB,EAAI,GACT,GAAe,EAAY,UAAA,EAAA,EAAA,WAAmB,EAAI,CAAC,CACrE,GAEyB,IAE3B,EAAA,EAAA,QAAO,uBAAuB,EAAY,KAAM,CAC9C,MAAO,OACR,CAAC,CAEF,IAAM,EAAU,CAAE,GAAG,QAAQ,IAAK,CAE9B,GACF,EAAQ,mBAAqB,EAAM,SACnC,EAAQ,uBAAyB,EAAM,cAC9B,IACT,EAAA,EAAA,QACE,yCAAyC,EAAY,mCACrD,CAAE,UAAW,GAAM,CACpB,EASH,EAAA,EAAA,WANyB,EAAS,EAAW,CAC3C,IAAK,EACL,MAAO,UACP,IAAK,EACN,CAAC,CAES,SAAW,KACpB,EAAA,EAAA,QAAO,kBAAkB,IAAe,CACtC,MAAO,QACR,CAAC,CACF,EAAW,IAIX,GAAU,QAAQ,KAAK,EAAE"}
|
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:
|
|
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/cli`),a=require(`@intlayer/config/logger`),o=require(`@intlayer/config/node`),s=require(`@intlayer/unmerged-dictionaries-entry`),c=require(`enquirer`);c=e.__toESM(c);let l=require(`fast-glob`);l=e.__toESM(l);const u=async e=>{let u=(0,o.getConfiguration)(e.configOptions);(0,i.logConfigDetails)(e?.configOptions);let d=(0,a.getAppLogger)(u),{baseDir:f}=u.system,{codeDir:p,excludedPath:m}=u.content,{traversePattern:h}=u.build,g=e=>(0,a.colorizePath)((0,n.relative)(f,e)),_=(0,r.detectPackageName)(f),v=e.files??[];if(v.length===0){let e=e=>(m??[]).some(t=>{let n=t.split(`/`).filter(e=>!e.includes(`*`)&&e.length>0),r=e.split(`/`);return n.some(e=>r.includes(e))}),r=(await Promise.all(p.filter(t=>!e(t)).map(e=>(0,l.default)(h,{cwd:e,ignore:m,absolute:!0})))).flat(),i=[...new Set(r)].filter(e=>(0,t.existsSync)(e)).map(e=>({value:e,label:(0,n.relative)(f,e)}));if(i.length===0){d(`No extractable files found in the project.`);return}let a=`__select_all__`,o;try{let e=Math.max((process.stdout.columns||80)-15,20),t=t=>t.length>e?`...${t.slice(-(e-3))}`:t,{files:n}=await c.default.prompt({type:`autocomplete`,name:`files`,message:`Select files to extract (Type to search):`,multiple:!0,limit:40,choices:[{name:a,message:`────── Select all ──────`},...i.map(e=>({name:e.value,message:t(e.label)}))],async toggle(e,t){if(!(!e||e.disabled))return e.enabled=t??!e.enabled,e.name===a&&this.choices.filter(e=>e.name!==a).forEach(t=>{t.enabled=e.enabled}),this.render()},format(){return this.state?.submitted&&this.options?.multiple?`${this.selected.filter(e=>e.name!==a).length} file(s) selected`:this.input??``}});o=n.filter(e=>e!==a)}catch{o=Symbol(`cancel`)}typeof o==`symbol`&&process.exit(0),v=o}if(v.length===0){d(`No files selected for extraction.`);return}let y=v.map(e=>(0,n.resolve)(f,e)).filter(e=>(0,t.existsSync)(e)?!0:(d(`File not found: ${g(e)}`),!1));if(y.length===0)return;let b=(0,s.getUnmergedDictionaries)(u);await Promise.all(y.map(async t=>{try{await(0,r.extractContent)(t,_,{unmergedDictionaries:b,configuration:u,codeOnly:e.codeOnly,declarationOnly:e.declarationOnly})}catch(e){d(`Failed to transform ${t}: ${e.message}`)}}))};exports.extract=u;
|
|
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 { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport { extractContent, type PackageName } from '@intlayer/babel';\nimport { logConfigDetails } from '@intlayer/chokidar/cli';\nimport { colorizePath, getAppLogger } 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';\nimport fg from 'fast-glob';\n\ntype ExtractOptions = {\n files?: string[];\n output?: FilePathPattern;\n configOptions?: GetConfigurationOptions;\n codeOnly?: boolean;\n declarationOnly?: boolean;\n};\n\n// Helper to read package.json dependencies\nconst getDependencies = async (baseDir: string) => {\n try {\n const packageJsonPath = resolve(baseDir, 'package.json');\n if (!existsSync(packageJsonPath)) {\n // Try parent directory if not found in baseDir\n return {};\n }\n const file = await readFile(packageJsonPath, 'utf8');\n const packageJSON = JSON.parse(file);\n\n return packageJSON.dependencies;\n } catch {\n return {};\n }\n};\n\nexport const extract = async (options: ExtractOptions) => {\n const configuration = getConfiguration(options.configOptions);\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(configuration);\n const { baseDir, codeDir, excludedPath } = configuration.content;\n const { traversePattern } = configuration.build;\n\n const formatPath = (path: string) => {\n const relativePath = relative(baseDir, path);\n return colorizePath(relativePath);\n };\n\n // Detect package\n const dependencies = await getDependencies(baseDir);\n let packageName: PackageName = 'react-intlayer';\n\n if (dependencies['next-intlayer']) {\n packageName = 'next-intlayer';\n } else if (dependencies['vue-intlayer']) {\n packageName = 'vue-intlayer';\n } else if (dependencies['svelte-intlayer']) {\n packageName = 'svelte-intlayer';\n } else if (dependencies['react-intlayer']) {\n packageName = 'react-intlayer';\n } else if (dependencies['preact-intlayer']) {\n packageName = 'preact-intlayer';\n } else if (dependencies['solid-intlayer']) {\n packageName = 'solid-intlayer';\n } else if (dependencies['angular-intlayer']) {\n packageName = 'angular-intlayer';\n } else if (dependencies['express-intlayer']) {\n packageName = 'express-intlayer';\n }\n\n let filesToExtract = options.files ?? [];\n\n if (filesToExtract.length === 0) {\n // Filter out codeDirs that are themselves inside an excluded path (e.g. dist, node_modules)\n const isDirExcluded = (dirPath: string): boolean =>\n (excludedPath ?? []).some((pattern) => {\n const segments = pattern\n .split('/')\n .filter((s) => !s.includes('*') && s.length > 0);\n const parts = dirPath.split('/');\n return segments.some((seg) => parts.includes(seg));\n });\n\n // Await all promises simultaneously\n const resultsArray = await Promise.all(\n codeDir\n .filter((dir) => !isDirExcluded(dir))\n .map((dir) =>\n fg(traversePattern, {\n cwd: dir,\n ignore: excludedPath,\n absolute: true,\n })\n )\n );\n\n // Flatten the nested arrays and remove duplicates\n const allFiles = resultsArray.flat();\n\n const uniqueFiles = [...new Set(allFiles)].filter((file) =>\n existsSync(file)\n );\n\n // Relative paths for selection\n const choices = uniqueFiles.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 output: options.output,\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"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"extract.cjs","names":[],"sources":["../../src/extract.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport {\n detectPackageName,\n extractContent,\n type PackageName,\n} from '@intlayer/babel';\nimport { logConfigDetails } from '@intlayer/chokidar/cli';\nimport { colorizePath, getAppLogger } 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';\nimport fg from 'fast-glob';\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 logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(configuration);\n const { baseDir } = configuration.system;\n const { codeDir, excludedPath } = configuration.content;\n const { traversePattern } = configuration.build;\n\n const formatPath = (path: string) => {\n const relativePath = relative(baseDir, path);\n return colorizePath(relativePath);\n };\n\n // Detect package\n const packageName: PackageName = detectPackageName(baseDir);\n\n let filesToExtract = options.files ?? [];\n\n if (filesToExtract.length === 0) {\n // Filter out codeDirs that are themselves inside an excluded path (e.g. dist, node_modules)\n const isDirExcluded = (dirPath: string): boolean =>\n (excludedPath ?? []).some((pattern) => {\n const segments = pattern\n .split('/')\n .filter((s) => !s.includes('*') && s.length > 0);\n const parts = dirPath.split('/');\n return segments.some((seg) => parts.includes(seg));\n });\n\n // Await all promises simultaneously\n const resultsArray = await Promise.all(\n codeDir\n .filter((dir) => !isDirExcluded(dir))\n .map((dir) =>\n fg(traversePattern, {\n cwd: dir,\n ignore: excludedPath,\n absolute: true,\n })\n )\n );\n\n // Flatten the nested arrays and remove duplicates\n const allFiles = resultsArray.flat();\n\n const uniqueFiles = [...new Set(allFiles)].filter((file) =>\n existsSync(file)\n );\n\n // Relative paths for selection\n const choices = uniqueFiles.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"],"mappings":"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"}
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./extract.cjs`),t=require(`./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./extract.cjs`),t=require(`./listProjects.cjs`),n=require(`./liveSync.cjs`),r=require(`./listContentDeclaration.cjs`),i=require(`./init.cjs`),a=require(`./editor.cjs`),o=require(`./build.cjs`),s=require(`./test/listMissingTranslations.cjs`),c=require(`./test/test.cjs`),l=require(`./fill/fill.cjs`),u=require(`./initSkills.cjs`),d=require(`./pull.cjs`),f=require(`./push/push.cjs`),p=require(`./pushConfig.cjs`),m=require(`./reviewDoc/reviewDoc.cjs`),h=require(`./searchDoc.cjs`),g=require(`./translateDoc/translateDoc.cjs`),_=require(`./cli.cjs`);exports.PLATFORM_OPTIONS=u.PLATFORM_OPTIONS,exports.build=o.build,exports.dirname=_.dirname,exports.extract=e.extract,exports.fill=l.fill,exports.findProjectRoot=i.findProjectRoot,exports.getDetectedPlatform=u.getDetectedPlatform,exports.init=i.init,exports.initSkills=u.initSkills,exports.listContentDeclaration=r.listContentDeclaration,exports.listContentDeclarationRows=r.listContentDeclarationRows,exports.listMissingTranslations=s.listMissingTranslations,exports.listMissingTranslationsWithConfig=s.listMissingTranslationsWithConfig,exports.listProjectsCommand=t.listProjectsCommand,exports.liveSync=n.liveSync,exports.pull=d.pull,exports.push=f.push,exports.pushConfig=p.pushConfig,exports.reviewDoc=m.reviewDoc,exports.searchDoc=h.searchDoc,exports.setAPI=_.setAPI,exports.startEditor=a.startEditor,exports.testMissingTranslations=c.testMissingTranslations,exports.translateDoc=g.translateDoc;
|
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:
|
|
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/cli`),a=require(`@intlayer/config/logger`),o=require(`@intlayer/config/node`),s=require(`@intlayer/unmerged-dictionaries-entry`),c=require(`@intlayer/chokidar/build`),l=require(`@intlayer/chokidar/utils`),u=require(`@intlayer/api`),d=require(`node:fs/promises`);d=e.__toESM(d);const f={pushed:{icon:`✔`,color:a.ANSIColors.GREEN},modified:{icon:`✔`,color:a.ANSIColors.GREEN},error:{icon:`✖`,color:a.ANSIColors.RED},default:{icon:`⏲`,color:a.ANSIColors.BLUE}},p=e=>f[e]??f.default,m=async e=>{let d=(0,o.getConfiguration)(e?.configOptions);(0,i.logConfigDetails)(e?.configOptions);let f=(0,a.getAppLogger)(d);e?.build===!0?await(0,c.prepareIntlayer)(d,{forceRun:!0}):e?.build===void 0&&await(0,c.prepareIntlayer)(d);try{if(!await t.checkCMSAuth(d))return;let o=(0,u.getIntlayerAPIProxy)(void 0,d),m=(0,s.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,a.colorize)(_[0],a.ANSIColors.BLUE,a.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,a.colorize)(`remote`,a.ANSIColors.BLUE,a.ANSIColors.RESET)}, ${(0,a.colorize)(`hybrid`,a.ANSIColors.BLUE,a.ANSIColors.RESET)} or selected custom locations are pushed.`,{level:`warn`}),f(`You can set the location in your dictionary file (e.g. ${(0,a.colorize)(`{ key: 'my-key', location: 'hybrid', ... }`,a.ANSIColors.BLUE,a.ANSIColors.RESET)} or globally in your intlayer.config.ts file (e.g. ${(0,a.colorize)(`{ dictionary: { location: 'hybrid' } }`,a.ANSIColors.BLUE,a.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,i.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,l.parallelize)(x,async e=>{e.status=`pushing`,S.update([{dictionaryKey:e.dictionary.key,status:`pushing`}]);try{let t=await o.dictionary.pushDictionaries([e.dictionary]),n=t.data?.updatedDictionaries??[],r=t.data?.newDictionaries??[],i=[...n,...r];for(let e of i){let t=m[e.key]?.find(t=>t.localId===e.localId);t&&await(0,c.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,a.colorizeKey)(e.dictionary.key)} ${a.ANSIColors.GREY}[${n}${t} ${e.status}${a.ANSIColors.GREY}]${a.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`),o=await r({message:`Do you want to delete the local dictionaries that were successfully pushed? ${(0,a.colorize)(`(Dictionaries:`,a.ANSIColors.GREY,a.ANSIColors.RESET)} ${(0,a.colorizeKey)(n)}${(0,a.colorize)(`)`,a.ANSIColors.GREY,a.ANSIColors.RESET)}`,initialValue:!1});if(i(o))return;o&&await h(t,e)}}}catch(e){f(e,{level:`error`})}},h=async(e,t)=>{let n=(0,a.getAppLogger)((0,o.getConfiguration)(t?.configOptions)),r=new Set;for(let t of e){let{filePath:e}=t;if(!e){n(`Dictionary ${(0,a.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,l.formatPath)(e)}`,{})):t.isDirectory()?n(`Path is a directory ${(0,l.formatPath)(e)}, skipping.`,{}):n(`Unknown file type for ${(0,l.formatPath)(e)}, skipping.`,{})}catch(t){n(`Error deleting ${(0,l.formatPath)(e)}: ${t}`,{level:`error`})}};exports.push=m;
|
|
2
2
|
//# sourceMappingURL=push.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"push.cjs","names":["ANSIColors","checkCMSAuth","PushLogger","fsPromises"],"sources":["../../../src/push/push.ts"],"sourcesContent":["import * as fsPromises from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { getIntlayerAPIProxy } from '@intlayer/api';\nimport {\n prepareIntlayer,\n writeContentDeclaration,\n} from '@intlayer/chokidar/build';\nimport {\n type ListGitFilesOptions,\n listGitFiles,\n logConfigDetails,\n} from '@intlayer/chokidar/cli';\nimport { formatPath, parallelize } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizeKey,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { PushLogger, type PushStatus } from '../pushLog';\nimport { checkCMSAuth } from '../utils/checkAccess';\n\ntype PushOptions = {\n deleteLocaleDictionary?: boolean;\n keepLocaleDictionary?: boolean;\n dictionaries?: string[];\n gitOptions?: ListGitFilesOptions;\n configOptions?: GetConfigurationOptions;\n build?: boolean;\n};\n\ntype DictionariesStatus = {\n dictionary: Dictionary;\n status: 'pending' | 'pushing' | 'modified' | 'pushed' | 'unknown' | 'error';\n error?: Error;\n errorMessage?: string;\n};\n\n// Print per-dictionary summary similar to loadDictionaries\nconst statusIconsAndColors = {\n pushed: { icon: '✔', color: ANSIColors.GREEN },\n modified: { icon: '✔', color: ANSIColors.GREEN },\n error: { icon: '✖', color: ANSIColors.RED },\n default: { icon: '⏲', color: ANSIColors.BLUE },\n};\n\nconst getIconAndColor = (status: DictionariesStatus['status']) => {\n return (\n statusIconsAndColors[status as keyof typeof statusIconsAndColors] ??\n statusIconsAndColors.default\n );\n};\n\n/**\n * Get all local dictionaries and push them simultaneously.\n */\nexport const push = async (options?: PushOptions): Promise<void> => {\n const config = getConfiguration(options?.configOptions);\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(config);\n\n if (options?.build === true) {\n await prepareIntlayer(config, { forceRun: true });\n } else if (typeof options?.build === 'undefined') {\n await prepareIntlayer(config);\n }\n\n try {\n const hasCMSAuth = await checkCMSAuth(config);\n\n if (!hasCMSAuth) return;\n\n const intlayerAPI = getIntlayerAPIProxy(undefined, config);\n\n const unmergedDictionariesRecord = getUnmergedDictionaries(config);\n const allDictionaries = Object.values(unmergedDictionariesRecord).flat();\n\n const customLocations = Array.from(\n new Set(\n allDictionaries\n .map((dictionary) => dictionary.location)\n .filter(\n (location) =>\n location && !['remote', 'local', 'hybrid'].includes(location)\n )\n )\n ) as string[];\n\n let selectedCustomLocations: string[] = [];\n\n if (customLocations.length > 0) {\n const { multiselect, confirm, isCancel } = await import('@clack/prompts');\n\n if (customLocations.length === 1) {\n const shouldPush = await confirm({\n message: `Do you want to push dictionaries with custom location ${colorize(customLocations[0], ANSIColors.BLUE, ANSIColors.RESET)}?`,\n initialValue: false,\n });\n\n if (isCancel(shouldPush)) {\n return;\n }\n\n if (shouldPush) {\n selectedCustomLocations = [customLocations[0]];\n }\n } else {\n const selected = await multiselect({\n message: 'Select custom locations to push:',\n options: customLocations.map((location) => ({\n value: location,\n label: location,\n })),\n required: false,\n });\n\n if (isCancel(selected)) {\n return;\n }\n\n selectedCustomLocations = selected as string[];\n }\n }\n\n let dictionaries: Dictionary[] = allDictionaries.filter((dictionary) => {\n const location =\n dictionary.location ?? config.dictionary?.location ?? 'local';\n\n return (\n location === 'remote' ||\n location === 'hybrid' ||\n selectedCustomLocations.includes(location)\n );\n });\n\n // Check if the dictionaries list is empty after filtering by location\n if (dictionaries.length === 0) {\n appLogger(\n `No dictionaries found to push. Only dictionaries with location ${colorize('remote', ANSIColors.BLUE, ANSIColors.RESET)}, ${colorize('hybrid', ANSIColors.BLUE, ANSIColors.RESET)} or selected custom locations are pushed.`,\n { level: 'warn' }\n );\n appLogger(\n `You can set the location in your dictionary file (e.g. ${colorize(\"{ key: 'my-key', location: 'hybrid', ... }\", ANSIColors.BLUE, ANSIColors.RESET)} or globally in your intlayer.config.ts file (e.g. ${colorize(\"{ dictionary: { location: 'hybrid' } }\", ANSIColors.BLUE, ANSIColors.RESET)}).`,\n { level: 'info' }\n );\n return;\n }\n\n const existingDictionariesKeys: string[] = Object.keys(\n unmergedDictionariesRecord\n );\n\n if (options?.dictionaries) {\n // Check if the provided dictionaries exist\n const noneExistingDictionariesOption = options.dictionaries.filter(\n (dictionaryId) => !existingDictionariesKeys.includes(dictionaryId)\n );\n\n if (noneExistingDictionariesOption.length > 0) {\n appLogger(\n `The following dictionaries do not exist: ${noneExistingDictionariesOption.join(\n ', '\n )} and have been ignored.`,\n {\n level: 'error',\n }\n );\n }\n\n // Filter the dictionaries from the provided list of IDs\n dictionaries = dictionaries.filter((dictionary) =>\n options.dictionaries?.includes(dictionary.key)\n );\n }\n\n if (options?.gitOptions) {\n const gitFiles = await listGitFiles(options.gitOptions);\n\n dictionaries = dictionaries.filter((dictionary) =>\n gitFiles.includes(\n join(config.system.baseDir, dictionary.filePath ?? '')\n )\n );\n }\n\n // Check if the dictionaries list is empty\n if (dictionaries.length === 0) {\n appLogger('No local dictionaries found', {\n level: 'error',\n });\n return;\n }\n\n appLogger('Pushing dictionaries:');\n\n // Prepare dictionaries statuses\n const dictionariesStatuses: DictionariesStatus[] = dictionaries.map(\n (dictionary) => ({\n dictionary,\n status: 'pending',\n })\n );\n\n // Initialize aggregated logger similar to loadDictionaries\n const logger = new PushLogger();\n logger.update(\n dictionariesStatuses.map<PushStatus>((s) => ({\n dictionaryKey: s.dictionary.key,\n status: 'pending',\n }))\n );\n\n const successfullyPushedDictionaries: Dictionary[] = [];\n\n const processDictionary = async (\n statusObj: DictionariesStatus\n ): Promise<void> => {\n statusObj.status = 'pushing';\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'pushing' },\n ]);\n\n try {\n const pushResult = await intlayerAPI.dictionary.pushDictionaries([\n statusObj.dictionary,\n ]);\n\n const updatedDictionaries = pushResult.data?.updatedDictionaries ?? [];\n const newDictionaries = pushResult.data?.newDictionaries ?? [];\n\n const allDictionaries = [...updatedDictionaries, ...newDictionaries];\n\n for (const remoteDictionaryData of allDictionaries) {\n const localDictionary = unmergedDictionariesRecord[\n remoteDictionaryData.key\n ]?.find(\n (dictionary) => dictionary.localId === remoteDictionaryData.localId\n );\n\n if (!localDictionary) continue;\n\n await writeContentDeclaration(\n { ...localDictionary, id: remoteDictionaryData.id },\n config\n );\n }\n\n if (\n updatedDictionaries.some(\n (dictionary) => dictionary.key === statusObj.dictionary.key\n )\n ) {\n statusObj.status = 'modified';\n successfullyPushedDictionaries.push(statusObj.dictionary);\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'modified' },\n ]);\n } else if (\n newDictionaries.some(\n (dictionary) => dictionary.key === statusObj.dictionary.key\n )\n ) {\n statusObj.status = 'pushed';\n successfullyPushedDictionaries.push(statusObj.dictionary);\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'pushed' },\n ]);\n } else {\n statusObj.status = 'unknown';\n }\n } catch (error) {\n statusObj.status = 'error';\n statusObj.error = error as Error;\n statusObj.errorMessage = `Error pushing dictionary ${statusObj.dictionary.key}: ${error}`;\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'error' },\n ]);\n }\n };\n\n // Process dictionaries in parallel with a concurrency limit (reuse parallelize)\n await parallelize(dictionariesStatuses, processDictionary, 5);\n\n // Stop the logger and render final state\n logger.finish();\n\n for (const dictionaryStatus of dictionariesStatuses) {\n const { icon, color } = getIconAndColor(dictionaryStatus.status);\n appLogger(\n ` - ${colorizeKey(dictionaryStatus.dictionary.key)} ${ANSIColors.GREY}[${color}${icon} ${dictionaryStatus.status}${ANSIColors.GREY}]${ANSIColors.RESET}`\n );\n }\n\n // Output any error messages\n for (const statusObj of dictionariesStatuses) {\n if (statusObj.errorMessage) {\n appLogger(statusObj.errorMessage, {\n level: 'error',\n });\n }\n }\n\n // Handle delete or keep options\n const deleteOption = options?.deleteLocaleDictionary;\n const keepOption = options?.keepLocaleDictionary;\n\n if (deleteOption && keepOption) {\n throw new Error(\n 'Cannot specify both --deleteLocaleDictionary and --keepLocaleDictionary options.'\n );\n }\n\n if (deleteOption) {\n // Delete only the successfully pushed dictionaries\n await deleteLocalDictionaries(successfullyPushedDictionaries, options);\n } else if (keepOption) {\n // Do nothing, keep the local dictionaries\n } else {\n // Ask the user\n const remoteDictionaries = successfullyPushedDictionaries.filter(\n (dictionary) => dictionary.location === 'remote'\n );\n const remoteDictionariesKeys = remoteDictionaries.map(\n (dictionary) => dictionary.key\n );\n\n if (remoteDictionaries.length > 0) {\n const { confirm, isCancel } = await import('@clack/prompts');\n\n const shouldDelete = await confirm({\n message: `Do you want to delete the local dictionaries that were successfully pushed? ${colorize('(Dictionaries:', ANSIColors.GREY, ANSIColors.RESET)} ${colorizeKey(remoteDictionariesKeys)}${colorize(')', ANSIColors.GREY, ANSIColors.RESET)}`,\n initialValue: false,\n });\n\n if (isCancel(shouldDelete)) {\n return;\n }\n\n if (shouldDelete) {\n await deleteLocalDictionaries(remoteDictionaries, options);\n }\n }\n }\n } catch (error) {\n appLogger(error, {\n level: 'error',\n });\n }\n};\n\nconst deleteLocalDictionaries = async (\n dictionariesToDelete: Dictionary[],\n options?: PushOptions\n): Promise<void> => {\n const config = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(config);\n\n // Use a Set to collect all unique file paths\n const filePathsSet: Set<string> = new Set();\n\n for (const dictionary of dictionariesToDelete) {\n const { filePath } = dictionary;\n\n if (!filePath) {\n appLogger(\n `Dictionary ${colorizeKey(dictionary.key)} does not have a file path`,\n {\n level: 'error',\n }\n );\n continue;\n }\n\n filePathsSet.add(filePath);\n }\n\n for (const filePath of filePathsSet) {\n try {\n const stats = await fsPromises.lstat(filePath);\n\n if (stats.isFile()) {\n await fsPromises.unlink(filePath);\n appLogger(`Deleted file ${formatPath(filePath)}`, {});\n } else if (stats.isDirectory()) {\n appLogger(`Path is a directory ${formatPath(filePath)}, skipping.`, {});\n } else {\n appLogger(\n `Unknown file type for ${formatPath(filePath)}, skipping.`,\n {}\n );\n }\n } catch (err) {\n appLogger(`Error deleting ${formatPath(filePath)}: ${err}`, {\n level: 'error',\n });\n }\n }\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"push.cjs","names":["ANSIColors","checkCMSAuth","PushLogger","fsPromises"],"sources":["../../../src/push/push.ts"],"sourcesContent":["import * as fsPromises from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { getIntlayerAPIProxy } from '@intlayer/api';\nimport {\n prepareIntlayer,\n writeContentDeclaration,\n} from '@intlayer/chokidar/build';\nimport {\n type ListGitFilesOptions,\n listGitFiles,\n logConfigDetails,\n} from '@intlayer/chokidar/cli';\nimport { formatPath, parallelize } from '@intlayer/chokidar/utils';\nimport {\n ANSIColors,\n colorize,\n colorizeKey,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { PushLogger, type PushStatus } from '../pushLog';\nimport { checkCMSAuth } from '../utils/checkAccess';\n\ntype PushOptions = {\n deleteLocaleDictionary?: boolean;\n keepLocaleDictionary?: boolean;\n dictionaries?: string[];\n gitOptions?: ListGitFilesOptions;\n configOptions?: GetConfigurationOptions;\n build?: boolean;\n};\n\ntype DictionariesStatus = {\n dictionary: Dictionary;\n status: 'pending' | 'pushing' | 'modified' | 'pushed' | 'unknown' | 'error';\n error?: Error;\n errorMessage?: string;\n};\n\n// Print per-dictionary summary similar to loadDictionaries\nconst statusIconsAndColors = {\n pushed: { icon: '✔', color: ANSIColors.GREEN },\n modified: { icon: '✔', color: ANSIColors.GREEN },\n error: { icon: '✖', color: ANSIColors.RED },\n default: { icon: '⏲', color: ANSIColors.BLUE },\n};\n\nconst getIconAndColor = (status: DictionariesStatus['status']) => {\n return (\n statusIconsAndColors[status as keyof typeof statusIconsAndColors] ??\n statusIconsAndColors.default\n );\n};\n\n/**\n * Get all local dictionaries and push them simultaneously.\n */\nexport const push = async (options?: PushOptions): Promise<void> => {\n const config = getConfiguration(options?.configOptions);\n logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(config);\n\n if (options?.build === true) {\n await prepareIntlayer(config, { forceRun: true });\n } else if (typeof options?.build === 'undefined') {\n await prepareIntlayer(config);\n }\n\n try {\n const hasCMSAuth = await checkCMSAuth(config);\n\n if (!hasCMSAuth) return;\n\n const intlayerAPI = getIntlayerAPIProxy(undefined, config);\n\n const unmergedDictionariesRecord = getUnmergedDictionaries(config);\n const allDictionaries = Object.values(unmergedDictionariesRecord).flat();\n\n const customLocations = Array.from(\n new Set(\n allDictionaries\n .map((dictionary) => dictionary.location)\n .filter(\n (location) =>\n location && !['remote', 'local', 'hybrid'].includes(location)\n )\n )\n ) as string[];\n\n let selectedCustomLocations: string[] = [];\n\n if (customLocations.length > 0) {\n const { multiselect, confirm, isCancel } = await import('@clack/prompts');\n\n if (customLocations.length === 1) {\n const shouldPush = await confirm({\n message: `Do you want to push dictionaries with custom location ${colorize(customLocations[0], ANSIColors.BLUE, ANSIColors.RESET)}?`,\n initialValue: false,\n });\n\n if (isCancel(shouldPush)) {\n return;\n }\n\n if (shouldPush) {\n selectedCustomLocations = [customLocations[0]];\n }\n } else {\n const selected = await multiselect({\n message: 'Select custom locations to push:',\n options: customLocations.map((location) => ({\n value: location,\n label: location,\n })),\n required: false,\n });\n\n if (isCancel(selected)) {\n return;\n }\n\n selectedCustomLocations = selected as string[];\n }\n }\n\n let dictionaries: Dictionary[] = allDictionaries.filter((dictionary) => {\n const location =\n dictionary.location ?? config.dictionary?.location ?? 'local';\n\n return (\n location === 'remote' ||\n location === 'hybrid' ||\n selectedCustomLocations.includes(location)\n );\n });\n\n // Check if the dictionaries list is empty after filtering by location\n if (dictionaries.length === 0) {\n appLogger(\n `No dictionaries found to push. Only dictionaries with location ${colorize('remote', ANSIColors.BLUE, ANSIColors.RESET)}, ${colorize('hybrid', ANSIColors.BLUE, ANSIColors.RESET)} or selected custom locations are pushed.`,\n { level: 'warn' }\n );\n appLogger(\n `You can set the location in your dictionary file (e.g. ${colorize(\"{ key: 'my-key', location: 'hybrid', ... }\", ANSIColors.BLUE, ANSIColors.RESET)} or globally in your intlayer.config.ts file (e.g. ${colorize(\"{ dictionary: { location: 'hybrid' } }\", ANSIColors.BLUE, ANSIColors.RESET)}).`,\n { level: 'info' }\n );\n return;\n }\n\n const existingDictionariesKeys: string[] = Object.keys(\n unmergedDictionariesRecord\n );\n\n if (options?.dictionaries) {\n // Check if the provided dictionaries exist\n const noneExistingDictionariesOption = options.dictionaries.filter(\n (dictionaryId) => !existingDictionariesKeys.includes(dictionaryId)\n );\n\n if (noneExistingDictionariesOption.length > 0) {\n appLogger(\n `The following dictionaries do not exist: ${noneExistingDictionariesOption.join(\n ', '\n )} and have been ignored.`,\n {\n level: 'error',\n }\n );\n }\n\n // Filter the dictionaries from the provided list of IDs\n dictionaries = dictionaries.filter((dictionary) =>\n options.dictionaries?.includes(dictionary.key)\n );\n }\n\n if (options?.gitOptions) {\n const gitFiles = await listGitFiles(options.gitOptions);\n\n dictionaries = dictionaries.filter((dictionary) =>\n gitFiles.includes(\n join(config.system.baseDir, dictionary.filePath ?? '')\n )\n );\n }\n\n // Check if the dictionaries list is empty\n if (dictionaries.length === 0) {\n appLogger('No local dictionaries found', {\n level: 'error',\n });\n return;\n }\n\n appLogger('Pushing dictionaries:');\n\n // Prepare dictionaries statuses\n const dictionariesStatuses: DictionariesStatus[] = dictionaries.map(\n (dictionary) => ({\n dictionary,\n status: 'pending',\n })\n );\n\n // Initialize aggregated logger similar to loadDictionaries\n const logger = new PushLogger();\n logger.update(\n dictionariesStatuses.map<PushStatus>((s) => ({\n dictionaryKey: s.dictionary.key,\n status: 'pending',\n }))\n );\n\n const successfullyPushedDictionaries: Dictionary[] = [];\n\n const processDictionary = async (\n statusObj: DictionariesStatus\n ): Promise<void> => {\n statusObj.status = 'pushing';\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'pushing' },\n ]);\n\n try {\n const pushResult = await intlayerAPI.dictionary.pushDictionaries([\n statusObj.dictionary,\n ]);\n\n const updatedDictionaries = pushResult.data?.updatedDictionaries ?? [];\n const newDictionaries = pushResult.data?.newDictionaries ?? [];\n\n const allDictionaries = [...updatedDictionaries, ...newDictionaries];\n\n for (const remoteDictionaryData of allDictionaries) {\n const localDictionary = unmergedDictionariesRecord[\n remoteDictionaryData.key\n ]?.find(\n (dictionary) => dictionary.localId === remoteDictionaryData.localId\n );\n\n if (!localDictionary) continue;\n\n await writeContentDeclaration(\n { ...localDictionary, id: remoteDictionaryData.id },\n config\n );\n }\n\n if (\n updatedDictionaries.some(\n (dictionary) => dictionary.key === statusObj.dictionary.key\n )\n ) {\n statusObj.status = 'modified';\n successfullyPushedDictionaries.push(statusObj.dictionary);\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'modified' },\n ]);\n } else if (\n newDictionaries.some(\n (dictionary) => dictionary.key === statusObj.dictionary.key\n )\n ) {\n statusObj.status = 'pushed';\n successfullyPushedDictionaries.push(statusObj.dictionary);\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'pushed' },\n ]);\n } else {\n statusObj.status = 'unknown';\n }\n } catch (error) {\n statusObj.status = 'error';\n statusObj.error = error as Error;\n statusObj.errorMessage = `Error pushing dictionary ${statusObj.dictionary.key}: ${error}`;\n logger.update([\n { dictionaryKey: statusObj.dictionary.key, status: 'error' },\n ]);\n }\n };\n\n // Process dictionaries in parallel with a concurrency limit (reuse parallelize)\n await parallelize(dictionariesStatuses, processDictionary, 5);\n\n // Stop the logger and render final state\n logger.finish();\n\n for (const dictionaryStatus of dictionariesStatuses) {\n const { icon, color } = getIconAndColor(dictionaryStatus.status);\n appLogger(\n ` - ${colorizeKey(dictionaryStatus.dictionary.key)} ${ANSIColors.GREY}[${color}${icon} ${dictionaryStatus.status}${ANSIColors.GREY}]${ANSIColors.RESET}`\n );\n }\n\n // Output any error messages\n for (const statusObj of dictionariesStatuses) {\n if (statusObj.errorMessage) {\n appLogger(statusObj.errorMessage, {\n level: 'error',\n });\n }\n }\n\n // Handle delete or keep options\n const deleteOption = options?.deleteLocaleDictionary;\n const keepOption = options?.keepLocaleDictionary;\n\n if (deleteOption && keepOption) {\n throw new Error(\n 'Cannot specify both --deleteLocaleDictionary and --keepLocaleDictionary options.'\n );\n }\n\n if (deleteOption) {\n // Delete only the successfully pushed dictionaries\n await deleteLocalDictionaries(successfullyPushedDictionaries, options);\n } else if (keepOption) {\n // Do nothing, keep the local dictionaries\n } else {\n // Ask the user\n const remoteDictionaries = successfullyPushedDictionaries.filter(\n (dictionary) => dictionary.location === 'remote'\n );\n const remoteDictionariesKeys = remoteDictionaries.map(\n (dictionary) => dictionary.key\n );\n\n if (remoteDictionaries.length > 0) {\n const { confirm, isCancel } = await import('@clack/prompts');\n\n const shouldDelete = await confirm({\n message: `Do you want to delete the local dictionaries that were successfully pushed? ${colorize('(Dictionaries:', ANSIColors.GREY, ANSIColors.RESET)} ${colorizeKey(remoteDictionariesKeys)}${colorize(')', ANSIColors.GREY, ANSIColors.RESET)}`,\n initialValue: false,\n });\n\n if (isCancel(shouldDelete)) {\n return;\n }\n\n if (shouldDelete) {\n await deleteLocalDictionaries(remoteDictionaries, options);\n }\n }\n }\n } catch (error) {\n appLogger(error, {\n level: 'error',\n });\n }\n};\n\nconst deleteLocalDictionaries = async (\n dictionariesToDelete: Dictionary[],\n options?: PushOptions\n): Promise<void> => {\n const config = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(config);\n\n // Use a Set to collect all unique file paths\n const filePathsSet: Set<string> = new Set();\n\n for (const dictionary of dictionariesToDelete) {\n const { filePath } = dictionary;\n\n if (!filePath) {\n appLogger(\n `Dictionary ${colorizeKey(dictionary.key)} does not have a file path`,\n {\n level: 'error',\n }\n );\n continue;\n }\n\n filePathsSet.add(filePath);\n }\n\n for (const filePath of filePathsSet) {\n try {\n const stats = await fsPromises.lstat(filePath);\n\n if (stats.isFile()) {\n await fsPromises.unlink(filePath);\n appLogger(`Deleted file ${formatPath(filePath)}`, {});\n } else if (stats.isDirectory()) {\n appLogger(`Path is a directory ${formatPath(filePath)}, skipping.`, {});\n } else {\n appLogger(\n `Unknown file type for ${formatPath(filePath)}, skipping.`,\n {}\n );\n }\n } catch (err) {\n appLogger(`Error deleting ${formatPath(filePath)}: ${err}`, {\n level: 'error',\n });\n }\n }\n};\n"],"mappings":"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"}
|
|
@@ -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:
|
|
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/config/logger`),u=require(`@intlayer/config/node`),d=require(`@intlayer/chokidar/utils`),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,u.getConfiguration)(b),E=(0,l.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,d.formatLocale)(_,!1)}`).replaceAll(`{{baseLocaleName}}`,`${(0,d.formatLocale)(v,!1)}`).replace(`{{applicationContext}}`,y?.applicationContext??`-`).replace(`{{customInstructions}}`,x??`-`),A=[(0,l.colon)(`${l.ANSIColors.GREY_DARK}[${(0,d.formatPath)(e)}${l.ANSIColors.GREY_DARK}] `,{colSize:40}),`→ ${l.ANSIColors.RESET}`].join(``),j=[(0,l.colon)(`${l.ANSIColors.GREY_DARK}[${(0,d.formatPath)(e)}${l.ANSIColors.GREY_DARK}][${(0,d.formatLocale)(_)}${l.ANSIColors.GREY_DARK}] `,{colSize:40}),`→ ${l.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,l.colorizeNumber)(M.length)}, FR=${(0,l.colorizeNumber)(N.length)}`),E(`${A}Actions: reuse=${(0,l.colorizeNumber)(P.actions.filter(e=>e.kind===`reuse`).length)}, review=${(0,l.colorizeNumber)(P.actions.filter(e=>e.kind===`review`).length)}, new=${(0,l.colorizeNumber)(P.actions.filter(e=>e.kind===`insert_new`).length)}, delete=${(0,l.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,l.colorize)(`✔`,l.ANSIColors.GREEN)} File ${(0,d.formatPath)(g)} updated successfully (no changes needed).`);return}E(`${A}Segments to review: ${(0,l.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,d.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,d.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,l.colorizeNumber)(t)} of ${(0,l.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,l.colorizeNumber)(e.tokenUsed)} tokens used - Block ${(0,l.colorizeNumber)(t)} of ${(0,l.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,l.colorize)(`✔`,l.ANSIColors.GREEN)} File ${(0,d.formatPath)(g)} created/updated successfully.`)};exports.reviewFileBlockAware=g;
|
|
2
2
|
//# sourceMappingURL=reviewDocBlockAware.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:
|
|
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/config/logger`),c=require(`@intlayer/chokidar/utils`),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,s.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,s.colon)(`${s.ANSIColors.GREY_DARK}[${(0,c.formatPath)(f)}${s.ANSIColors.GREY_DARK}] `,{colSize:40})}${s.ANSIColors.RESET}`,A=`${(0,s.colon)(`${s.ANSIColors.GREY_DARK}[${(0,c.formatPath)(f)}${s.ANSIColors.GREY_DARK}][${(0,c.formatLocale)(m)}${s.ANSIColors.GREY_DARK}] `,{colSize:40})}${s.ANSIColors.RESET}`;T(`${k}Split into ${(0,s.colorizeNumber)(O)} chunks. Queuing...`);let j=e.readAsset(`./prompts/TRANSLATE_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${(0,c.formatLocale)(m,!1)}`).replaceAll(`{{baseLocaleName}}`,`${(0,c.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 c=(0,s.getAppLogger)(g,{config:{prefix:`${A} ${s.ANSIColors.GREY_DARK}[${i+1}/${O}] ${s.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 <<<";c(`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,c))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)}c([`${(0,s.colorizeNumber)(T)} tokens used `,`${s.ANSIColors.GREY_DARK}in ${(0,s.colorizeNumber)(E)}ms${s.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,s.colorize)(`✔`,s.ANSIColors.GREEN)} File ${(0,c.formatPath)(L)} completed in ${(0,s.colorizeNumber)(I)}s.`),F}catch(e){_.count++;let t=e?.message??JSON.stringify(e);return T(`${(0,s.colorize)(`✖`,s.ANSIColors.RED)} Error: ${t}`),_.count>=_.maxErrors&&(_.shouldStop=!0),null}};exports.translateFile=f;
|
|
3
3
|
//# sourceMappingURL=translateFile.cjs.map
|
package/dist/esm/ci.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{normalize as e,resolve as t}from"node:path";import{listProjects as n}from"@intlayer/chokidar/cli";import{logger as r}from"@intlayer/config/logger";import{spawnSync as i}from"node:child_process";const a=()=>{let e=process.env.npm_config_user_agent;return e?.startsWith(`bun`)?{command:`bun`,args:[`intlayer`]}:e?.startsWith(`pnpm`)?{command:`pnpm`,args:[`exec`,`intlayer`]}:e?.startsWith(`yarn`)?{command:`yarn`,args:[`run`,`intlayer`]}:{command:`npx`,args:[`intlayer`]}},o=async o=>{let s=process.env.INTLAYER_PROJECT_CREDENTIALS,c={};if(s)try{c=JSON.parse(s)}catch{r(`INTLAYER_PROJECT_CREDENTIALS is not valid JSON. Proceeding without credentials.`,{level:`warn`})}let l=process.cwd(),{projectsPath:u}=await n();if(u.length===0){r(`No Intlayer projects found.`,{level:`warn`});return}let d=u.find(e=>l===e),f=d?[d]:u,{command:p,args:m}=a(),h=[...m,...o];r(`CI: Using package manager: ${p}`,{level:`
|
|
1
|
+
import{normalize as e,resolve as t}from"node:path";import{listProjects as n}from"@intlayer/chokidar/cli";import{logger as r}from"@intlayer/config/logger";import{spawnSync as i}from"node:child_process";const a=()=>{let e=process.env.npm_config_user_agent;return e?.startsWith(`bun`)?{command:`bun`,args:[`intlayer`]}:e?.startsWith(`pnpm`)?{command:`pnpm`,args:[`exec`,`intlayer`]}:e?.startsWith(`yarn`)?{command:`yarn`,args:[`run`,`intlayer`]}:{command:`npx`,args:[`intlayer`]}},o=async o=>{let s=process.env.INTLAYER_PROJECT_CREDENTIALS,c={};if(s)try{c=JSON.parse(s)}catch{r(`INTLAYER_PROJECT_CREDENTIALS is not valid JSON. Proceeding without credentials.`,{level:`warn`})}let l=process.cwd(),{projectsPath:u}=await n();if(u.length===0){r(`No Intlayer projects found.`,{level:`warn`});return}let d=u.find(e=>l===e),f=d?[d]:u,{command:p,args:m}=a(),h=[...m,...o];r(`CI: Using package manager: ${p}`,{level:`info`,isVerbose:!0}),r(d?`CI: Detected project context: ${d}`:`CI: No specific project context detected. Iterating over ${f.length} discovered projects...`,{level:`info`});let g=!1;for(let n of f){let a=Object.entries(c).find(([r])=>t(r)===n||n.endsWith(e(r)))?.[1];r(`\nCI: Executing for ${n}...`,{level:`info`});let o={...process.env};a?(o.INTLAYER_CLIENT_ID=a.clientId,o.INTLAYER_CLIENT_SECRET=a.clientSecret):s&&r(`CI: No matching credentials found for ${n} in INTLAYER_PROJECT_CREDENTIALS.`,{isVerbose:!0}),i(p,h,{cwd:n,stdio:`inherit`,env:o}).status!==0&&(r(`CI: Failed for ${n}`,{level:`error`}),g=!0)}g&&process.exit(1)};export{o as runCI};
|
|
2
2
|
//# sourceMappingURL=ci.mjs.map
|
package/dist/esm/ci.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ci.mjs","names":[],"sources":["../../src/ci.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport { normalize, resolve } from 'node:path';\nimport { listProjects } from '@intlayer/chokidar/cli';\nimport { logger } from '@intlayer/config/logger';\n\n// Helper to detect the package manager used to run the command\nconst getPackageManagerCommand = () => {\n const userAgent = process.env.npm_config_user_agent;\n\n if (userAgent?.startsWith('bun')) {\n return { command: 'bun', args: ['intlayer'] }; // Bun runs local bins natively\n }\n if (userAgent?.startsWith('pnpm')) {\n return { command: 'pnpm', args: ['exec', 'intlayer'] }; // pnpm requires 'exec'\n }\n if (userAgent?.startsWith('yarn')) {\n return { command: 'yarn', args: ['run', 'intlayer'] }; // yarn requires 'run' or 'exec'\n }\n\n // Default fallback\n return { command: 'npx', args: ['intlayer'] };\n};\n\nexport const runCI = async (commands: string[]) => {\n const credentialsEnv = process.env.INTLAYER_PROJECT_CREDENTIALS;\n let credentials: Record<string, { clientId: string; clientSecret: string }> =\n {};\n\n // Parse Credentials (Optional now)\n if (credentialsEnv) {\n try {\n credentials = JSON.parse(credentialsEnv);\n } catch {\n logger(\n 'INTLAYER_PROJECT_CREDENTIALS is not valid JSON. Proceeding without credentials.',\n {\n level: 'warn',\n }\n );\n }\n }\n\n const cwd = process.cwd();\n\n // Discover Projects\n const { projectsPath } = await listProjects();\n\n if (projectsPath.length === 0) {\n logger('No Intlayer projects found.', { level: 'warn' });\n return;\n }\n\n // 3. Determine Context: Single Project vs All Projects\n // Check if the current directory matches one of the discovered project paths\n const currentProject = projectsPath.find((p) => cwd === p);\n const projectsToRun = currentProject ? [currentProject] : projectsPath;\n\n const { command, args: pmArgs } = getPackageManagerCommand();\n const finalArgs = [...pmArgs, ...commands];\n\n logger(`CI: Using package manager: ${command}`, {
|
|
1
|
+
{"version":3,"file":"ci.mjs","names":[],"sources":["../../src/ci.ts"],"sourcesContent":["import { spawnSync } from 'node:child_process';\nimport { normalize, resolve } from 'node:path';\nimport { listProjects } from '@intlayer/chokidar/cli';\nimport { logger } from '@intlayer/config/logger';\n\n// Helper to detect the package manager used to run the command\nconst getPackageManagerCommand = () => {\n const userAgent = process.env.npm_config_user_agent;\n\n if (userAgent?.startsWith('bun')) {\n return { command: 'bun', args: ['intlayer'] }; // Bun runs local bins natively\n }\n if (userAgent?.startsWith('pnpm')) {\n return { command: 'pnpm', args: ['exec', 'intlayer'] }; // pnpm requires 'exec'\n }\n if (userAgent?.startsWith('yarn')) {\n return { command: 'yarn', args: ['run', 'intlayer'] }; // yarn requires 'run' or 'exec'\n }\n\n // Default fallback\n return { command: 'npx', args: ['intlayer'] };\n};\n\nexport const runCI = async (commands: string[]) => {\n const credentialsEnv = process.env.INTLAYER_PROJECT_CREDENTIALS;\n let credentials: Record<string, { clientId: string; clientSecret: string }> =\n {};\n\n // Parse Credentials (Optional now)\n if (credentialsEnv) {\n try {\n credentials = JSON.parse(credentialsEnv);\n } catch {\n logger(\n 'INTLAYER_PROJECT_CREDENTIALS is not valid JSON. Proceeding without credentials.',\n {\n level: 'warn',\n }\n );\n }\n }\n\n const cwd = process.cwd();\n\n // Discover Projects\n const { projectsPath } = await listProjects();\n\n if (projectsPath.length === 0) {\n logger('No Intlayer projects found.', { level: 'warn' });\n return;\n }\n\n // 3. Determine Context: Single Project vs All Projects\n // Check if the current directory matches one of the discovered project paths\n const currentProject = projectsPath.find((p) => cwd === p);\n const projectsToRun = currentProject ? [currentProject] : projectsPath;\n\n const { command, args: pmArgs } = getPackageManagerCommand();\n const finalArgs = [...pmArgs, ...commands];\n\n logger(`CI: Using package manager: ${command}`, {\n level: 'info',\n isVerbose: true,\n });\n\n if (currentProject) {\n logger(`CI: Detected project context: ${currentProject}`, {\n level: 'info',\n });\n } else {\n logger(\n `CI: No specific project context detected. Iterating over ${projectsToRun.length} discovered projects...`,\n {\n level: 'info',\n }\n );\n }\n\n let hasError = false;\n\n // Iterate and Execute\n for (const projectPath of projectsToRun) {\n // Attempt to match credentials to the project path\n // We check if the key (relative or absolute) matches the resolved project path\n const credsEntry = Object.entries(credentials).find(([key]) => {\n const absKey = resolve(key);\n return absKey === projectPath || projectPath.endsWith(normalize(key));\n });\n\n const creds = credsEntry?.[1];\n\n logger(`\\nCI: Executing for ${projectPath}...`, {\n level: 'info',\n });\n\n const envVars = { ...process.env };\n\n if (creds) {\n envVars.INTLAYER_CLIENT_ID = creds.clientId;\n envVars.INTLAYER_CLIENT_SECRET = creds.clientSecret;\n } else if (credentialsEnv) {\n logger(\n `CI: No matching credentials found for ${projectPath} in INTLAYER_PROJECT_CREDENTIALS.`,\n { isVerbose: true }\n );\n }\n\n const result = spawnSync(command, finalArgs, {\n cwd: projectPath,\n stdio: 'inherit',\n env: envVars,\n });\n\n if (result.status !== 0) {\n logger(`CI: Failed for ${projectPath}`, {\n level: 'error',\n });\n hasError = true;\n }\n }\n\n if (hasError) process.exit(1);\n};\n"],"mappings":"yMAMA,MAAM,MAAiC,CACrC,IAAM,EAAY,QAAQ,IAAI,sBAa9B,OAXI,GAAW,WAAW,MAAM,CACvB,CAAE,QAAS,MAAO,KAAM,CAAC,WAAW,CAAE,CAE3C,GAAW,WAAW,OAAO,CACxB,CAAE,QAAS,OAAQ,KAAM,CAAC,OAAQ,WAAW,CAAE,CAEpD,GAAW,WAAW,OAAO,CACxB,CAAE,QAAS,OAAQ,KAAM,CAAC,MAAO,WAAW,CAAE,CAIhD,CAAE,QAAS,MAAO,KAAM,CAAC,WAAW,CAAE,EAGlC,EAAQ,KAAO,IAAuB,CACjD,IAAM,EAAiB,QAAQ,IAAI,6BAC/B,EACF,EAAE,CAGJ,GAAI,EACF,GAAI,CACF,EAAc,KAAK,MAAM,EAAe,MAClC,CACN,EACE,kFACA,CACE,MAAO,OACR,CACF,CAIL,IAAM,EAAM,QAAQ,KAAK,CAGnB,CAAE,gBAAiB,MAAM,GAAc,CAE7C,GAAI,EAAa,SAAW,EAAG,CAC7B,EAAO,8BAA+B,CAAE,MAAO,OAAQ,CAAC,CACxD,OAKF,IAAM,EAAiB,EAAa,KAAM,GAAM,IAAQ,EAAE,CACpD,EAAgB,EAAiB,CAAC,EAAe,CAAG,EAEpD,CAAE,UAAS,KAAM,GAAW,GAA0B,CACtD,EAAY,CAAC,GAAG,EAAQ,GAAG,EAAS,CAE1C,EAAO,8BAA8B,IAAW,CAC9C,MAAO,OACP,UAAW,GACZ,CAAC,CAGA,EADE,EACK,iCAAiC,IAKtC,4DAA4D,EAAc,OAAO,yBALzB,CACxD,MAAO,OACR,CAOA,CAGH,IAAI,EAAW,GAGf,IAAK,IAAM,KAAe,EAAe,CAQvC,IAAM,EALa,OAAO,QAAQ,EAAY,CAAC,MAAM,CAAC,KACrC,EAAQ,EAAI,GACT,GAAe,EAAY,SAAS,EAAU,EAAI,CAAC,CACrE,GAEyB,GAE3B,EAAO,uBAAuB,EAAY,KAAM,CAC9C,MAAO,OACR,CAAC,CAEF,IAAM,EAAU,CAAE,GAAG,QAAQ,IAAK,CAE9B,GACF,EAAQ,mBAAqB,EAAM,SACnC,EAAQ,uBAAyB,EAAM,cAC9B,GACT,EACE,yCAAyC,EAAY,mCACrD,CAAE,UAAW,GAAM,CACpB,CAGY,EAAU,EAAS,EAAW,CAC3C,IAAK,EACL,MAAO,UACP,IAAK,EACN,CAAC,CAES,SAAW,IACpB,EAAO,kBAAkB,IAAe,CACtC,MAAO,QACR,CAAC,CACF,EAAW,IAIX,GAAU,QAAQ,KAAK,EAAE"}
|
package/dist/esm/extract.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{existsSync as e}from"node:fs";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{logConfigDetails as a}from"@intlayer/chokidar/cli";import{colorizePath as o,getAppLogger as s}from"@intlayer/config/logger";import{getConfiguration as c}from"@intlayer/config/node";import{getUnmergedDictionaries as l}from"@intlayer/unmerged-dictionaries-entry";import u from"enquirer";import d from"fast-glob";const f=async f=>{let p=c(f.configOptions);a(f?.configOptions);let m=s(p),{baseDir:h}=p.system,{codeDir:g,excludedPath:_}=p.content,{traversePattern:v}=p.build,y=e=>o(t(h,e)),b=r(h),x=f.files??[];if(x.length===0){let n=e=>(_??[]).some(t=>{let n=t.split(`/`).filter(e=>!e.includes(`*`)&&e.length>0),r=e.split(`/`);return n.some(e=>r.includes(e))}),r=(await Promise.all(g.filter(e=>!n(e)).map(e=>d(v,{cwd:e,ignore:_,absolute:!0})))).flat(),i=[...new Set(r)].filter(t=>e(t)).map(e=>({value:e,label:t(h,e)}));if(i.length===0){m(`No extractable files found in the project.`);return}let a=`__select_all__`,o;try{let e=Math.max((process.stdout.columns||80)-15,20),t=t=>t.length>e?`...${t.slice(-(e-3))}`:t,{files:n}=await u.prompt({type:`autocomplete`,name:`files`,message:`Select files to extract (Type to search):`,multiple:!0,limit:40,choices:[{name:a,message:`────── Select all ──────`},...i.map(e=>({name:e.value,message:t(e.label)}))],async toggle(e,t){if(!(!e||e.disabled))return e.enabled=t??!e.enabled,e.name===a&&this.choices.filter(e=>e.name!==a).forEach(t=>{t.enabled=e.enabled}),this.render()},format(){return this.state?.submitted&&this.options?.multiple?`${this.selected.filter(e=>e.name!==a).length} file(s) selected`:this.input??``}});o=n.filter(e=>e!==a)}catch{o=Symbol(`cancel`)}typeof o==`symbol`&&process.exit(0),x=o}if(x.length===0){m(`No files selected for extraction.`);return}let S=x.map(e=>n(h,e)).filter(t=>e(t)?!0:(m(`File not found: ${y(t)}`),!1));if(S.length===0)return;let C=l(p);await Promise.all(S.map(async e=>{try{await i(e,b,{unmergedDictionaries:C,configuration:p,codeOnly:f.codeOnly,declarationOnly:f.declarationOnly})}catch(t){m(`Failed to transform ${e}: ${t.message}`)}}))};export{f 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 { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport {
|
|
1
|
+
{"version":3,"file":"extract.mjs","names":[],"sources":["../../src/extract.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { relative, resolve } from 'node:path';\nimport {\n detectPackageName,\n extractContent,\n type PackageName,\n} from '@intlayer/babel';\nimport { logConfigDetails } from '@intlayer/chokidar/cli';\nimport { colorizePath, getAppLogger } 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';\nimport fg from 'fast-glob';\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 logConfigDetails(options?.configOptions);\n\n const appLogger = getAppLogger(configuration);\n const { baseDir } = configuration.system;\n const { codeDir, excludedPath } = configuration.content;\n const { traversePattern } = configuration.build;\n\n const formatPath = (path: string) => {\n const relativePath = relative(baseDir, path);\n return colorizePath(relativePath);\n };\n\n // Detect package\n const packageName: PackageName = detectPackageName(baseDir);\n\n let filesToExtract = options.files ?? [];\n\n if (filesToExtract.length === 0) {\n // Filter out codeDirs that are themselves inside an excluded path (e.g. dist, node_modules)\n const isDirExcluded = (dirPath: string): boolean =>\n (excludedPath ?? []).some((pattern) => {\n const segments = pattern\n .split('/')\n .filter((s) => !s.includes('*') && s.length > 0);\n const parts = dirPath.split('/');\n return segments.some((seg) => parts.includes(seg));\n });\n\n // Await all promises simultaneously\n const resultsArray = await Promise.all(\n codeDir\n .filter((dir) => !isDirExcluded(dir))\n .map((dir) =>\n fg(traversePattern, {\n cwd: dir,\n ignore: excludedPath,\n absolute: true,\n })\n )\n );\n\n // Flatten the nested arrays and remove duplicates\n const allFiles = resultsArray.flat();\n\n const uniqueFiles = [...new Set(allFiles)].filter((file) =>\n existsSync(file)\n );\n\n // Relative paths for selection\n const choices = uniqueFiles.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"],"mappings":"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"}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{extract as e}from"./extract.mjs";import{
|
|
1
|
+
import{extract as e}from"./extract.mjs";import{listProjectsCommand as t}from"./listProjects.mjs";import{liveSync as n}from"./liveSync.mjs";import{listContentDeclaration as r,listContentDeclarationRows as i}from"./listContentDeclaration.mjs";import{findProjectRoot as a,init as o}from"./init.mjs";import{startEditor as s}from"./editor.mjs";import{build as c}from"./build.mjs";import{listMissingTranslations as l,listMissingTranslationsWithConfig as u}from"./test/listMissingTranslations.mjs";import{testMissingTranslations as d}from"./test/test.mjs";import{fill as f}from"./fill/fill.mjs";import{PLATFORM_OPTIONS as p,getDetectedPlatform as m,initSkills as h}from"./initSkills.mjs";import{pull as g}from"./pull.mjs";import{push as _}from"./push/push.mjs";import{pushConfig as v}from"./pushConfig.mjs";import{reviewDoc as y}from"./reviewDoc/reviewDoc.mjs";import{searchDoc as b}from"./searchDoc.mjs";import{translateDoc as x}from"./translateDoc/translateDoc.mjs";import{dirname as S,setAPI as C}from"./cli.mjs";export{p as PLATFORM_OPTIONS,c as build,S as dirname,e as extract,f as fill,a as findProjectRoot,m as getDetectedPlatform,o as init,h as initSkills,r as listContentDeclaration,i as listContentDeclarationRows,l as listMissingTranslations,u as listMissingTranslationsWithConfig,t as listProjectsCommand,n as liveSync,g as pull,_ as push,v as pushConfig,y as reviewDoc,b as searchDoc,C as setAPI,s as startEditor,d as testMissingTranslations,x as translateDoc};
|
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
|
|
1
|
+
import{checkCMSAuth as e}from"../utils/checkAccess.mjs";import{PushLogger as t}from"../pushLog.mjs";import{join as n}from"node:path";import{listGitFiles as r,logConfigDetails as i}from"@intlayer/chokidar/cli";import{ANSIColors as a,colorize as o,colorizeKey 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{prepareIntlayer as d,writeContentDeclaration as f}from"@intlayer/chokidar/build";import{formatPath as p,parallelize as m}from"@intlayer/chokidar/utils";import{getIntlayerAPIProxy as h}from"@intlayer/api";import*as g from"node:fs/promises";const _={pushed:{icon:`✔`,color:a.GREEN},modified:{icon:`✔`,color:a.GREEN},error:{icon:`✖`,color:a.RED},default:{icon:`⏲`,color:a.BLUE}},v=e=>_[e]??_.default,y=async p=>{let g=l(p?.configOptions);i(p?.configOptions);let _=c(g);p?.build===!0?await d(g,{forceRun:!0}):p?.build===void 0&&await d(g);try{if(!await e(g))return;let i=h(void 0,g),c=u(g),l=Object.values(c).flat(),d=Array.from(new Set(l.map(e=>e.location).filter(e=>e&&![`remote`,`local`,`hybrid`].includes(e)))),y=[];if(d.length>0){let{multiselect:e,confirm:t,isCancel:n}=await import(`@clack/prompts`);if(d.length===1){let e=await t({message:`Do you want to push dictionaries with custom location ${o(d[0],a.BLUE,a.RESET)}?`,initialValue:!1});if(n(e))return;e&&(y=[d[0]])}else{let t=await e({message:`Select custom locations to push:`,options:d.map(e=>({value:e,label:e})),required:!1});if(n(t))return;y=t}}let x=l.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 ${o(`remote`,a.BLUE,a.RESET)}, ${o(`hybrid`,a.BLUE,a.RESET)} or selected custom locations are pushed.`,{level:`warn`}),_(`You can set the location in your dictionary file (e.g. ${o(`{ key: 'my-key', location: 'hybrid', ... }`,a.BLUE,a.RESET)} or globally in your intlayer.config.ts file (e.g. ${o(`{ dictionary: { location: 'hybrid' } }`,a.BLUE,a.RESET)}).`,{level:`info`});return}let S=Object.keys(c);if(p?.dictionaries){let e=p.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=>p.dictionaries?.includes(e.key))}if(p?.gitOptions){let e=await r(p.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 m(C,async e=>{e.status=`pushing`,w.update([{dictionaryKey:e.dictionary.key,status:`pushing`}]);try{let t=await i.dictionary.pushDictionaries([e.dictionary]),n=t.data?.updatedDictionaries??[],r=t.data?.newDictionaries??[],a=[...n,...r];for(let e of a){let t=c[e.key]?.find(t=>t.localId===e.localId);t&&await f({...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`}])):r.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);_(` - ${s(e.dictionary.key)} ${a.GREY}[${n}${t} ${e.status}${a.GREY}]${a.RESET}`)}for(let e of C)e.errorMessage&&_(e.errorMessage,{level:`error`});let E=p?.deleteLocaleDictionary,D=p?.keepLocaleDictionary;if(E&&D)throw Error(`Cannot specify both --deleteLocaleDictionary and --keepLocaleDictionary options.`);if(E)await b(T,p);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? ${o(`(Dictionaries:`,a.GREY,a.RESET)} ${s(t)}${o(`)`,a.GREY,a.RESET)}`,initialValue:!1});if(r(i))return;i&&await b(e,p)}}}catch(e){_(e,{level:`error`})}},b=async(e,t)=>{let n=c(l(t?.configOptions)),r=new Set;for(let t of e){let{filePath:e}=t;if(!e){n(`Dictionary ${s(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 ${p(e)}`,{})):t.isDirectory()?n(`Path is a directory ${p(e)}, skipping.`,{}):n(`Unknown file type for ${p(e)}, skipping.`,{})}catch(t){n(`Error deleting ${p(e)}: ${t}`,{level:`error`})}};export{y as push};
|
|
2
2
|
//# sourceMappingURL=push.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{
|
|
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{ANSIColors as u,colon as d,colorize as f,colorizeNumber as p,getAppLogger as m}from"@intlayer/config/logger";import{getConfiguration as h}from"@intlayer/config/node";import{formatLocale as g,formatPath as _}from"@intlayer/chokidar/utils";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=h(D),N=m(M),P=await y(S,`utf-8`),F=await y(C,`utf-8`).catch(()=>``),I=e(`./prompts/REVIEW_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${g(w,!1)}`).replaceAll(`{{baseLocaleName}}`,`${g(T,!1)}`).replace(`{{applicationContext}}`,E?.applicationContext??`-`).replace(`{{customInstructions}}`,O??`-`),L=[d(`${u.GREY_DARK}[${_(S)}${u.GREY_DARK}] `,{colSize:40}),`→ ${u.RESET}`].join(``),R=[d(`${u.GREY_DARK}[${_(S)}${u.GREY_DARK}][${g(w)}${u.GREY_DARK}] `,{colSize:40}),`→ ${u.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=${p(z.length)}, FR=${p(B.length)}`),N(`${L}Actions: reuse=${p(V.actions.filter(e=>e.kind===`reuse`).length)}, review=${p(V.actions.filter(e=>e.kind===`review`).length)}, new=${p(V.actions.filter(e=>e.kind===`insert_new`).length)}, delete=${p(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(`${f(`✔`,u.GREEN)} File ${_(C)} updated successfully (no changes needed).`);return}N(`${L}Segments to review: ${p(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 ${g(T,!1)} as reference.\n///chunksStart///\n`+i.content+`///chunksEnd///`,c=()=>`**BLOCK ${r} of ${H.length}** is the current block to review in ${g(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 ${p(r)} of ${p(H.length)}** that should be translated in ${b(w,x.ENGLISH)} (${w}).`},{role:`user`,content:i.content}],E,M,A,j);N(`${R}${p(e.tokenUsed)} tokens used - Block ${p(r)} of ${p(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(`${f(`✔`,u.GREEN)} File ${_(C)} created/updated successfully.`)};export{S as reviewFileBlockAware};
|
|
2
2
|
//# sourceMappingURL=reviewDocBlockAware.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{
|
|
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{ANSIColors as u,colon as d,colorize as f,colorizeNumber as p,getAppLogger as m}from"@intlayer/config/logger";import{formatLocale as h,formatPath as g}from"@intlayer/chokidar/utils";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=m(w,{config:{prefix:``}}),P=y.now();try{let F=a(await v(b,`utf-8`)),I=F.length,L=`${d(`${u.GREY_DARK}[${g(b)}${u.GREY_DARK}] `,{colSize:40})}${u.RESET}`,R=`${d(`${u.GREY_DARK}[${g(b)}${u.GREY_DARK}][${h(S)}${u.GREY_DARK}] `,{colSize:40})}${u.RESET}`;N(`${L}Split into ${p(I)} chunks. Queuing...`);let z=e(`./prompts/TRANSLATE_PROMPT.md`,`utf-8`).replaceAll(`{{localeName}}`,`${h(S,!1)}`).replaceAll(`{{baseLocaleName}}`,`${h(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=m(w,{config:{prefix:`${R} ${u.GREY_DARK}[${a+1}/${I}] ${u.RESET}`}}),d=y.now(),f=a===0,h=e.content,g=()=>">>> 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()}]:[],...f?[]:[{role:`system`,content:g()}],{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${h}\n>>> TARGET CHUNK END <<<`}],E,w,O,k),o=t(e?.fileContent,h);if(o=i(o,h),!n(h,o,l))throw Error(`Validation failed for chunk ${a+1}/${I}`);return{content:o,tokens:e.tokenUsed}})(),C=(y.now()-d).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([`${p(S)} tokens used `,`${u.GREY_DARK}in ${p(C)}ms${u.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(`${f(`✔`,u.GREEN)} File ${g(G)} completed in ${p(W)}s.`),U}catch(e){T.count++;let t=e?.message??JSON.stringify(e);return N(`${f(`✖`,u.RED)} Error: ${t}`),T.count>=T.maxErrors&&(T.shouldStop=!0),null}};export{b as translateFile};
|
|
3
3
|
//# sourceMappingURL=translateFile.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":";;;;KAmBK,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/dist/types/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { FillOptions, fill } from "./fill/fill.js";
|
|
|
6
6
|
import { findProjectRoot, init } from "./init.js";
|
|
7
7
|
import { PLATFORM_OPTIONS, getDetectedPlatform, initSkills } from "./initSkills.js";
|
|
8
8
|
import { listContentDeclaration, listContentDeclarationRows } from "./listContentDeclaration.js";
|
|
9
|
+
import { ListProjectsCommandOptions, listProjectsCommand } from "./listProjects.js";
|
|
9
10
|
import { liveSync } from "./liveSync.js";
|
|
10
11
|
import { pull } from "./pull.js";
|
|
11
12
|
import { push } from "./push/push.js";
|
|
@@ -19,4 +20,4 @@ export * from "@intlayer/chokidar/cli";
|
|
|
19
20
|
export * from "@intlayer/chokidar/utils";
|
|
20
21
|
export * from "@intlayer/chokidar/build";
|
|
21
22
|
export * from "@intlayer/chokidar/watcher";
|
|
22
|
-
export { ConfigurationOptions, FillOptions, PLATFORM_OPTIONS, build, dirname, extract, fill, findProjectRoot, getDetectedPlatform, init, initSkills, listContentDeclaration, listContentDeclarationRows, listMissingTranslations, listMissingTranslationsWithConfig, liveSync, pull, push, pushConfig, reviewDoc, searchDoc, setAPI, startEditor, testMissingTranslations, translateDoc };
|
|
23
|
+
export { ConfigurationOptions, FillOptions, ListProjectsCommandOptions, PLATFORM_OPTIONS, build, dirname, extract, fill, findProjectRoot, getDetectedPlatform, init, initSkills, listContentDeclaration, listContentDeclarationRows, listMissingTranslations, listMissingTranslationsWithConfig, listProjectsCommand, liveSync, pull, push, pushConfig, reviewDoc, searchDoc, setAPI, startEditor, testMissingTranslations, translateDoc };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/cli",
|
|
3
|
-
"version": "8.3.0-canary.
|
|
3
|
+
"version": "8.3.0-canary.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,33 +67,33 @@
|
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@clack/prompts": "0.11.0",
|
|
70
|
-
"@intlayer/ai": "8.3.0-canary.
|
|
71
|
-
"@intlayer/api": "8.3.0-canary.
|
|
72
|
-
"@intlayer/babel": "8.3.0-canary.
|
|
73
|
-
"@intlayer/chokidar": "8.3.0-canary.
|
|
74
|
-
"@intlayer/config": "8.3.0-canary.
|
|
75
|
-
"@intlayer/core": "8.3.0-canary.
|
|
76
|
-
"@intlayer/dictionaries-entry": "8.3.0-canary.
|
|
77
|
-
"@intlayer/remote-dictionaries-entry": "8.3.0-canary.
|
|
78
|
-
"@intlayer/types": "8.3.0-canary.
|
|
79
|
-
"@intlayer/unmerged-dictionaries-entry": "8.3.0-canary.
|
|
70
|
+
"@intlayer/ai": "8.3.0-canary.1",
|
|
71
|
+
"@intlayer/api": "8.3.0-canary.1",
|
|
72
|
+
"@intlayer/babel": "8.3.0-canary.1",
|
|
73
|
+
"@intlayer/chokidar": "8.3.0-canary.1",
|
|
74
|
+
"@intlayer/config": "8.3.0-canary.1",
|
|
75
|
+
"@intlayer/core": "8.3.0-canary.1",
|
|
76
|
+
"@intlayer/dictionaries-entry": "8.3.0-canary.1",
|
|
77
|
+
"@intlayer/remote-dictionaries-entry": "8.3.0-canary.1",
|
|
78
|
+
"@intlayer/types": "8.3.0-canary.1",
|
|
79
|
+
"@intlayer/unmerged-dictionaries-entry": "8.3.0-canary.1",
|
|
80
80
|
"commander": "14.0.3",
|
|
81
81
|
"enquirer": "^2.4.1",
|
|
82
82
|
"eventsource": "4.1.0",
|
|
83
83
|
"fast-glob": "3.3.3"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
|
-
"@types/node": "25.
|
|
86
|
+
"@types/node": "25.4.0",
|
|
87
87
|
"@utils/ts-config": "1.0.4",
|
|
88
88
|
"@utils/ts-config-types": "1.0.4",
|
|
89
89
|
"@utils/tsdown-config": "1.0.4",
|
|
90
90
|
"rimraf": "6.1.3",
|
|
91
|
-
"tsdown": "0.21.
|
|
91
|
+
"tsdown": "0.21.2",
|
|
92
92
|
"typescript": "5.9.3",
|
|
93
93
|
"vitest": "4.0.18"
|
|
94
94
|
},
|
|
95
95
|
"peerDependencies": {
|
|
96
|
-
"@intlayer/ai": "8.3.0-canary.
|
|
96
|
+
"@intlayer/ai": "8.3.0-canary.1"
|
|
97
97
|
},
|
|
98
98
|
"peerDependenciesMeta": {
|
|
99
99
|
"@intlayer/ai": {
|