@intlayer/chokidar 8.1.4 → 8.1.6
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/cli.cjs +1 -1
- package/dist/cjs/getContentDeclarationFileTemplate/index.cjs +1 -0
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/installSkills/index.cjs +1 -1
- package/dist/cjs/listGitFiles.cjs +3 -3
- package/dist/cjs/loadDictionaries/loadContentDeclaration.cjs +2 -2
- package/dist/cjs/loadDictionaries/loadContentDeclaration.cjs.map +1 -1
- package/dist/cjs/loadDictionaries/logTypeScriptErrors.cjs +3 -0
- package/dist/cjs/loadDictionaries/logTypeScriptErrors.cjs.map +1 -0
- package/dist/cjs/transformFiles/index.cjs +1 -1
- package/dist/cjs/transformFiles/transformFiles.cjs +1 -1
- package/dist/cjs/transformFiles/transformFiles.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/processContentDeclarationContent.cjs +1 -1
- package/dist/cjs/writeContentDeclaration/writeContentDeclaration.cjs +1 -1
- package/dist/cjs/writeContentDeclaration/writeContentDeclaration.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/writeJSFile.cjs +1 -1
- package/dist/cjs/writeContentDeclaration/writeJSFile.cjs.map +1 -1
- package/dist/cjs/writeFileIfChanged.cjs +1 -1
- package/dist/cjs/writeFileIfChanged.cjs.map +1 -1
- package/dist/esm/cli.mjs +1 -1
- package/dist/esm/getContentDeclarationFileTemplate/index.mjs +1 -0
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/installSkills/index.mjs +1 -1
- package/dist/esm/listGitFiles.mjs +3 -3
- package/dist/esm/loadDictionaries/loadContentDeclaration.mjs +2 -2
- package/dist/esm/loadDictionaries/loadContentDeclaration.mjs.map +1 -1
- package/dist/esm/loadDictionaries/logTypeScriptErrors.mjs +3 -0
- package/dist/esm/loadDictionaries/logTypeScriptErrors.mjs.map +1 -0
- package/dist/esm/transformFiles/index.mjs +1 -1
- package/dist/esm/transformFiles/transformFiles.mjs +1 -1
- package/dist/esm/transformFiles/transformFiles.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/processContentDeclarationContent.mjs +1 -1
- package/dist/esm/writeContentDeclaration/writeContentDeclaration.mjs +1 -1
- package/dist/esm/writeContentDeclaration/writeContentDeclaration.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/writeJSFile.mjs +1 -1
- package/dist/esm/writeContentDeclaration/writeJSFile.mjs.map +1 -1
- package/dist/esm/writeFileIfChanged.mjs +1 -1
- package/dist/esm/writeFileIfChanged.mjs.map +1 -1
- package/dist/types/cli.d.ts +4 -2
- package/dist/types/getContentDeclarationFileTemplate/index.d.ts +2 -0
- package/dist/types/index.d.ts +5 -3
- package/dist/types/loadDictionaries/loadContentDeclaration.d.ts.map +1 -1
- package/dist/types/loadDictionaries/logTypeScriptErrors.d.ts +7 -0
- package/dist/types/loadDictionaries/logTypeScriptErrors.d.ts.map +1 -0
- package/dist/types/transformFiles/index.d.ts +2 -2
- package/dist/types/transformFiles/transformFiles.d.ts +1 -5
- package/dist/types/transformFiles/transformFiles.d.ts.map +1 -1
- package/dist/types/writeFileIfChanged.d.ts +4 -2
- package/dist/types/writeFileIfChanged.d.ts.map +1 -1
- package/package.json +10 -10
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{parallelize as e}from"../utils/parallelize.mjs";import{filterInvalidDictionaries as t}from"../filterInvalidDictionaries.mjs";import{processContentDeclaration as n}from"../buildIntlayerDictionary/processContentDeclaration.mjs";import{getIntlayerBundle as r}from"./getIntlayerBundle.mjs";import{
|
|
2
|
-
`)}},aliases:{intlayer:
|
|
1
|
+
import{parallelize as e}from"../utils/parallelize.mjs";import{filterInvalidDictionaries as t}from"../filterInvalidDictionaries.mjs";import{processContentDeclaration as n}from"../buildIntlayerDictionary/processContentDeclaration.mjs";import{getIntlayerBundle as r}from"./getIntlayerBundle.mjs";import{logTypeScriptErrors as i}from"./logTypeScriptErrors.mjs";import{writeFile as a}from"node:fs/promises";import{join as o,relative as s}from"node:path";import{cacheDisk as c,getProjectRequire as l}from"@intlayer/config/utils";import{loadExternalFile as u}from"@intlayer/config/file";const d=(e,t)=>Object.entries(e).map(([e,n])=>({...n,location:n.location??t.dictionary?.location??`local`,localId:`${n.key}::local::${e}`,filePath:e})),f=async(f,p,m)=>{let{build:h,system:g}=p;h.checkTypes&&i(f,p).catch(e=>{console.error(`Error during TypeScript validation:`,e)});let{set:_,isValid:v,clear:y}=c(p,[`intlayer-bundle`],{ttlMs:1e3*60*60*24*5}),b=o(g.cacheDir,`intlayer-bundle.cjs`);await v()||(await a(b,await r(p)),await _(`ok`));try{let r=f.map(async e=>({relativePath:s(p.content.baseDir,e),dictionary:await u(e,{projectRequire:h.require??l(),buildOptions:{banner:{js:[`globalThis.INTLAYER_FILE_PATH = '${e}';`,`globalThis.INTLAYER_BASE_DIR = '${p.content.baseDir}';`].join(`
|
|
2
|
+
`)}},aliases:{intlayer:b}})})),i=d((await Promise.all(r)).reduce((e,{relativePath:t,dictionary:n})=>(e[t]=n,e),{}),p).filter(e=>e.location!==`remote`),a=i.map(e=>({dictionaryKey:e.key,type:`local`,status:`found`}));return m?.(a),t(await e(i,async e=>{if(!e)return;m?.([{dictionaryKey:e.key,type:`local`,status:`building`}]);let t=await n(e,p);if(t)return m?.([{dictionaryKey:t.key,type:`local`,status:`built`}]),t}),p,{checkSchema:!1})}catch{console.error(`Error loading content declarations`),await y()}return[]};export{d as formatLocalDictionaries,f as loadContentDeclarations};
|
|
3
3
|
//# sourceMappingURL=loadContentDeclaration.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadContentDeclaration.mjs","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"sourcesContent":["import { writeFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { loadExternalFile } from '@intlayer/config/file';\nimport { cacheDisk, getProjectRequire } from '@intlayer/config/utils';\nimport type { Dictionary, IntlayerConfig } from '@intlayer/types';\nimport { processContentDeclaration } from '../buildIntlayerDictionary/processContentDeclaration';\nimport { filterInvalidDictionaries } from '../filterInvalidDictionaries';\nimport { parallelize } from '../utils/parallelize';\nimport { getIntlayerBundle } from './getIntlayerBundle';\nimport type { DictionariesStatus } from './loadDictionaries';\n\nexport const formatLocalDictionaries = (\n dictionariesRecord: Record<string, Dictionary>,\n configuration: IntlayerConfig\n): Dictionary[] =>\n Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({\n ...dict,\n location: dict.location ?? configuration.dictionary?.location ?? 'local',\n localId: `${dict.key}::local::${relativePath}`,\n filePath: relativePath,\n }));\n\nexport const loadContentDeclarations = async (\n contentDeclarationFilePath: string[],\n configuration: IntlayerConfig,\n onStatusUpdate?: (status: DictionariesStatus[]) => void\n): Promise<Dictionary[]> => {\n const { build, system } = configuration;\n\n const { set, isValid, clear } = cacheDisk(\n configuration,\n ['intlayer-bundle'],\n {\n ttlMs: 1000 * 60 * 60 * 24 * 5, // 5 days\n }\n );\n\n const filePath = join(system.cacheDir, 'intlayer-bundle.cjs');\n const hasIntlayerBundle = await isValid();\n\n // If cache is invalid, write the intlayer bundle to the cache\n if (!hasIntlayerBundle) {\n const intlayerBundle = await getIntlayerBundle(configuration);\n await writeFile(filePath, intlayerBundle);\n await set('ok');\n }\n\n try {\n const dictionariesPromises = contentDeclarationFilePath.map(\n async (path) => {\n const relativePath = relative(configuration.content.baseDir, path);\n\n const dictionary = await loadExternalFile(path, {\n projectRequire: build.require ?? getProjectRequire(),\n buildOptions: {\n banner: {\n js: [\n `globalThis.INTLAYER_FILE_PATH = '${path}';`,\n `globalThis.INTLAYER_BASE_DIR = '${configuration.content.baseDir}';`,\n ].join('\\n'),\n },\n },\n aliases: {\n intlayer: filePath,\n },\n });\n\n return { relativePath, dictionary };\n }\n );\n\n const dictionariesArray = await Promise.all(dictionariesPromises);\n const dictionariesRecord = dictionariesArray.reduce(\n (acc, { relativePath, dictionary }) => {\n acc[relativePath] = dictionary;\n return acc;\n },\n {} as Record<string, Dictionary>\n );\n\n const contentDeclarations: Dictionary[] = formatLocalDictionaries(\n dictionariesRecord,\n configuration\n ).filter((dictionary) => dictionary.location !== 'remote');\n\n const listFoundDictionaries = contentDeclarations.map((declaration) => ({\n dictionaryKey: declaration.key,\n type: 'local' as const,\n status: 'found' as const,\n }));\n\n onStatusUpdate?.(listFoundDictionaries);\n\n const processedDictionaries = await parallelize(\n contentDeclarations,\n async (contentDeclaration): Promise<Dictionary | undefined> => {\n if (!contentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: contentDeclaration.key,\n type: 'local',\n status: 'building',\n },\n ]);\n\n const processedContentDeclaration = await processContentDeclaration(\n contentDeclaration as Dictionary,\n configuration\n );\n\n if (!processedContentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: processedContentDeclaration.key,\n type: 'local',\n status: 'built',\n },\n ]);\n\n return processedContentDeclaration;\n }\n );\n\n return filterInvalidDictionaries(processedDictionaries, configuration, {\n checkSchema: false,\n });\n } catch {\n console.error('Error loading content declarations');\n await clear();\n }\n\n return [];\n};\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"loadContentDeclaration.mjs","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"sourcesContent":["import { writeFile } from 'node:fs/promises';\nimport { join, relative } from 'node:path';\nimport { loadExternalFile } from '@intlayer/config/file';\nimport { cacheDisk, getProjectRequire } from '@intlayer/config/utils';\nimport type { Dictionary, IntlayerConfig } from '@intlayer/types';\nimport { processContentDeclaration } from '../buildIntlayerDictionary/processContentDeclaration';\nimport { filterInvalidDictionaries } from '../filterInvalidDictionaries';\nimport { parallelize } from '../utils/parallelize';\nimport { getIntlayerBundle } from './getIntlayerBundle';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { logTypeScriptErrors } from './logTypeScriptErrors';\n\nexport const formatLocalDictionaries = (\n dictionariesRecord: Record<string, Dictionary>,\n configuration: IntlayerConfig\n): Dictionary[] =>\n Object.entries(dictionariesRecord).map(([relativePath, dict]) => ({\n ...dict,\n location: dict.location ?? configuration.dictionary?.location ?? 'local',\n localId: `${dict.key}::local::${relativePath}`,\n filePath: relativePath,\n }));\n\nexport const loadContentDeclarations = async (\n contentDeclarationFilePath: string[],\n configuration: IntlayerConfig,\n onStatusUpdate?: (status: DictionariesStatus[]) => void\n): Promise<Dictionary[]> => {\n const { build, system } = configuration;\n\n // Check for TypeScript warnings before we build\n if (build.checkTypes) {\n logTypeScriptErrors(contentDeclarationFilePath, configuration).catch(\n (e) => {\n console.error('Error during TypeScript validation:', e);\n }\n );\n }\n\n const { set, isValid, clear } = cacheDisk(\n configuration,\n ['intlayer-bundle'],\n {\n ttlMs: 1000 * 60 * 60 * 24 * 5, // 5 days\n }\n );\n\n const filePath = join(system.cacheDir, 'intlayer-bundle.cjs');\n const hasIntlayerBundle = await isValid();\n\n // If cache is invalid, write the intlayer bundle to the cache\n if (!hasIntlayerBundle) {\n const intlayerBundle = await getIntlayerBundle(configuration);\n await writeFile(filePath, intlayerBundle);\n await set('ok');\n }\n\n try {\n const dictionariesPromises = contentDeclarationFilePath.map(\n async (path) => {\n const relativePath = relative(configuration.content.baseDir, path);\n\n const dictionary = await loadExternalFile(path, {\n projectRequire: build.require ?? getProjectRequire(),\n buildOptions: {\n banner: {\n js: [\n `globalThis.INTLAYER_FILE_PATH = '${path}';`,\n `globalThis.INTLAYER_BASE_DIR = '${configuration.content.baseDir}';`,\n ].join('\\n'),\n },\n },\n aliases: {\n intlayer: filePath,\n },\n });\n\n return { relativePath, dictionary };\n }\n );\n\n const dictionariesArray = await Promise.all(dictionariesPromises);\n const dictionariesRecord = dictionariesArray.reduce(\n (acc, { relativePath, dictionary }) => {\n acc[relativePath] = dictionary;\n return acc;\n },\n {} as Record<string, Dictionary>\n );\n\n const contentDeclarations: Dictionary[] = formatLocalDictionaries(\n dictionariesRecord,\n configuration\n ).filter((dictionary) => dictionary.location !== 'remote');\n\n const listFoundDictionaries = contentDeclarations.map((declaration) => ({\n dictionaryKey: declaration.key,\n type: 'local' as const,\n status: 'found' as const,\n }));\n\n onStatusUpdate?.(listFoundDictionaries);\n\n const processedDictionaries = await parallelize(\n contentDeclarations,\n async (contentDeclaration): Promise<Dictionary | undefined> => {\n if (!contentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: contentDeclaration.key,\n type: 'local',\n status: 'building',\n },\n ]);\n\n const processedContentDeclaration = await processContentDeclaration(\n contentDeclaration as Dictionary,\n configuration\n );\n\n if (!processedContentDeclaration) {\n return undefined;\n }\n\n onStatusUpdate?.([\n {\n dictionaryKey: processedContentDeclaration.key,\n type: 'local',\n status: 'built',\n },\n ]);\n\n return processedContentDeclaration;\n }\n );\n\n return filterInvalidDictionaries(processedDictionaries, configuration, {\n checkSchema: false,\n });\n } catch {\n console.error('Error loading content declarations');\n await clear();\n }\n\n return [];\n};\n"],"mappings":"okBAYA,MAAa,GACX,EACA,IAEA,OAAO,QAAQ,EAAmB,CAAC,KAAK,CAAC,EAAc,MAAW,CAChE,GAAG,EACH,SAAU,EAAK,UAAY,EAAc,YAAY,UAAY,QACjE,QAAS,GAAG,EAAK,IAAI,WAAW,IAChC,SAAU,EACX,EAAE,CAEQ,EAA0B,MACrC,EACA,EACA,IAC0B,CAC1B,GAAM,CAAE,QAAO,UAAW,EAGtB,EAAM,YACR,EAAoB,EAA4B,EAAc,CAAC,MAC5D,GAAM,CACL,QAAQ,MAAM,sCAAuC,EAAE,EAE1D,CAGH,GAAM,CAAE,MAAK,UAAS,SAAU,EAC9B,EACA,CAAC,kBAAkB,CACnB,CACE,MAAO,IAAO,GAAK,GAAK,GAAK,EAC9B,CACF,CAEK,EAAW,EAAK,EAAO,SAAU,sBAAsB,CACnC,MAAM,GAAS,GAKvC,MAAM,EAAU,EADO,MAAM,EAAkB,EAAc,CACpB,CACzC,MAAM,EAAI,KAAK,EAGjB,GAAI,CACF,IAAM,EAAuB,EAA2B,IACtD,KAAO,KAkBE,CAAE,aAjBY,EAAS,EAAc,QAAQ,QAAS,EAAK,CAiB3C,WAfJ,MAAM,EAAiB,EAAM,CAC9C,eAAgB,EAAM,SAAW,GAAmB,CACpD,aAAc,CACZ,OAAQ,CACN,GAAI,CACF,oCAAoC,EAAK,IACzC,mCAAmC,EAAc,QAAQ,QAAQ,IAClE,CAAC,KAAK;EAAK,CACb,CACF,CACD,QAAS,CACP,SAAU,EACX,CACF,CAAC,CAEiC,EAEtC,CAWK,EAAoC,GAThB,MAAM,QAAQ,IAAI,EAAqB,EACpB,QAC1C,EAAK,CAAE,eAAc,iBACpB,EAAI,GAAgB,EACb,GAET,EAAE,CACH,CAIC,EACD,CAAC,OAAQ,GAAe,EAAW,WAAa,SAAS,CAEpD,EAAwB,EAAoB,IAAK,IAAiB,CACtE,cAAe,EAAY,IAC3B,KAAM,QACN,OAAQ,QACT,EAAE,CAwCH,OAtCA,IAAiB,EAAsB,CAsChC,EApCuB,MAAM,EAClC,EACA,KAAO,IAAwD,CAC7D,GAAI,CAAC,EACH,OAGF,IAAiB,CACf,CACE,cAAe,EAAmB,IAClC,KAAM,QACN,OAAQ,WACT,CACF,CAAC,CAEF,IAAM,EAA8B,MAAM,EACxC,EACA,EACD,CAEI,KAYL,OARA,IAAiB,CACf,CACE,cAAe,EAA4B,IAC3C,KAAM,QACN,OAAQ,QACT,CACF,CAAC,CAEK,GAEV,CAEuD,EAAe,CACrE,YAAa,GACd,CAAC,MACI,CACN,QAAQ,MAAM,qCAAqC,CACnD,MAAM,GAAO,CAGf,MAAO,EAAE"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{dirname as e,extname as t}from"node:path";import{getAppLogger as n}from"@intlayer/config";const r=async(r,i)=>{let a=n(i),o=r.filter(e=>{let n=t(e);return[`.ts`,`.tsx`,`.js`,`.jsx`,`.cjs`,`.mjs`,`.json`].includes(n)});if(o.length===0)return;let s;try{s=(await import(`typescript`)).default||await import(`typescript`)}catch{return}let c=s.findConfigFile(i.content?.baseDir??process.cwd(),s.sys.fileExists,`tsconfig.json`),l={noEmit:!0,allowJs:!0,resolveJsonModule:!0};if(c){let t=s.sys.readFile(c);if(t){let n=s.parseConfigFileTextToJson(c,t);if(!n.error){let{incremental:t,tsBuildInfoFile:r,...i}=s.parseJsonConfigFileContent(n.config,s.sys,e(c)).options;l={...l,...i,noEmit:!0}}}}let u=s.createProgram(o,l);o.forEach(e=>{let t=u.getSourceFile(e);t&&s.getPreEmitDiagnostics(u,t).forEach(e=>{let t=s.flattenDiagnosticMessageText(e.messageText,`
|
|
2
|
+
`);if(e.file&&e.start!==void 0){let{line:n,character:r}=e.file.getLineAndCharacterOfPosition(e.start);a(`TS Error in ${e.file.fileName} (${n+1},${r+1}): ${t}`,{level:`warn`})}})})};export{r as logTypeScriptErrors};
|
|
3
|
+
//# sourceMappingURL=logTypeScriptErrors.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logTypeScriptErrors.mjs","names":[],"sources":["../../../src/loadDictionaries/logTypeScriptErrors.ts"],"sourcesContent":["import { dirname, extname } from 'node:path';\n\nimport { getAppLogger } from '@intlayer/config';\n\nimport type { IntlayerConfig } from '@intlayer/types';\n\nexport const logTypeScriptErrors = async (\n filePaths: string[],\n\n configuration: IntlayerConfig\n) => {\n const appLogger = getAppLogger(configuration);\n\n const filesToCheck = filePaths.filter((path) => {\n const ext = extname(path);\n\n return ['.ts', '.tsx', '.js', '.jsx', '.cjs', '.mjs', '.json'].includes(\n ext\n );\n });\n\n if (filesToCheck.length === 0) return;\n\n let ts: typeof import('typescript');\n\n try {\n ts = (await import('typescript')).default || (await import('typescript'));\n } catch {\n // TypeScript not installed, skip type checking\n\n return;\n }\n\n const configFileName = ts.findConfigFile(\n configuration.content?.baseDir ?? process.cwd(),\n\n ts.sys.fileExists,\n\n 'tsconfig.json'\n );\n\n let compilerOptions: any = {\n noEmit: true,\n\n allowJs: true,\n\n resolveJsonModule: true,\n };\n\n if (configFileName) {\n const configFileText = ts.sys.readFile(configFileName);\n\n if (configFileText) {\n const configJson = ts.parseConfigFileTextToJson(\n configFileName,\n\n configFileText\n );\n\n if (!configJson.error) {\n const parsedConfig = ts.parseJsonConfigFileContent(\n configJson.config,\n\n ts.sys,\n\n dirname(configFileName)\n );\n\n const { incremental, tsBuildInfoFile, ...restOptions } =\n parsedConfig.options;\n\n compilerOptions = { ...compilerOptions, ...restOptions, noEmit: true };\n }\n }\n }\n\n const program = ts.createProgram(filesToCheck, compilerOptions);\n\n filesToCheck.forEach((filePath) => {\n const sourceFile = program.getSourceFile(filePath);\n\n if (!sourceFile) return;\n\n const diagnostics = ts.getPreEmitDiagnostics(program, sourceFile);\n\n diagnostics.forEach((diagnostic) => {\n const message = ts.flattenDiagnosticMessageText(\n diagnostic.messageText,\n\n '\\n'\n );\n\n if (diagnostic.file && diagnostic.start !== undefined) {\n const { line, character } =\n diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);\n\n appLogger(\n `TS Error in ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`,\n\n { level: 'warn' }\n );\n }\n });\n });\n};\n"],"mappings":"iGAMA,MAAa,EAAsB,MACjC,EAEA,IACG,CACH,IAAM,EAAY,EAAa,EAAc,CAEvC,EAAe,EAAU,OAAQ,GAAS,CAC9C,IAAM,EAAM,EAAQ,EAAK,CAEzB,MAAO,CAAC,MAAO,OAAQ,MAAO,OAAQ,OAAQ,OAAQ,QAAQ,CAAC,SAC7D,EACD,EACD,CAEF,GAAI,EAAa,SAAW,EAAG,OAE/B,IAAI,EAEJ,GAAI,CACF,GAAM,MAAM,OAAO,eAAe,SAAY,MAAM,OAAO,mBACrD,CAGN,OAGF,IAAM,EAAiB,EAAG,eACxB,EAAc,SAAS,SAAW,QAAQ,KAAK,CAE/C,EAAG,IAAI,WAEP,gBACD,CAEG,EAAuB,CACzB,OAAQ,GAER,QAAS,GAET,kBAAmB,GACpB,CAED,GAAI,EAAgB,CAClB,IAAM,EAAiB,EAAG,IAAI,SAAS,EAAe,CAEtD,GAAI,EAAgB,CAClB,IAAM,EAAa,EAAG,0BACpB,EAEA,EACD,CAED,GAAI,CAAC,EAAW,MAAO,CASrB,GAAM,CAAE,cAAa,kBAAiB,GAAG,GARpB,EAAG,2BACtB,EAAW,OAEX,EAAG,IAEH,EAAQ,EAAe,CACxB,CAGc,QAEf,EAAkB,CAAE,GAAG,EAAiB,GAAG,EAAa,OAAQ,GAAM,GAK5E,IAAM,EAAU,EAAG,cAAc,EAAc,EAAgB,CAE/D,EAAa,QAAS,GAAa,CACjC,IAAM,EAAa,EAAQ,cAAc,EAAS,CAE7C,GAEe,EAAG,sBAAsB,EAAS,EAAW,CAErD,QAAS,GAAe,CAClC,IAAM,EAAU,EAAG,6BACjB,EAAW,YAEX;EACD,CAED,GAAI,EAAW,MAAQ,EAAW,QAAU,IAAA,GAAW,CACrD,GAAM,CAAE,OAAM,aACZ,EAAW,KAAK,8BAA8B,EAAW,MAAM,CAEjE,EACE,eAAe,EAAW,KAAK,SAAS,IAAI,EAAO,EAAE,GAAG,EAAY,EAAE,KAAK,IAE3E,CAAE,MAAO,OAAQ,CAClB,GAEH,EACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{extractDictionaryKey as e}from"./extractDictionaryKey.mjs";import{ATTRIBUTES_TO_EXTRACT as t,extractIntlayer as n,
|
|
1
|
+
import{extractDictionaryKey as e}from"./extractDictionaryKey.mjs";import{ATTRIBUTES_TO_EXTRACT as t,extractIntlayer as n,shouldExtract as r,transformFiles as i}from"./transformFiles.mjs";export{t as ATTRIBUTES_TO_EXTRACT,e as extractDictionaryKey,n as extractIntlayer,r as shouldExtract,i as transformFiles};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{detectFormatCommand as e}from"../writeContentDeclaration/detectFormatCommand.mjs";import{writeContentDeclaration as t}from"../writeContentDeclaration/writeContentDeclaration.mjs";import{extractDictionaryKey as n}from"./extractDictionaryKey.mjs";import{getConfiguration as r}from"@intlayer/config/node";import i from"node:fs/promises";import{basename as a,dirname as o,extname as s,join as c,relative as l,resolve as u}from"node:path";import{ANSIColors as d,colorizePath as f,getAppLogger as p}from"@intlayer/config/logger";import{camelCaseToKebabCase as m}from"@intlayer/config/utils";import{Node as h,Project as g,SyntaxKind as _}from"ts-morph";import{execSync as v}from"node:child_process";const
|
|
1
|
+
import{detectFormatCommand as e}from"../writeContentDeclaration/detectFormatCommand.mjs";import{writeContentDeclaration as t}from"../writeContentDeclaration/writeContentDeclaration.mjs";import{extractDictionaryKey as n}from"./extractDictionaryKey.mjs";import{getConfiguration as r}from"@intlayer/config/node";import i from"node:fs/promises";import{basename as a,dirname as o,extname as s,join as c,relative as l,resolve as u}from"node:path";import{ANSIColors as d,colorizePath as f,getAppLogger as p}from"@intlayer/config/logger";import{camelCaseToKebabCase as m}from"@intlayer/config/utils";import{Node as h,Project as g,SyntaxKind as _}from"ts-morph";import{execSync as v}from"node:child_process";import{generateKey as y}from"@intlayer/core/utils";const b=[`title`,`placeholder`,`alt`,`aria-label`,`label`],x=e=>{let t=e.trim();return!(!t||!t.includes(` `)||!/^[A-Z]/.test(t)||t.startsWith(`{`)||t.startsWith(`v-`))},S=async(e,n,r,i,d)=>{let{defaultLocale:f}=i.internationalization,{baseDir:p,fileExtensions:m}=i.content,h=i?.dictionary?.locale,g=d?u(d):o(r),_=a(r,s(r)),v=c(g,`${_.charAt(0).toLowerCase()+_.slice(1)}.${m[0]}`),y=l(p,v),b;if(h)b={key:n,content:e,locale:f,filePath:y};else{let t={};for(let[n,r]of Object.entries(e))t[n]={nodeType:`translation`,translation:{[f]:r}};b={key:n,content:t,filePath:y}}let x=l(p,g);return await t(b,i,{newDictionariesPath:x}),v},C=(e,t)=>{let n={},r=[];return e.forEachDescendant(e=>{if(h.isJsxText(e)){let i=e.getText();if(x(i)){let a=y(i,t);t.add(a),n[a]=i.replace(/\s+/g,` `).trim(),r.push({node:e,key:a,type:`jsx-text`})}}else if(h.isJsxAttribute(e)){let i=e.getNameNode().getText();if(b.includes(i)){let i=e.getInitializer();if(h.isStringLiteral(i)){let a=i.getLiteralValue();if(x(a)){let i=y(a,t);t.add(i),n[i]=a.trim(),r.push({node:e,key:i,type:`jsx-attribute`})}}}}else if(h.isStringLiteral(e)){let i=e.getLiteralValue();if(x(i)){let a=e.getParent();if(a?.getKindName()===`ImportDeclaration`||a?.getKindName()===`ImportSpecifier`||a?.getKindName()===`ModuleSpecifier`||h.isJsxAttribute(a)||h.isCallExpression(a)&&a.getExpression().getText().includes(`console.log`)||h.isPropertyAssignment(a)&&a.getNameNode()===e)return;let o=y(i,t);t.add(o),n[o]=i.trim(),r.push({node:e,key:o,type:`string-literal`})}}}),{extractedContent:n,replacements:r}},w=async(e,t,n,r,i=!0)=>{let a;try{a=r.addSourceFileAtPath(e)}catch{a=r.getSourceFileOrThrow(e)}let o=n===`solid-intlayer`,{extractedContent:s,replacements:c}=C(a,new Set);if(Object.keys(s).length===0)return null;for(let{node:e,key:t,type:n}of c){let r=o?`content().${t}`:`content.${t}`;n===`jsx-text`&&h.isJsxText(e)?e.replaceWithText(`{${r}}`):n===`jsx-attribute`&&h.isJsxAttribute(e)?e.setInitializer(`{${r}.value}`):n===`string-literal`&&h.isStringLiteral(e)&&e.replaceWithText(`${r}.value`)}let l=a.getImportDeclaration(e=>e.getModuleSpecifierValue()===n);return l?l.getNamedImports().some(e=>e.getName()===`useIntlayer`)||l.addNamedImport(`useIntlayer`):a.addImportDeclaration({namedImports:[`useIntlayer`],moduleSpecifier:n}),a.getFunctions().forEach(e=>{e.getBody()?.asKind(_.Block)?.insertStatements(0,`const content = useIntlayer("${t}");`)}),a.getVariableDeclarations().forEach(e=>{let n=e.getInitializer();if(h.isArrowFunction(n)||h.isFunctionExpression(n)){let e=n.getBody();h.isBlock(e)&&(e.getText().includes(`return`)||e.getText().includes(`use`))&&e.insertStatements(0,`const content = useIntlayer("${t}");`)}}),i&&await a.save(),s},T=async(t,a,o,c)=>{let u=!o?.declarationOnly,h=!o?.codeOnly,_=r(o?.configOptions),b=p(_),{baseDir:T}=_.content,E=c||new g({skipAddingFilesFromTsConfig:!0}),D=n(t,(await i.readFile(t)).toString()),O=m(D),k=s(t),A=null;if(k===`.vue`)try{let{processVueFile:e}=await import(`@intlayer/vue-transformer`);A=await e(t,O,a,{generateKey:y,shouldExtract:x,extractTsContent:C},u)}catch(e){throw e.code===`ERR_MODULE_NOT_FOUND`||e.message?.includes(`Cannot find module`)?Error(`Please install ${f(`@intlayer/vue-transformer`,d.YELLOW)} to process Vue files.`):e}else if(k===`.svelte`)try{let{processSvelteFile:e}=await import(`@intlayer/svelte-transformer`);A=await e(t,O,a,{generateKey:y,shouldExtract:x,extractTsContent:C},u)}catch(e){throw e.code===`ERR_MODULE_NOT_FOUND`||e.message?.includes(`Cannot find module`)?Error(`Please install ${f(`@intlayer/svelte-transformer`,d.YELLOW)} to process Svelte files.`):e}else [`.tsx`,`.jsx`,`.ts`,`.js`].includes(k)&&(A=await w(t,O,a,E,u));if(!A){b(`No extractable text found in ${D}`);return}if(h){let e=await S(A,O,t,_,o?.outputDir);b(`Created content file: ${f(l(_.content.baseDir,e))}`)}if(u){try{let n=e(_);n&&v(n.replace(`{{file}}`,t),{stdio:`ignore`,cwd:T})}catch{}b(`Updated component: ${f(l(T,t))}`)}},E=async(e,t,n)=>{let i=p(r(n?.configOptions)),a=new g({skipAddingFilesFromTsConfig:!0});for(let r of e)try{await T(r,t,n,a)}catch(e){i(`Failed to transform ${r}: ${e.message}`)}};export{b as ATTRIBUTES_TO_EXTRACT,T as extractIntlayer,x as shouldExtract,E as transformFiles};
|
|
2
2
|
//# sourceMappingURL=transformFiles.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformFiles.mjs","names":[],"sources":["../../../src/transformFiles/transformFiles.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport fs from 'node:fs/promises';\nimport { basename, dirname, extname, join, relative, resolve } from 'node:path';\nimport {\n ANSIColors,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { camelCaseToKebabCase } from '@intlayer/config/utils';\nimport type { Dictionary, IntlayerConfig } from '@intlayer/types';\nimport { Node, Project, type SourceFile, SyntaxKind } from 'ts-morph';\nimport { writeContentDeclaration } from '../writeContentDeclaration';\nimport { detectFormatCommand } from '../writeContentDeclaration/detectFormatCommand';\nimport { extractDictionaryKey } from './extractDictionaryKey';\n\n// ==========================================\n// Shared Utilities (exported for reuse in babel plugin)\n// ==========================================\n\n/**\n * Attributes that should be extracted for localization\n */\nexport const ATTRIBUTES_TO_EXTRACT = [\n 'title',\n 'placeholder',\n 'alt',\n 'aria-label',\n 'label',\n];\n\n/**\n * Default function to determine if a string should be extracted for localization\n */\nexport const shouldExtract = (text: string): boolean => {\n const trimmed = text.trim();\n if (!trimmed) return false;\n if (!trimmed.includes(' ')) return false;\n // Starts with Capital letter\n if (!/^[A-Z]/.test(trimmed)) return false;\n // Filter out template logic identifiers (simple check)\n if (trimmed.startsWith('{') || trimmed.startsWith('v-')) return false;\n return true;\n};\n\n/**\n * Generate a unique key from text for use as a dictionary key\n */\nexport const generateKey = (\n text: string,\n existingKeys: Set<string>\n): string => {\n const maxWords = 5;\n let key = text\n .replace(/\\s+/g, ' ')\n .replace(/_+/g, ' ')\n .replace(/-+/g, ' ')\n .replace(/[^a-zA-Z0-9 ]/g, '')\n .trim()\n .split(' ')\n .filter(Boolean)\n .slice(0, maxWords)\n .map((word, index) =>\n index === 0\n ? word.toLowerCase()\n : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()\n )\n .join('');\n\n if (!key) key = 'content';\n if (existingKeys.has(key)) {\n let i = 1;\n while (existingKeys.has(`${key}${i}`)) i++;\n key = `${key}${i}`;\n }\n return key;\n};\n\n/**\n * Translation node structure used in multilingual dictionaries\n */\ntype TranslationNode = {\n nodeType: 'translation';\n translation: Record<string, string>;\n};\n\nconst writeContentHelper = async (\n extractedContent: Record<string, string>,\n componentKey: string,\n filePath: string,\n configuration: IntlayerConfig,\n outputDir?: string\n) => {\n const { defaultLocale } = configuration.internationalization;\n const { baseDir, fileExtensions } = configuration.content;\n\n const isPerLocaleFile = configuration?.dictionary?.locale;\n\n const dirName = outputDir ? resolve(outputDir) : dirname(filePath);\n const ext = extname(filePath);\n const baseName = basename(filePath, ext);\n const contentBaseName = baseName.charAt(0).toLowerCase() + baseName.slice(1);\n\n const contentFilePath = join(\n dirName,\n `${contentBaseName}.${fileExtensions[0]}`\n );\n const relativeContentFilePath = relative(baseDir, contentFilePath);\n\n let dictionary: Dictionary;\n\n if (isPerLocaleFile) {\n // Per-locale format: simple string content with locale property\n dictionary = {\n key: componentKey,\n content: extractedContent,\n locale: defaultLocale,\n filePath: relativeContentFilePath,\n };\n } else {\n // Multilingual format: content wrapped in translation nodes, no locale property\n const multilingualContent: Record<string, TranslationNode> = {};\n for (const [key, value] of Object.entries(extractedContent)) {\n multilingualContent[key] = {\n nodeType: 'translation',\n translation: {\n [defaultLocale]: value,\n },\n };\n }\n\n dictionary = {\n key: componentKey,\n content: multilingualContent,\n filePath: relativeContentFilePath,\n };\n }\n\n const relativeDir = relative(baseDir, dirName);\n await writeContentDeclaration(dictionary, configuration, {\n newDictionariesPath: relativeDir,\n });\n\n return contentFilePath;\n};\n\ntype TsReplacement = {\n node: Node;\n key: string;\n type: 'jsx-text' | 'jsx-attribute' | 'string-literal';\n};\n\nconst extractTsContent = (\n sourceFile: SourceFile,\n existingKeys: Set<string>\n): {\n extractedContent: Record<string, string>;\n replacements: TsReplacement[];\n} => {\n const extractedContent: Record<string, string> = {};\n const replacements: TsReplacement[] = [];\n\n sourceFile.forEachDescendant((node) => {\n // 1. JSX Text\n if (Node.isJsxText(node)) {\n const text = node.getText();\n if (shouldExtract(text)) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n extractedContent[key] = text.replace(/\\s+/g, ' ').trim();\n replacements.push({ node, key, type: 'jsx-text' });\n }\n }\n\n // 2. JSX Attributes\n else if (Node.isJsxAttribute(node)) {\n const name = node.getNameNode().getText();\n if (ATTRIBUTES_TO_EXTRACT.includes(name)) {\n const initializer = node.getInitializer();\n if (Node.isStringLiteral(initializer)) {\n const text = initializer.getLiteralValue();\n if (shouldExtract(text)) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n extractedContent[key] = text.trim();\n replacements.push({ node, key, type: 'jsx-attribute' });\n }\n }\n }\n }\n\n // 3. String Literals (Variables, Arrays, etc.)\n else if (Node.isStringLiteral(node)) {\n const text = node.getLiteralValue();\n if (shouldExtract(text)) {\n const parent = node.getParent();\n\n // Skip if inside ImportDeclaration\n if (\n parent?.getKindName() === 'ImportDeclaration' ||\n parent?.getKindName() === 'ImportSpecifier' ||\n parent?.getKindName() === 'ModuleSpecifier'\n ) {\n return;\n }\n\n // Skip if it's a JSX Attribute value (handled above)\n if (Node.isJsxAttribute(parent)) return;\n\n // Skip console.log\n if (Node.isCallExpression(parent)) {\n const expression = parent.getExpression();\n if (expression.getText().includes('console.log')) return;\n }\n\n // Skip Object Keys: { key: \"value\" } -> \"key\" is PropertyAssignment name if not computed\n if (Node.isPropertyAssignment(parent)) {\n if (parent.getNameNode() === node) return; // It's the key\n }\n\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n extractedContent[key] = text.trim();\n replacements.push({ node, key, type: 'string-literal' });\n }\n }\n });\n\n return { extractedContent, replacements };\n};\n\n// ==========================================\n// React (TS-Morph) Strategy\n// ==========================================\n\nconst processTsxFile = async (\n filePath: string,\n componentKey: string,\n packageName: PackageName,\n project: Project,\n save: boolean = true\n) => {\n let sourceFile: SourceFile;\n try {\n sourceFile = project.addSourceFileAtPath(filePath);\n } catch {\n sourceFile = project.getSourceFileOrThrow(filePath);\n }\n\n const isSolid = packageName === 'solid-intlayer';\n\n const existingKeys = new Set<string>();\n const { extractedContent, replacements } = extractTsContent(\n sourceFile,\n existingKeys\n );\n\n if (Object.keys(extractedContent).length === 0) return null;\n\n for (const { node, key, type } of replacements) {\n const contentAccess = isSolid ? `content().${key}` : `content.${key}`;\n\n if (type === 'jsx-text' && Node.isJsxText(node)) {\n node.replaceWithText(`{${contentAccess}}`);\n } else if (type === 'jsx-attribute' && Node.isJsxAttribute(node)) {\n node.setInitializer(`{${contentAccess}.value}`);\n } else if (type === 'string-literal' && Node.isStringLiteral(node)) {\n // For React/JS variables, we usually want the value\n node.replaceWithText(`${contentAccess}.value`);\n }\n }\n\n // Inject hook\n const importDecl = sourceFile.getImportDeclaration(\n (d) => d.getModuleSpecifierValue() === packageName\n );\n if (!importDecl) {\n sourceFile.addImportDeclaration({\n namedImports: ['useIntlayer'],\n moduleSpecifier: packageName,\n });\n } else if (\n !importDecl.getNamedImports().some((n) => n.getName() === 'useIntlayer')\n ) {\n importDecl.addNamedImport('useIntlayer');\n }\n\n // Insert hook at start of component\n sourceFile.getFunctions().forEach((f) => {\n f.getBody()\n ?.asKind(SyntaxKind.Block)\n ?.insertStatements(0, `const content = useIntlayer(\"${componentKey}\");`);\n });\n\n // Also handle const/arrow components\n sourceFile.getVariableDeclarations().forEach((v) => {\n const init = v.getInitializer();\n if (Node.isArrowFunction(init) || Node.isFunctionExpression(init)) {\n const body = init.getBody();\n if (Node.isBlock(body)) {\n // Heuristic: check if it returns JSX or uses hooks\n if (\n body.getText().includes('return') ||\n body.getText().includes('use')\n ) {\n body.insertStatements(\n 0,\n `const content = useIntlayer(\"${componentKey}\");`\n );\n }\n }\n }\n });\n\n if (save) {\n await sourceFile.save();\n }\n return extractedContent;\n};\n\n// ==========================================\n// 5. Main Dispatcher\n// ==========================================\n\nexport type PackageName =\n | 'next-intlayer'\n | 'react-intlayer'\n | 'vue-intlayer'\n | 'svelte-intlayer'\n | 'preact-intlayer'\n | 'solid-intlayer'\n | 'angular-intlayer'\n | 'express-intlayer';\n\nexport type ExtractIntlayerOptions = {\n configOptions?: GetConfigurationOptions;\n outputDir?: string;\n codeOnly?: boolean;\n declarationOnly?: boolean;\n};\n\nexport const extractIntlayer = async (\n filePath: string,\n packageName: PackageName,\n options?: ExtractIntlayerOptions,\n project?: Project\n) => {\n const saveComponent = !options?.declarationOnly;\n const writeContent = !options?.codeOnly;\n\n const configuration = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(configuration);\n const { baseDir } = configuration.content;\n\n // Setup Project for TS/React files if needed\n const _project =\n project || new Project({ skipAddingFilesFromTsConfig: true });\n\n const baseName = extractDictionaryKey(\n filePath,\n (await fs.readFile(filePath)).toString()\n );\n const componentKey = camelCaseToKebabCase(baseName);\n const ext = extname(filePath);\n\n let extractedContent: Record<string, string> | null = null;\n\n if (ext === '.vue') {\n try {\n const { processVueFile } = await import('@intlayer/vue-transformer');\n extractedContent = await processVueFile(\n filePath,\n componentKey,\n packageName,\n {\n generateKey,\n shouldExtract,\n extractTsContent,\n },\n saveComponent\n );\n } catch (error: any) {\n if (\n error.code === 'ERR_MODULE_NOT_FOUND' ||\n error.message?.includes('Cannot find module')\n ) {\n throw new Error(\n `Please install ${colorizePath('@intlayer/vue-transformer', ANSIColors.YELLOW)} to process Vue files.`\n );\n }\n throw error;\n }\n } else if (ext === '.svelte') {\n try {\n const { processSvelteFile } = (await import(\n '@intlayer/svelte-transformer'\n )) as any;\n extractedContent = await processSvelteFile(\n filePath,\n componentKey,\n packageName,\n {\n generateKey,\n shouldExtract,\n extractTsContent,\n },\n saveComponent\n );\n } catch (error: any) {\n if (\n error.code === 'ERR_MODULE_NOT_FOUND' ||\n error.message?.includes('Cannot find module')\n ) {\n throw new Error(\n `Please install ${colorizePath('@intlayer/svelte-transformer', ANSIColors.YELLOW)} to process Svelte files.`\n );\n }\n throw error;\n }\n } else if (['.tsx', '.jsx', '.ts', '.js'].includes(ext)) {\n extractedContent = await processTsxFile(\n filePath,\n componentKey,\n packageName,\n _project,\n saveComponent\n );\n }\n\n if (!extractedContent) {\n appLogger(`No extractable text found in ${baseName}`);\n return;\n }\n\n // Shared Write Logic\n if (writeContent) {\n const contentFilePath = await writeContentHelper(\n extractedContent,\n componentKey,\n filePath,\n configuration,\n options?.outputDir\n );\n\n const relativeContentFilePath = relative(\n configuration.content.baseDir,\n contentFilePath\n );\n appLogger(`Created content file: ${colorizePath(relativeContentFilePath)}`);\n }\n\n // Optional: Format\n if (saveComponent) {\n try {\n const formatCommand = detectFormatCommand(configuration);\n if (formatCommand) {\n execSync(formatCommand.replace('{{file}}', filePath), {\n stdio: 'ignore', // Silent\n cwd: baseDir,\n });\n }\n } catch {\n // Ignore format errors\n }\n\n appLogger(\n `Updated component: ${colorizePath(relative(baseDir, filePath))}`\n );\n }\n};\n\nexport const transformFiles = async (\n filePaths: string[],\n packageName: PackageName,\n options?: ExtractIntlayerOptions\n) => {\n const configuration = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(configuration);\n\n const project = new Project({\n skipAddingFilesFromTsConfig: true,\n });\n\n for (const filePath of filePaths) {\n try {\n await extractIntlayer(filePath, packageName, options, project);\n } catch (error) {\n appLogger(`Failed to transform ${filePath}: ${(error as Error).message}`);\n }\n }\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"transformFiles.mjs","names":[],"sources":["../../../src/transformFiles/transformFiles.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport fs from 'node:fs/promises';\nimport { basename, dirname, extname, join, relative, resolve } from 'node:path';\nimport {\n ANSIColors,\n colorizePath,\n getAppLogger,\n} from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { camelCaseToKebabCase } from '@intlayer/config/utils';\nimport { generateKey } from '@intlayer/core/utils';\nimport type { Dictionary, IntlayerConfig } from '@intlayer/types';\nimport { Node, Project, type SourceFile, SyntaxKind } from 'ts-morph';\nimport { writeContentDeclaration } from '../writeContentDeclaration';\nimport { detectFormatCommand } from '../writeContentDeclaration/detectFormatCommand';\nimport { extractDictionaryKey } from './extractDictionaryKey';\n\n// ==========================================\n// Shared Utilities (exported for reuse in babel plugin)\n// ==========================================\n\n/**\n * Attributes that should be extracted for localization\n */\nexport const ATTRIBUTES_TO_EXTRACT = [\n 'title',\n 'placeholder',\n 'alt',\n 'aria-label',\n 'label',\n];\n\n/**\n * Default function to determine if a string should be extracted for localization\n */\nexport const shouldExtract = (text: string): boolean => {\n const trimmed = text.trim();\n if (!trimmed) return false;\n if (!trimmed.includes(' ')) return false;\n // Starts with Capital letter\n if (!/^[A-Z]/.test(trimmed)) return false;\n // Filter out template logic identifiers (simple check)\n if (trimmed.startsWith('{') || trimmed.startsWith('v-')) return false;\n return true;\n};\n\n/**\n * Translation node structure used in multilingual dictionaries\n */\ntype TranslationNode = {\n nodeType: 'translation';\n translation: Record<string, string>;\n};\n\nconst writeContentHelper = async (\n extractedContent: Record<string, string>,\n componentKey: string,\n filePath: string,\n configuration: IntlayerConfig,\n outputDir?: string\n) => {\n const { defaultLocale } = configuration.internationalization;\n const { baseDir, fileExtensions } = configuration.content;\n\n const isPerLocaleFile = configuration?.dictionary?.locale;\n\n const dirName = outputDir ? resolve(outputDir) : dirname(filePath);\n const ext = extname(filePath);\n const baseName = basename(filePath, ext);\n const contentBaseName = baseName.charAt(0).toLowerCase() + baseName.slice(1);\n\n const contentFilePath = join(\n dirName,\n `${contentBaseName}.${fileExtensions[0]}`\n );\n const relativeContentFilePath = relative(baseDir, contentFilePath);\n\n let dictionary: Dictionary;\n\n if (isPerLocaleFile) {\n // Per-locale format: simple string content with locale property\n dictionary = {\n key: componentKey,\n content: extractedContent,\n locale: defaultLocale,\n filePath: relativeContentFilePath,\n };\n } else {\n // Multilingual format: content wrapped in translation nodes, no locale property\n const multilingualContent: Record<string, TranslationNode> = {};\n for (const [key, value] of Object.entries(extractedContent)) {\n multilingualContent[key] = {\n nodeType: 'translation',\n translation: {\n [defaultLocale]: value,\n },\n };\n }\n\n dictionary = {\n key: componentKey,\n content: multilingualContent,\n filePath: relativeContentFilePath,\n };\n }\n\n const relativeDir = relative(baseDir, dirName);\n await writeContentDeclaration(dictionary, configuration, {\n newDictionariesPath: relativeDir,\n });\n\n return contentFilePath;\n};\n\ntype TsReplacement = {\n node: Node;\n key: string;\n type: 'jsx-text' | 'jsx-attribute' | 'string-literal';\n};\n\nconst extractTsContent = (\n sourceFile: SourceFile,\n existingKeys: Set<string>\n): {\n extractedContent: Record<string, string>;\n replacements: TsReplacement[];\n} => {\n const extractedContent: Record<string, string> = {};\n const replacements: TsReplacement[] = [];\n\n sourceFile.forEachDescendant((node) => {\n // 1. JSX Text\n if (Node.isJsxText(node)) {\n const text = node.getText();\n if (shouldExtract(text)) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n extractedContent[key] = text.replace(/\\s+/g, ' ').trim();\n replacements.push({ node, key, type: 'jsx-text' });\n }\n }\n\n // 2. JSX Attributes\n else if (Node.isJsxAttribute(node)) {\n const name = node.getNameNode().getText();\n if (ATTRIBUTES_TO_EXTRACT.includes(name)) {\n const initializer = node.getInitializer();\n if (Node.isStringLiteral(initializer)) {\n const text = initializer.getLiteralValue();\n if (shouldExtract(text)) {\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n extractedContent[key] = text.trim();\n replacements.push({ node, key, type: 'jsx-attribute' });\n }\n }\n }\n }\n\n // 3. String Literals (Variables, Arrays, etc.)\n else if (Node.isStringLiteral(node)) {\n const text = node.getLiteralValue();\n if (shouldExtract(text)) {\n const parent = node.getParent();\n\n // Skip if inside ImportDeclaration\n if (\n parent?.getKindName() === 'ImportDeclaration' ||\n parent?.getKindName() === 'ImportSpecifier' ||\n parent?.getKindName() === 'ModuleSpecifier'\n ) {\n return;\n }\n\n // Skip if it's a JSX Attribute value (handled above)\n if (Node.isJsxAttribute(parent)) return;\n\n // Skip console.log\n if (Node.isCallExpression(parent)) {\n const expression = parent.getExpression();\n if (expression.getText().includes('console.log')) return;\n }\n\n // Skip Object Keys: { key: \"value\" } -> \"key\" is PropertyAssignment name if not computed\n if (Node.isPropertyAssignment(parent)) {\n if (parent.getNameNode() === node) return; // It's the key\n }\n\n const key = generateKey(text, existingKeys);\n existingKeys.add(key);\n extractedContent[key] = text.trim();\n replacements.push({ node, key, type: 'string-literal' });\n }\n }\n });\n\n return { extractedContent, replacements };\n};\n\n// ==========================================\n// React (TS-Morph) Strategy\n// ==========================================\n\nconst processTsxFile = async (\n filePath: string,\n componentKey: string,\n packageName: PackageName,\n project: Project,\n save: boolean = true\n) => {\n let sourceFile: SourceFile;\n try {\n sourceFile = project.addSourceFileAtPath(filePath);\n } catch {\n sourceFile = project.getSourceFileOrThrow(filePath);\n }\n\n const isSolid = packageName === 'solid-intlayer';\n\n const existingKeys = new Set<string>();\n const { extractedContent, replacements } = extractTsContent(\n sourceFile,\n existingKeys\n );\n\n if (Object.keys(extractedContent).length === 0) return null;\n\n for (const { node, key, type } of replacements) {\n const contentAccess = isSolid ? `content().${key}` : `content.${key}`;\n\n if (type === 'jsx-text' && Node.isJsxText(node)) {\n node.replaceWithText(`{${contentAccess}}`);\n } else if (type === 'jsx-attribute' && Node.isJsxAttribute(node)) {\n node.setInitializer(`{${contentAccess}.value}`);\n } else if (type === 'string-literal' && Node.isStringLiteral(node)) {\n // For React/JS variables, we usually want the value\n node.replaceWithText(`${contentAccess}.value`);\n }\n }\n\n // Inject hook\n const importDecl = sourceFile.getImportDeclaration(\n (d) => d.getModuleSpecifierValue() === packageName\n );\n if (!importDecl) {\n sourceFile.addImportDeclaration({\n namedImports: ['useIntlayer'],\n moduleSpecifier: packageName,\n });\n } else if (\n !importDecl.getNamedImports().some((n) => n.getName() === 'useIntlayer')\n ) {\n importDecl.addNamedImport('useIntlayer');\n }\n\n // Insert hook at start of component\n sourceFile.getFunctions().forEach((f) => {\n f.getBody()\n ?.asKind(SyntaxKind.Block)\n ?.insertStatements(0, `const content = useIntlayer(\"${componentKey}\");`);\n });\n\n // Also handle const/arrow components\n sourceFile.getVariableDeclarations().forEach((v) => {\n const init = v.getInitializer();\n if (Node.isArrowFunction(init) || Node.isFunctionExpression(init)) {\n const body = init.getBody();\n if (Node.isBlock(body)) {\n // Heuristic: check if it returns JSX or uses hooks\n if (\n body.getText().includes('return') ||\n body.getText().includes('use')\n ) {\n body.insertStatements(\n 0,\n `const content = useIntlayer(\"${componentKey}\");`\n );\n }\n }\n }\n });\n\n if (save) {\n await sourceFile.save();\n }\n return extractedContent;\n};\n\n// ==========================================\n// 5. Main Dispatcher\n// ==========================================\n\nexport type PackageName =\n | 'next-intlayer'\n | 'react-intlayer'\n | 'vue-intlayer'\n | 'svelte-intlayer'\n | 'preact-intlayer'\n | 'solid-intlayer'\n | 'angular-intlayer'\n | 'express-intlayer';\n\nexport type ExtractIntlayerOptions = {\n configOptions?: GetConfigurationOptions;\n outputDir?: string;\n codeOnly?: boolean;\n declarationOnly?: boolean;\n};\n\nexport const extractIntlayer = async (\n filePath: string,\n packageName: PackageName,\n options?: ExtractIntlayerOptions,\n project?: Project\n) => {\n const saveComponent = !options?.declarationOnly;\n const writeContent = !options?.codeOnly;\n\n const configuration = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(configuration);\n const { baseDir } = configuration.content;\n\n // Setup Project for TS/React files if needed\n const _project =\n project || new Project({ skipAddingFilesFromTsConfig: true });\n\n const baseName = extractDictionaryKey(\n filePath,\n (await fs.readFile(filePath)).toString()\n );\n const componentKey = camelCaseToKebabCase(baseName);\n const ext = extname(filePath);\n\n let extractedContent: Record<string, string> | null = null;\n\n if (ext === '.vue') {\n try {\n const { processVueFile } = await import('@intlayer/vue-transformer');\n extractedContent = await processVueFile(\n filePath,\n componentKey,\n packageName,\n {\n generateKey,\n shouldExtract,\n extractTsContent,\n },\n saveComponent\n );\n } catch (error: any) {\n if (\n error.code === 'ERR_MODULE_NOT_FOUND' ||\n error.message?.includes('Cannot find module')\n ) {\n throw new Error(\n `Please install ${colorizePath('@intlayer/vue-transformer', ANSIColors.YELLOW)} to process Vue files.`\n );\n }\n throw error;\n }\n } else if (ext === '.svelte') {\n try {\n const { processSvelteFile } = (await import(\n '@intlayer/svelte-transformer'\n )) as any;\n extractedContent = await processSvelteFile(\n filePath,\n componentKey,\n packageName,\n {\n generateKey,\n shouldExtract,\n extractTsContent,\n },\n saveComponent\n );\n } catch (error: any) {\n if (\n error.code === 'ERR_MODULE_NOT_FOUND' ||\n error.message?.includes('Cannot find module')\n ) {\n throw new Error(\n `Please install ${colorizePath('@intlayer/svelte-transformer', ANSIColors.YELLOW)} to process Svelte files.`\n );\n }\n throw error;\n }\n } else if (['.tsx', '.jsx', '.ts', '.js'].includes(ext)) {\n extractedContent = await processTsxFile(\n filePath,\n componentKey,\n packageName,\n _project,\n saveComponent\n );\n }\n\n if (!extractedContent) {\n appLogger(`No extractable text found in ${baseName}`);\n return;\n }\n\n // Shared Write Logic\n if (writeContent) {\n const contentFilePath = await writeContentHelper(\n extractedContent,\n componentKey,\n filePath,\n configuration,\n options?.outputDir\n );\n\n const relativeContentFilePath = relative(\n configuration.content.baseDir,\n contentFilePath\n );\n appLogger(`Created content file: ${colorizePath(relativeContentFilePath)}`);\n }\n\n // Optional: Format\n if (saveComponent) {\n try {\n const formatCommand = detectFormatCommand(configuration);\n if (formatCommand) {\n execSync(formatCommand.replace('{{file}}', filePath), {\n stdio: 'ignore', // Silent\n cwd: baseDir,\n });\n }\n } catch {\n // Ignore format errors\n }\n\n appLogger(\n `Updated component: ${colorizePath(relative(baseDir, filePath))}`\n );\n }\n};\n\nexport const transformFiles = async (\n filePaths: string[],\n packageName: PackageName,\n options?: ExtractIntlayerOptions\n) => {\n const configuration = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(configuration);\n\n const project = new Project({\n skipAddingFilesFromTsConfig: true,\n });\n\n for (const filePath of filePaths) {\n try {\n await extractIntlayer(filePath, packageName, options, project);\n } catch (error) {\n appLogger(`Failed to transform ${filePath}: ${(error as Error).message}`);\n }\n }\n};\n"],"mappings":"8uBA2BA,MAAa,EAAwB,CACnC,QACA,cACA,MACA,aACA,QACD,CAKY,EAAiB,GAA0B,CACtD,IAAM,EAAU,EAAK,MAAM,CAO3B,MADA,EALI,CAAC,GACD,CAAC,EAAQ,SAAS,IAAI,EAEtB,CAAC,SAAS,KAAK,EAAQ,EAEvB,EAAQ,WAAW,IAAI,EAAI,EAAQ,WAAW,KAAK,GAYnD,EAAqB,MACzB,EACA,EACA,EACA,EACA,IACG,CACH,GAAM,CAAE,iBAAkB,EAAc,qBAClC,CAAE,UAAS,kBAAmB,EAAc,QAE5C,EAAkB,GAAe,YAAY,OAE7C,EAAU,EAAY,EAAQ,EAAU,CAAG,EAAQ,EAAS,CAE5D,EAAW,EAAS,EADd,EAAQ,EAAS,CACW,CAGlC,EAAkB,EACtB,EACA,GAJsB,EAAS,OAAO,EAAE,CAAC,aAAa,CAAG,EAAS,MAAM,EAAE,CAIvD,GAAG,EAAe,KACtC,CACK,EAA0B,EAAS,EAAS,EAAgB,CAE9D,EAEJ,GAAI,EAEF,EAAa,CACX,IAAK,EACL,QAAS,EACT,OAAQ,EACR,SAAU,EACX,KACI,CAEL,IAAM,EAAuD,EAAE,CAC/D,IAAK,GAAM,CAAC,EAAK,KAAU,OAAO,QAAQ,EAAiB,CACzD,EAAoB,GAAO,CACzB,SAAU,cACV,YAAa,EACV,GAAgB,EAClB,CACF,CAGH,EAAa,CACX,IAAK,EACL,QAAS,EACT,SAAU,EACX,CAGH,IAAM,EAAc,EAAS,EAAS,EAAQ,CAK9C,OAJA,MAAM,EAAwB,EAAY,EAAe,CACvD,oBAAqB,EACtB,CAAC,CAEK,GASH,GACJ,EACA,IAIG,CACH,IAAM,EAA2C,EAAE,CAC7C,EAAgC,EAAE,CAoExC,OAlEA,EAAW,kBAAmB,GAAS,CAErC,GAAI,EAAK,UAAU,EAAK,CAAE,CACxB,IAAM,EAAO,EAAK,SAAS,CAC3B,GAAI,EAAc,EAAK,CAAE,CACvB,IAAM,EAAM,EAAY,EAAM,EAAa,CAC3C,EAAa,IAAI,EAAI,CACrB,EAAiB,GAAO,EAAK,QAAQ,OAAQ,IAAI,CAAC,MAAM,CACxD,EAAa,KAAK,CAAE,OAAM,MAAK,KAAM,WAAY,CAAC,UAK7C,EAAK,eAAe,EAAK,CAAE,CAClC,IAAM,EAAO,EAAK,aAAa,CAAC,SAAS,CACzC,GAAI,EAAsB,SAAS,EAAK,CAAE,CACxC,IAAM,EAAc,EAAK,gBAAgB,CACzC,GAAI,EAAK,gBAAgB,EAAY,CAAE,CACrC,IAAM,EAAO,EAAY,iBAAiB,CAC1C,GAAI,EAAc,EAAK,CAAE,CACvB,IAAM,EAAM,EAAY,EAAM,EAAa,CAC3C,EAAa,IAAI,EAAI,CACrB,EAAiB,GAAO,EAAK,MAAM,CACnC,EAAa,KAAK,CAAE,OAAM,MAAK,KAAM,gBAAiB,CAAC,YAOtD,EAAK,gBAAgB,EAAK,CAAE,CACnC,IAAM,EAAO,EAAK,iBAAiB,CACnC,GAAI,EAAc,EAAK,CAAE,CACvB,IAAM,EAAS,EAAK,WAAW,CAqB/B,GAjBE,GAAQ,aAAa,GAAK,qBAC1B,GAAQ,aAAa,GAAK,mBAC1B,GAAQ,aAAa,GAAK,mBAMxB,EAAK,eAAe,EAAO,EAG3B,EAAK,iBAAiB,EAAO,EACZ,EAAO,eAAe,CAC1B,SAAS,CAAC,SAAS,cAAc,EAI9C,EAAK,qBAAqB,EAAO,EAC/B,EAAO,aAAa,GAAK,EAAM,OAGrC,IAAM,EAAM,EAAY,EAAM,EAAa,CAC3C,EAAa,IAAI,EAAI,CACrB,EAAiB,GAAO,EAAK,MAAM,CACnC,EAAa,KAAK,CAAE,OAAM,MAAK,KAAM,iBAAkB,CAAC,IAG5D,CAEK,CAAE,mBAAkB,eAAc,EAOrC,EAAiB,MACrB,EACA,EACA,EACA,EACA,EAAgB,KACb,CACH,IAAI,EACJ,GAAI,CACF,EAAa,EAAQ,oBAAoB,EAAS,MAC5C,CACN,EAAa,EAAQ,qBAAqB,EAAS,CAGrD,IAAM,EAAU,IAAgB,iBAG1B,CAAE,mBAAkB,gBAAiB,EACzC,EAFmB,IAAI,IAIxB,CAED,GAAI,OAAO,KAAK,EAAiB,CAAC,SAAW,EAAG,OAAO,KAEvD,IAAK,GAAM,CAAE,OAAM,MAAK,UAAU,EAAc,CAC9C,IAAM,EAAgB,EAAU,aAAa,IAAQ,WAAW,IAE5D,IAAS,YAAc,EAAK,UAAU,EAAK,CAC7C,EAAK,gBAAgB,IAAI,EAAc,GAAG,CACjC,IAAS,iBAAmB,EAAK,eAAe,EAAK,CAC9D,EAAK,eAAe,IAAI,EAAc,SAAS,CACtC,IAAS,kBAAoB,EAAK,gBAAgB,EAAK,EAEhE,EAAK,gBAAgB,GAAG,EAAc,QAAQ,CAKlD,IAAM,EAAa,EAAW,qBAC3B,GAAM,EAAE,yBAAyB,GAAK,EACxC,CA0CD,OAzCK,EAMF,EAAW,iBAAiB,CAAC,KAAM,GAAM,EAAE,SAAS,GAAK,cAAc,EAExE,EAAW,eAAe,cAAc,CAPxC,EAAW,qBAAqB,CAC9B,aAAc,CAAC,cAAc,CAC7B,gBAAiB,EAClB,CAAC,CAQJ,EAAW,cAAc,CAAC,QAAS,GAAM,CACvC,EAAE,SAAS,EACP,OAAO,EAAW,MAAM,EACxB,iBAAiB,EAAG,gCAAgC,EAAa,KAAK,EAC1E,CAGF,EAAW,yBAAyB,CAAC,QAAS,GAAM,CAClD,IAAM,EAAO,EAAE,gBAAgB,CAC/B,GAAI,EAAK,gBAAgB,EAAK,EAAI,EAAK,qBAAqB,EAAK,CAAE,CACjE,IAAM,EAAO,EAAK,SAAS,CACvB,EAAK,QAAQ,EAAK,GAGlB,EAAK,SAAS,CAAC,SAAS,SAAS,EACjC,EAAK,SAAS,CAAC,SAAS,MAAM,GAE9B,EAAK,iBACH,EACA,gCAAgC,EAAa,KAC9C,GAIP,CAEE,GACF,MAAM,EAAW,MAAM,CAElB,GAwBI,EAAkB,MAC7B,EACA,EACA,EACA,IACG,CACH,IAAM,EAAgB,CAAC,GAAS,gBAC1B,EAAe,CAAC,GAAS,SAEzB,EAAgB,EAAiB,GAAS,cAAc,CACxD,EAAY,EAAa,EAAc,CACvC,CAAE,WAAY,EAAc,QAG5B,EACJ,GAAW,IAAI,EAAQ,CAAE,4BAA6B,GAAM,CAAC,CAEzD,EAAW,EACf,GACC,MAAM,EAAG,SAAS,EAAS,EAAE,UAAU,CACzC,CACK,EAAe,EAAqB,EAAS,CAC7C,EAAM,EAAQ,EAAS,CAEzB,EAAkD,KAEtD,GAAI,IAAQ,OACV,GAAI,CACF,GAAM,CAAE,kBAAmB,MAAM,OAAO,6BACxC,EAAmB,MAAM,EACvB,EACA,EACA,EACA,CACE,cACA,gBACA,mBACD,CACD,EACD,OACM,EAAY,CASnB,MAPE,EAAM,OAAS,wBACf,EAAM,SAAS,SAAS,qBAAqB,CAEnC,MACR,kBAAkB,EAAa,4BAA6B,EAAW,OAAO,CAAC,wBAChF,CAEG,UAEC,IAAQ,UACjB,GAAI,CACF,GAAM,CAAE,qBAAuB,MAAM,OACnC,gCAEF,EAAmB,MAAM,EACvB,EACA,EACA,EACA,CACE,cACA,gBACA,mBACD,CACD,EACD,OACM,EAAY,CASnB,MAPE,EAAM,OAAS,wBACf,EAAM,SAAS,SAAS,qBAAqB,CAEnC,MACR,kBAAkB,EAAa,+BAAgC,EAAW,OAAO,CAAC,2BACnF,CAEG,OAEC,CAAC,OAAQ,OAAQ,MAAO,MAAM,CAAC,SAAS,EAAI,GACrD,EAAmB,MAAM,EACvB,EACA,EACA,EACA,EACA,EACD,EAGH,GAAI,CAAC,EAAkB,CACrB,EAAU,gCAAgC,IAAW,CACrD,OAIF,GAAI,EAAc,CAChB,IAAM,EAAkB,MAAM,EAC5B,EACA,EACA,EACA,EACA,GAAS,UACV,CAMD,EAAU,yBAAyB,EAJH,EAC9B,EAAc,QAAQ,QACtB,EACD,CACuE,GAAG,CAI7E,GAAI,EAAe,CACjB,GAAI,CACF,IAAM,EAAgB,EAAoB,EAAc,CACpD,GACF,EAAS,EAAc,QAAQ,WAAY,EAAS,CAAE,CACpD,MAAO,SACP,IAAK,EACN,CAAC,MAEE,EAIR,EACE,sBAAsB,EAAa,EAAS,EAAS,EAAS,CAAC,GAChE,GAIQ,EAAiB,MAC5B,EACA,EACA,IACG,CAEH,IAAM,EAAY,EADI,EAAiB,GAAS,cAAc,CACjB,CAEvC,EAAU,IAAI,EAAQ,CAC1B,4BAA6B,GAC9B,CAAC,CAEF,IAAK,IAAM,KAAY,EACrB,GAAI,CACF,MAAM,EAAgB,EAAU,EAAa,EAAS,EAAQ,OACvD,EAAO,CACd,EAAU,uBAAuB,EAAS,IAAK,EAAgB,UAAU"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{dirname as e,join as t}from"node:path";import{colorizePath as n,x as r}from"@intlayer/config/logger";import{
|
|
1
|
+
import{dirname as e,join as t}from"node:path";import{colorizePath as n,x as r}from"@intlayer/config/logger";import{existsSync as i,mkdirSync as a,writeFileSync as o}from"node:fs";import{deepTransformNode as s}from"@intlayer/core/interpreter";import{NodeType as c}from"@intlayer/types";const l={id:`write-file-plugin`,canHandle:e=>typeof e==`object`&&e?.nodeType===c.File,transform:s=>{let l=s.content,u=s.fixedPath;if(typeof l!=`string`)throw Error(`File content must be a string`);if(typeof u!=`string`)throw Error(`File path must be a string`);try{let n=t(process.cwd(),u),r=e(n);i(r)||a(r,{recursive:!0}),o(n,l)}catch(e){throw Error(`${r} Error writing file to ${n(u)}: ${e}`)}return{nodeType:c.File,[c.File]:s.file}}},u={id:`markdown-file-plugin`,canHandle:e=>typeof e==`object`&&e?.nodeType===c.Markdown,transform:(e,t,n)=>({nodeType:c.Markdown,[c.Markdown]:n(e.markdown,t)})},d={id:`insertion-file-plugin`,canHandle:e=>typeof e==`object`&&e?.nodeType===c.Insertion,transform:(e,t,n)=>({nodeType:c.Insertion,[c.Insertion]:n(e.insertion,t)})},f={id:`html-file-plugin`,canHandle:e=>typeof e==`object`&&e?.nodeType===c.HTML,transform:(e,t,n)=>({nodeType:c.HTML,[c.HTML]:n(e.html,t)})},p=async e=>s(e,{dictionaryKey:e.key,keyPath:[],plugins:[l,u,d,f]});export{p as processContentDeclarationContent};
|
|
2
2
|
//# sourceMappingURL=processContentDeclarationContent.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{getFormatFromExtension as e}from"../utils/getFormatFromExtension.mjs";import{processContentDeclarationContent as t}from"./processContentDeclarationContent.mjs";import{transformJSONFile as n}from"./transformJSONFile.mjs";import{writeJSFile as r}from"./writeJSFile.mjs";import{getUnmergedDictionaries as i}from"@intlayer/unmerged-dictionaries-entry";import{mkdir as a,readFile as o,rename as s,rm as c,writeFile as l}from"node:fs/promises";import{
|
|
1
|
+
import{getFormatFromExtension as e}from"../utils/getFormatFromExtension.mjs";import{processContentDeclarationContent as t}from"./processContentDeclarationContent.mjs";import{transformJSONFile as n}from"./transformJSONFile.mjs";import{writeJSFile as r}from"./writeJSFile.mjs";import{getUnmergedDictionaries as i}from"@intlayer/unmerged-dictionaries-entry";import{mkdir as a,readFile as o,rename as s,rm as c,writeFile as l}from"node:fs/promises";import{basename as u,dirname as d,extname as f,join as p,resolve as m}from"node:path";import{getFilteredLocalesDictionary as h,getPerLocaleDictionary as g}from"@intlayer/core/plugins";import{existsSync as _}from"node:fs";import{isDeepStrictEqual as v}from"node:util";const y=async(n,r,i)=>{let a=await t(n),o=a.content;n.locale?o=g(a,n.locale).content:i&&(o=h(a,i).content);let s={...n,content:o};for await(let e of r.plugins??[])if(e.formatOutput){let t=await e.formatOutput?.({dictionary:s,configuration:r});t&&(s=t)}if(!(s.content&&s.key))return s;let c={key:n.key,id:n.id,title:n.title,description:n.description,tags:n.tags,locale:n.locale,fill:n.fill,filled:n.filled,priority:n.priority,importMode:n.importMode,version:n.version,content:o};return e(n.filePath?f(n.filePath):`.json`)===`json`&&s.content&&s.key&&(c={$schema:`https://intlayer.org/schema.json`,...c}),c},b={newDictionariesPath:`intlayer-dictionaries`},x=async(e,t,n)=>{let{content:r}=t,{baseDir:a}=r,{newDictionariesPath:o,localeList:s}={...b,...n},c=p(a,o),l=i(t)[e.key]?.find(t=>t.localId===e.localId),u=await y(e,t,s);if(l?.filePath){let n=v(l,e),r=m(t.content.baseDir,l.filePath);return n?{status:`up-to-date`,path:r}:(await S(r,u,t),{status:`updated`,path:r})}if(e.filePath){let n=m(t.content.baseDir,e.filePath);return await S(n,u,t),{status:`created`,path:n}}let d=p(c,`${e.key}.content.json`);return await S(d,u,t),{status:`imported`,path:d}},S=async(e,t,i)=>{await a(d(e),{recursive:!0});let m=f(e);if(!i.content.fileExtensions.map(e=>f(e)).includes(m))throw Error(`Invalid file extension: ${m}, file: ${e}`);if(m===`.json`){let n=JSON.stringify(t,null,2),r=i.system?.tempDir;r&&await a(r,{recursive:!0});let o=`${u(e)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`,d=r?p(r,o):`${e}.${o}`;try{await l(d,`${n}\n`),await s(d,e)}catch(e){try{await c(d,{force:!0})}catch{}throw e}return}if([`.jsonc`,`.json5`].includes(m)){let r=`{}`;if(_(e))try{r=await o(e,`utf-8`)}catch{}let d=n(r,t),f=i.system?.tempDir;f&&await a(f,{recursive:!0});let m=`${u(e)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`,h=f?p(f,m):`${e}.${m}`;try{await l(h,d,`utf-8`),await s(h,e)}catch(e){try{await c(h,{force:!0})}catch{}throw e}return}await r(e,t,i);try{await c(p(i.system.cacheDir,`intlayer-prepared.lock`),{recursive:!0})}catch{}};export{x as writeContentDeclaration};
|
|
2
2
|
//# sourceMappingURL=writeContentDeclaration.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeContentDeclaration.mjs","names":[],"sources":["../../../src/writeContentDeclaration/writeContentDeclaration.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { dirname, extname, join, resolve } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport {\n getFilteredLocalesDictionary,\n getPerLocaleDictionary,\n} from '@intlayer/core/plugins';\nimport type {\n Dictionary,\n IntlayerConfig,\n Locale,\n LocalesValues,\n} from '@intlayer/types';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport {\n type Extension,\n getFormatFromExtension,\n} from '../utils/getFormatFromExtension';\nimport type { DictionaryStatus } from './dictionaryStatus';\nimport { processContentDeclarationContent } from './processContentDeclarationContent';\nimport { transformJSONFile } from './transformJSONFile';\nimport { writeJSFile } from './writeJSFile';\n\nconst formatContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n localeList?: LocalesValues[]\n) => {\n /**\n * Clean Markdown, Insertion, File, etc. node metadata\n */\n const processedDictionary =\n await processContentDeclarationContent(dictionary);\n\n let content = processedDictionary.content;\n\n /**\n * Filter locales content\n */\n\n if (dictionary.locale) {\n content = getPerLocaleDictionary(\n processedDictionary,\n dictionary.locale\n ).content;\n } else if (localeList) {\n content = getFilteredLocalesDictionary(\n processedDictionary,\n localeList\n ).content;\n }\n\n let pluginFormatResult: any = {\n ...dictionary,\n content,\n } satisfies Dictionary;\n\n /**\n * Format the dictionary with the plugins\n */\n\n for await (const plugin of configuration.plugins ?? []) {\n if (plugin.formatOutput) {\n const formattedResult = await plugin.formatOutput?.({\n dictionary: pluginFormatResult,\n configuration,\n });\n\n if (formattedResult) {\n pluginFormatResult = formattedResult;\n }\n }\n }\n\n const isDictionaryFormat =\n pluginFormatResult.content && pluginFormatResult.key;\n\n if (!isDictionaryFormat) return pluginFormatResult;\n\n let result: Dictionary = {\n key: dictionary.key,\n id: dictionary.id,\n title: dictionary.title,\n description: dictionary.description,\n tags: dictionary.tags,\n locale: dictionary.locale,\n fill: dictionary.fill,\n filled: dictionary.filled,\n priority: dictionary.priority,\n importMode: dictionary.importMode,\n version: dictionary.version,\n content,\n };\n\n /**\n * Add $schema to JSON dictionaries\n */\n const extension = (\n dictionary.filePath ? extname(dictionary.filePath) : '.json'\n ) as Extension;\n const format = getFormatFromExtension(extension);\n\n if (\n format === 'json' &&\n pluginFormatResult.content &&\n pluginFormatResult.key\n ) {\n result = {\n $schema: 'https://intlayer.org/schema.json',\n ...result,\n };\n }\n\n return result;\n};\n\ntype WriteContentDeclarationOptions = {\n newDictionariesPath?: string;\n localeList?: LocalesValues[];\n fallbackLocale?: Locale;\n};\n\nconst defaultOptions = {\n newDictionariesPath: 'intlayer-dictionaries',\n} satisfies WriteContentDeclarationOptions;\n\nexport const writeContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n options?: WriteContentDeclarationOptions\n): Promise<{ status: DictionaryStatus; path: string }> => {\n const { content } = configuration;\n const { baseDir } = content;\n const { newDictionariesPath, localeList } = {\n ...defaultOptions,\n ...options,\n };\n\n const newDictionaryLocationPath = join(baseDir, newDictionariesPath);\n\n const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);\n const unmergedDictionaries = unmergedDictionariesRecord[\n dictionary.key\n ] as Dictionary[];\n\n const existingDictionary = unmergedDictionaries?.find(\n (el) => el.localId === dictionary.localId\n );\n\n const formattedContentDeclaration = await formatContentDeclaration(\n dictionary,\n configuration,\n localeList\n );\n\n if (existingDictionary?.filePath) {\n // Compare existing dictionary content with new dictionary content\n const isSameContent = isDeepStrictEqual(existingDictionary, dictionary);\n\n const filePath = resolve(\n configuration.content.baseDir,\n existingDictionary.filePath\n );\n\n // Up to date, nothing to do\n if (isSameContent) {\n return {\n status: 'up-to-date',\n path: filePath,\n };\n }\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration\n );\n\n return { status: 'updated', path: filePath };\n }\n\n if (dictionary.filePath) {\n const filePath = resolve(\n configuration.content.baseDir,\n dictionary.filePath\n );\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration\n );\n\n return { status: 'created', path: filePath };\n }\n\n // No existing dictionary, write to new location\n const contentDeclarationPath = join(\n newDictionaryLocationPath,\n `${dictionary.key}.content.json`\n );\n\n await writeFileWithDirectories(\n contentDeclarationPath,\n formattedContentDeclaration,\n configuration\n );\n\n return {\n status: 'imported',\n path: contentDeclarationPath,\n };\n};\n\nconst writeFileWithDirectories = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig\n): Promise<void> => {\n // Extract the directory from the file path\n const dir = dirname(absoluteFilePath);\n\n // Create the directory recursively\n await mkdir(dir, { recursive: true });\n\n const extension = extname(absoluteFilePath);\n const acceptedExtensions = configuration.content.fileExtensions.map(\n (extension) => extname(extension)\n );\n\n if (!acceptedExtensions.includes(extension)) {\n throw new Error(\n `Invalid file extension: ${extension}, file: ${absoluteFilePath}`\n );\n }\n\n if (extension === '.json') {\n const jsonDictionary = JSON.stringify(dictionary, null, 2);\n\n // Write the file\n const tempPath = `${absoluteFilePath}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n await writeFile(tempPath, `${jsonDictionary}\\n`); // Add a new line at the end of the file to avoid formatting issues with VSCode\n await rename(tempPath, absoluteFilePath);\n\n return;\n }\n\n // Handle JSONC, and JSON5 via the AST transformer\n if (['.jsonc', '.json5'].includes(extension)) {\n let fileContent = '{}';\n\n if (existsSync(absoluteFilePath)) {\n try {\n fileContent = await readFile(absoluteFilePath, 'utf-8');\n } catch {\n // ignore read errors, start with empty object\n }\n }\n\n const transformedContent = transformJSONFile(fileContent, dictionary);\n\n // We use standard writeFile because transformedContent is already a string\n const tempPath = `${absoluteFilePath}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n await writeFile(tempPath, transformedContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n return;\n }\n\n await writeJSFile(absoluteFilePath, dictionary, configuration);\n\n // remove the cache as content has changed\n // Will force a new preparation of the intlayer on next build\n try {\n const sentinelPath = join(\n configuration.system.cacheDir,\n 'intlayer-prepared.lock'\n );\n await rm(sentinelPath, { recursive: true });\n } catch {}\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"writeContentDeclaration.mjs","names":[],"sources":["../../../src/writeContentDeclaration/writeContentDeclaration.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, dirname, extname, join, resolve } from 'node:path';\nimport { isDeepStrictEqual } from 'node:util';\nimport {\n getFilteredLocalesDictionary,\n getPerLocaleDictionary,\n} from '@intlayer/core/plugins';\nimport type {\n Dictionary,\n IntlayerConfig,\n Locale,\n LocalesValues,\n} from '@intlayer/types';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport {\n type Extension,\n getFormatFromExtension,\n} from '../utils/getFormatFromExtension';\nimport type { DictionaryStatus } from './dictionaryStatus';\nimport { processContentDeclarationContent } from './processContentDeclarationContent';\nimport { transformJSONFile } from './transformJSONFile';\nimport { writeJSFile } from './writeJSFile';\n\nconst formatContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n localeList?: LocalesValues[]\n) => {\n /**\n * Clean Markdown, Insertion, File, etc. node metadata\n */\n const processedDictionary =\n await processContentDeclarationContent(dictionary);\n\n let content = processedDictionary.content;\n\n /**\n * Filter locales content\n */\n\n if (dictionary.locale) {\n content = getPerLocaleDictionary(\n processedDictionary,\n dictionary.locale\n ).content;\n } else if (localeList) {\n content = getFilteredLocalesDictionary(\n processedDictionary,\n localeList\n ).content;\n }\n\n let pluginFormatResult: any = {\n ...dictionary,\n content,\n } satisfies Dictionary;\n\n /**\n * Format the dictionary with the plugins\n */\n\n for await (const plugin of configuration.plugins ?? []) {\n if (plugin.formatOutput) {\n const formattedResult = await plugin.formatOutput?.({\n dictionary: pluginFormatResult,\n configuration,\n });\n\n if (formattedResult) {\n pluginFormatResult = formattedResult;\n }\n }\n }\n\n const isDictionaryFormat =\n pluginFormatResult.content && pluginFormatResult.key;\n\n if (!isDictionaryFormat) return pluginFormatResult;\n\n let result: Dictionary = {\n key: dictionary.key,\n id: dictionary.id,\n title: dictionary.title,\n description: dictionary.description,\n tags: dictionary.tags,\n locale: dictionary.locale,\n fill: dictionary.fill,\n filled: dictionary.filled,\n priority: dictionary.priority,\n importMode: dictionary.importMode,\n version: dictionary.version,\n content,\n };\n\n /**\n * Add $schema to JSON dictionaries\n */\n const extension = (\n dictionary.filePath ? extname(dictionary.filePath) : '.json'\n ) as Extension;\n const format = getFormatFromExtension(extension);\n\n if (\n format === 'json' &&\n pluginFormatResult.content &&\n pluginFormatResult.key\n ) {\n result = {\n $schema: 'https://intlayer.org/schema.json',\n ...result,\n };\n }\n\n return result;\n};\n\ntype WriteContentDeclarationOptions = {\n newDictionariesPath?: string;\n localeList?: LocalesValues[];\n fallbackLocale?: Locale;\n};\n\nconst defaultOptions = {\n newDictionariesPath: 'intlayer-dictionaries',\n} satisfies WriteContentDeclarationOptions;\n\nexport const writeContentDeclaration = async (\n dictionary: Dictionary,\n configuration: IntlayerConfig,\n options?: WriteContentDeclarationOptions\n): Promise<{ status: DictionaryStatus; path: string }> => {\n const { content } = configuration;\n const { baseDir } = content;\n const { newDictionariesPath, localeList } = {\n ...defaultOptions,\n ...options,\n };\n\n const newDictionaryLocationPath = join(baseDir, newDictionariesPath);\n\n const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);\n const unmergedDictionaries = unmergedDictionariesRecord[\n dictionary.key\n ] as Dictionary[];\n\n const existingDictionary = unmergedDictionaries?.find(\n (el) => el.localId === dictionary.localId\n );\n\n const formattedContentDeclaration = await formatContentDeclaration(\n dictionary,\n configuration,\n localeList\n );\n\n if (existingDictionary?.filePath) {\n // Compare existing dictionary content with new dictionary content\n const isSameContent = isDeepStrictEqual(existingDictionary, dictionary);\n\n const filePath = resolve(\n configuration.content.baseDir,\n existingDictionary.filePath\n );\n\n // Up to date, nothing to do\n if (isSameContent) {\n return {\n status: 'up-to-date',\n path: filePath,\n };\n }\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration\n );\n\n return { status: 'updated', path: filePath };\n }\n\n if (dictionary.filePath) {\n const filePath = resolve(\n configuration.content.baseDir,\n dictionary.filePath\n );\n\n await writeFileWithDirectories(\n filePath,\n formattedContentDeclaration,\n configuration\n );\n\n return { status: 'created', path: filePath };\n }\n\n // No existing dictionary, write to new location\n const contentDeclarationPath = join(\n newDictionaryLocationPath,\n `${dictionary.key}.content.json`\n );\n\n await writeFileWithDirectories(\n contentDeclarationPath,\n formattedContentDeclaration,\n configuration\n );\n\n return {\n status: 'imported',\n path: contentDeclarationPath,\n };\n};\n\nconst writeFileWithDirectories = async (\n absoluteFilePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig\n): Promise<void> => {\n // Extract the directory from the file path\n const dir = dirname(absoluteFilePath);\n\n // Create the directory recursively\n await mkdir(dir, { recursive: true });\n\n const extension = extname(absoluteFilePath);\n const acceptedExtensions = configuration.content.fileExtensions.map(\n (extension) => extname(extension)\n );\n\n if (!acceptedExtensions.includes(extension)) {\n throw new Error(\n `Invalid file extension: ${extension}, file: ${absoluteFilePath}`\n );\n }\n\n if (extension === '.json') {\n const jsonDictionary = JSON.stringify(dictionary, null, 2);\n\n // Write the file\n const tempDir = configuration.system?.tempDir;\n if (tempDir) {\n await mkdir(tempDir, { recursive: true });\n }\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n try {\n await writeFile(tempPath, `${jsonDictionary}\\n`); // Add a new line at the end of the file to avoid formatting issues with VSCode\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // Ignore\n }\n throw error;\n }\n\n return;\n }\n\n // Handle JSONC, and JSON5 via the AST transformer\n if (['.jsonc', '.json5'].includes(extension)) {\n let fileContent = '{}';\n\n if (existsSync(absoluteFilePath)) {\n try {\n fileContent = await readFile(absoluteFilePath, 'utf-8');\n } catch {\n // ignore read errors, start with empty object\n }\n }\n\n const transformedContent = transformJSONFile(fileContent, dictionary);\n\n // We use standard writeFile because transformedContent is already a string\n const tempDir = configuration.system?.tempDir;\n if (tempDir) {\n await mkdir(tempDir, { recursive: true });\n }\n\n const tempFileName = `${basename(absoluteFilePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${absoluteFilePath}.${tempFileName}`;\n try {\n await writeFile(tempPath, transformedContent, 'utf-8');\n await rename(tempPath, absoluteFilePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // Ignore\n }\n throw error;\n }\n return;\n }\n\n await writeJSFile(absoluteFilePath, dictionary, configuration);\n\n // remove the cache as content has changed\n // Will force a new preparation of the intlayer on next build\n try {\n const sentinelPath = join(\n configuration.system.cacheDir,\n 'intlayer-prepared.lock'\n );\n await rm(sentinelPath, { recursive: true });\n } catch {}\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{detectFormatCommand as e}from"./detectFormatCommand.mjs";import{transformJSFile as t}from"./transformJSFile.mjs";import{getFormatFromExtension as n}from"../utils/getFormatFromExtension.mjs";import{getContentDeclarationFileTemplate as r}from"../getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.mjs";import{
|
|
1
|
+
import{detectFormatCommand as e}from"./detectFormatCommand.mjs";import{transformJSFile as t}from"./transformJSFile.mjs";import{getFormatFromExtension as n}from"../utils/getFormatFromExtension.mjs";import{getContentDeclarationFileTemplate as r}from"../getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.mjs";import{mkdir as i,readFile as a,rename as o,rm as s,writeFile as c}from"node:fs/promises";import{basename as l,extname as u,join as d}from"node:path";import{getAppLogger as f,logger as p}from"@intlayer/config/logger";import{existsSync as m}from"node:fs";import{execSync as h}from"node:child_process";const g=async(g,_,v)=>{let y={...v.dictionary,..._},b=f(v);if(!m(g)){let e=n(u(g));b(`File does not exist, creating it`,{isVerbose:!0});let t=await r(y.key,e,Object.fromEntries(Object.entries({id:y.id,locale:y.locale,filled:y.filled,fill:y.fill,description:y.description,title:y.title,tags:y.tags,version:y.version,priority:y.priority,importMode:y.importMode}).filter(([,e])=>e!==void 0))),a=v.system?.tempDir;a&&await i(a,{recursive:!0});let f=`${l(g)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`,p=a?d(a,f):`${g}.${f}`;try{await c(p,t,`utf-8`),await o(p,g)}catch(e){try{await s(p,{force:!0})}catch{}throw e}}let x=await a(g,`utf-8`);if(x===``){let e=n(u(g));x=await r(y.key,e)}let S=await t(x,_),C=v.system?.tempDir;C&&await i(C,{recursive:!0});let w=`${l(g)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`,T=C?d(C,w):`${g}.${w}`;try{await c(T,S,`utf-8`),await o(T,g),p(`Successfully updated ${g}`,{level:`info`,isVerbose:!0})}catch(e){try{await s(T,{force:!0})}catch{}let t=e;throw p(`Failed to write updated file: ${g}`,{level:`error`}),Error(`Failed to write updated file ${g}: ${t.message}`)}let E=e(v);if(E)try{h(E.replace(`{{file}}`,g),{stdio:`inherit`,cwd:v.content.baseDir})}catch(e){console.error(e)}};export{g as writeJSFile};
|
|
2
2
|
//# sourceMappingURL=writeJSFile.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeJSFile.mjs","names":[],"sources":["../../../src/writeContentDeclaration/writeJSFile.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { readFile, rename, writeFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\nimport { getAppLogger, logger } from '@intlayer/config/logger';\nimport type { Dictionary, IntlayerConfig } from '@intlayer/types';\nimport { getContentDeclarationFileTemplate } from '../getContentDeclarationFileTemplate/getContentDeclarationFileTemplate';\nimport {\n type Extension,\n getFormatFromExtension,\n} from '../utils/getFormatFromExtension';\nimport { detectFormatCommand } from './detectFormatCommand';\nimport { transformJSFile } from './transformJSFile';\n\n/**\n * Updates a JavaScript/TypeScript file based on the provided JSON instructions.\n * It targets a specific dictionary object within the file (identified by its 'key' property)\n * and updates its 'content' entries. Currently, it focuses on modifying arguments\n * of 't' (translation) function calls.\n */\nexport const writeJSFile = async (\n filePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig\n): Promise<void> => {\n const mergedDictionary = {\n ...configuration.dictionary,\n ...dictionary,\n };\n\n const appLogger = getAppLogger(configuration);\n\n // Check if the file exist\n if (!existsSync(filePath)) {\n const fileExtension = extname(filePath) as Extension;\n\n const format = getFormatFromExtension(fileExtension);\n\n appLogger('File does not exist, creating it', {\n isVerbose: true,\n });\n const template = await getContentDeclarationFileTemplate(\n mergedDictionary.key,\n format,\n // Filter out undefined values\n Object.fromEntries(\n Object.entries({\n id: mergedDictionary.id,\n locale: mergedDictionary.locale,\n filled: mergedDictionary.filled,\n fill: mergedDictionary.fill,\n description: mergedDictionary.description,\n title: mergedDictionary.title,\n tags: mergedDictionary.tags,\n version: mergedDictionary.version,\n priority: mergedDictionary.priority,\n importMode: mergedDictionary.importMode,\n }).filter(([, value]) => value !== undefined)\n )\n );\n\n const
|
|
1
|
+
{"version":3,"file":"writeJSFile.mjs","names":[],"sources":["../../../src/writeContentDeclaration/writeJSFile.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { existsSync } from 'node:fs';\nimport { mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises';\nimport { basename, extname, join } from 'node:path';\nimport { getAppLogger, logger } from '@intlayer/config/logger';\nimport type { Dictionary, IntlayerConfig } from '@intlayer/types';\nimport { getContentDeclarationFileTemplate } from '../getContentDeclarationFileTemplate/getContentDeclarationFileTemplate';\nimport {\n type Extension,\n getFormatFromExtension,\n} from '../utils/getFormatFromExtension';\nimport { detectFormatCommand } from './detectFormatCommand';\nimport { transformJSFile } from './transformJSFile';\n\n/**\n * Updates a JavaScript/TypeScript file based on the provided JSON instructions.\n * It targets a specific dictionary object within the file (identified by its 'key' property)\n * and updates its 'content' entries. Currently, it focuses on modifying arguments\n * of 't' (translation) function calls.\n */\nexport const writeJSFile = async (\n filePath: string,\n dictionary: Dictionary,\n configuration: IntlayerConfig\n): Promise<void> => {\n const mergedDictionary = {\n ...configuration.dictionary,\n ...dictionary,\n };\n\n const appLogger = getAppLogger(configuration);\n\n // Check if the file exist\n if (!existsSync(filePath)) {\n const fileExtension = extname(filePath) as Extension;\n\n const format = getFormatFromExtension(fileExtension);\n\n appLogger('File does not exist, creating it', {\n isVerbose: true,\n });\n const template = await getContentDeclarationFileTemplate(\n mergedDictionary.key,\n format,\n // Filter out undefined values\n Object.fromEntries(\n Object.entries({\n id: mergedDictionary.id,\n locale: mergedDictionary.locale,\n filled: mergedDictionary.filled,\n fill: mergedDictionary.fill,\n description: mergedDictionary.description,\n title: mergedDictionary.title,\n tags: mergedDictionary.tags,\n version: mergedDictionary.version,\n priority: mergedDictionary.priority,\n importMode: mergedDictionary.importMode,\n }).filter(([, value]) => value !== undefined)\n )\n );\n\n const tempDir = configuration.system?.tempDir;\n if (tempDir) {\n await mkdir(tempDir, { recursive: true });\n }\n\n const tempFileName = `${basename(filePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${filePath}.${tempFileName}`;\n try {\n await writeFile(tempPath, template, 'utf-8');\n await rename(tempPath, filePath);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // Ignore\n }\n throw error;\n }\n }\n\n let fileContent = await readFile(filePath, 'utf-8');\n\n if (fileContent === '') {\n const format = getFormatFromExtension(extname(filePath) as Extension);\n\n fileContent = await getContentDeclarationFileTemplate(\n mergedDictionary.key,\n format\n );\n }\n\n const finalCode = await transformJSFile(fileContent, dictionary);\n\n // Write the modified code back to the file\n const tempDir = configuration.system?.tempDir;\n if (tempDir) {\n await mkdir(tempDir, { recursive: true });\n }\n\n const tempFileName = `${basename(filePath)}.${Date.now()}-${Math.random().toString(36).slice(2)}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${filePath}.${tempFileName}`;\n try {\n await writeFile(tempPath, finalCode, 'utf-8');\n await rename(tempPath, filePath);\n logger(`Successfully updated ${filePath}`, {\n level: 'info',\n isVerbose: true,\n });\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {\n // Ignore\n }\n const err = error as Error;\n logger(`Failed to write updated file: ${filePath}`, {\n level: 'error',\n });\n throw new Error(`Failed to write updated file ${filePath}: ${err.message}`);\n }\n\n const formatCommand = detectFormatCommand(configuration);\n\n if (formatCommand) {\n try {\n execSync(formatCommand.replace('{{file}}', filePath), {\n stdio: 'inherit',\n cwd: configuration.content.baseDir,\n });\n } catch (error) {\n console.error(error);\n }\n }\n};\n"],"mappings":"gnBAoBA,MAAa,EAAc,MACzB,EACA,EACA,IACkB,CAClB,IAAM,EAAmB,CACvB,GAAG,EAAc,WACjB,GAAG,EACJ,CAEK,EAAY,EAAa,EAAc,CAG7C,GAAI,CAAC,EAAW,EAAS,CAAE,CAGzB,IAAM,EAAS,EAFO,EAAQ,EAAS,CAEa,CAEpD,EAAU,mCAAoC,CAC5C,UAAW,GACZ,CAAC,CACF,IAAM,EAAW,MAAM,EACrB,EAAiB,IACjB,EAEA,OAAO,YACL,OAAO,QAAQ,CACb,GAAI,EAAiB,GACrB,OAAQ,EAAiB,OACzB,OAAQ,EAAiB,OACzB,KAAM,EAAiB,KACvB,YAAa,EAAiB,YAC9B,MAAO,EAAiB,MACxB,KAAM,EAAiB,KACvB,QAAS,EAAiB,QAC1B,SAAU,EAAiB,SAC3B,WAAY,EAAiB,WAC9B,CAAC,CAAC,QAAQ,EAAG,KAAW,IAAU,IAAA,GAAU,CAC9C,CACF,CAEK,EAAU,EAAc,QAAQ,QAClC,GACF,MAAM,EAAM,EAAS,CAAE,UAAW,GAAM,CAAC,CAG3C,IAAM,EAAe,GAAG,EAAS,EAAS,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CAAC,MAC1F,EAAW,EACb,EAAK,EAAS,EAAa,CAC3B,GAAG,EAAS,GAAG,IACnB,GAAI,CACF,MAAM,EAAU,EAAU,EAAU,QAAQ,CAC5C,MAAM,EAAO,EAAU,EAAS,OACzB,EAAO,CACd,GAAI,CACF,MAAM,EAAG,EAAU,CAAE,MAAO,GAAM,CAAC,MAC7B,EAGR,MAAM,GAIV,IAAI,EAAc,MAAM,EAAS,EAAU,QAAQ,CAEnD,GAAI,IAAgB,GAAI,CACtB,IAAM,EAAS,EAAuB,EAAQ,EAAS,CAAc,CAErE,EAAc,MAAM,EAClB,EAAiB,IACjB,EACD,CAGH,IAAM,EAAY,MAAM,EAAgB,EAAa,EAAW,CAG1D,EAAU,EAAc,QAAQ,QAClC,GACF,MAAM,EAAM,EAAS,CAAE,UAAW,GAAM,CAAC,CAG3C,IAAM,EAAe,GAAG,EAAS,EAAS,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CAAC,MAC1F,EAAW,EACb,EAAK,EAAS,EAAa,CAC3B,GAAG,EAAS,GAAG,IACnB,GAAI,CACF,MAAM,EAAU,EAAU,EAAW,QAAQ,CAC7C,MAAM,EAAO,EAAU,EAAS,CAChC,EAAO,wBAAwB,IAAY,CACzC,MAAO,OACP,UAAW,GACZ,CAAC,OACK,EAAO,CACd,GAAI,CACF,MAAM,EAAG,EAAU,CAAE,MAAO,GAAM,CAAC,MAC7B,EAGR,IAAM,EAAM,EAIZ,MAHA,EAAO,iCAAiC,IAAY,CAClD,MAAO,QACR,CAAC,CACQ,MAAM,gCAAgC,EAAS,IAAI,EAAI,UAAU,CAG7E,IAAM,EAAgB,EAAoB,EAAc,CAExD,GAAI,EACF,GAAI,CACF,EAAS,EAAc,QAAQ,WAAY,EAAS,CAAE,CACpD,MAAO,UACP,IAAK,EAAc,QAAQ,QAC5B,CAAC,OACK,EAAO,CACd,QAAQ,MAAM,EAAM"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{writeFile as
|
|
1
|
+
import{chmod as e,mkdir as t,rename as n,rm as r,stat as i,writeFile as a}from"node:fs/promises";import{basename as o,join as s}from"node:path";import{createHash as c,randomBytes as l}from"node:crypto";import{createReadStream as u,rmSync as d}from"node:fs";const f=new Set;process.on(`exit`,()=>{for(let e of f)try{d(e,{force:!0})}catch{}});const p=e=>new Promise(t=>{let n=c(`sha256`),r=u(e);r.on(`data`,e=>n.update(e)),r.on(`end`,()=>t(n.digest(`hex`))),r.on(`error`,()=>t(null))}),m=async(u,d,{encoding:m=`utf8`,tempDir:h}={})=>{if(c(`sha256`).update(d,m).digest(`hex`)===await p(u))return!1;h&&await t(h,{recursive:!0});let g=`${o(u)}.${Date.now()}-${l(4).toString(`hex`)}.tmp`,_=h?s(h,g):`${u}.${g}`;f.add(_);try{let t;try{t=(await i(u)).mode}catch{}await a(_,d,{encoding:m}),t!==void 0&&await e(_,t),await n(_,u)}catch(e){try{await r(_,{force:!0})}catch{}throw e}finally{f.delete(_)}return!0};export{m as writeFileIfChanged};
|
|
2
2
|
//# sourceMappingURL=writeFileIfChanged.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeFileIfChanged.mjs","names":[],"sources":["../../src/writeFileIfChanged.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"writeFileIfChanged.mjs","names":[],"sources":["../../src/writeFileIfChanged.ts"],"sourcesContent":["import { createHash, randomBytes } from 'node:crypto';\nimport { createReadStream, rmSync } from 'node:fs';\nimport { chmod, mkdir, rename, rm, stat, writeFile } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\n\nconst activeTempFiles = new Set<string>();\n\n// Synchronous cleanup on process exit\nprocess.on('exit', () => {\n for (const file of activeTempFiles) {\n try {\n rmSync(file, { force: true });\n } catch {}\n }\n});\n\n// Helper to hash existing file via stream\nconst getFileHash = (path: string): Promise<string | null> => {\n return new Promise((resolve) => {\n const hash = createHash('sha256');\n const stream = createReadStream(path);\n stream.on('data', (chunk) => hash.update(chunk));\n stream.on('end', () => resolve(hash.digest('hex')));\n stream.on('error', () => resolve(null));\n });\n};\n\nexport const writeFileIfChanged = async (\n path: string,\n data: string,\n {\n encoding = 'utf8',\n tempDir,\n }: { encoding?: BufferEncoding; tempDir?: string } = {}\n): Promise<boolean> => {\n const newDataHash = createHash('sha256').update(data, encoding).digest('hex');\n const existingHash = await getFileHash(path);\n\n if (newDataHash === existingHash) {\n return false;\n }\n\n if (tempDir) {\n await mkdir(tempDir, { recursive: true });\n }\n\n const tempFileName = `${basename(path)}.${Date.now()}-${randomBytes(4).toString('hex')}.tmp`;\n const tempPath = tempDir\n ? join(tempDir, tempFileName)\n : `${path}.${tempFileName}`;\n activeTempFiles.add(tempPath);\n\n try {\n let mode: number | undefined;\n try {\n mode = (await stat(path)).mode;\n } catch {}\n\n await writeFile(tempPath, data, { encoding });\n\n if (mode !== undefined) {\n await chmod(tempPath, mode);\n }\n\n await rename(tempPath, path);\n } catch (error) {\n try {\n await rm(tempPath, { force: true });\n } catch {}\n throw error;\n } finally {\n activeTempFiles.delete(tempPath);\n }\n\n return true;\n};\n"],"mappings":"iQAKA,MAAM,EAAkB,IAAI,IAG5B,QAAQ,GAAG,WAAc,CACvB,IAAK,IAAM,KAAQ,EACjB,GAAI,CACF,EAAO,EAAM,CAAE,MAAO,GAAM,CAAC,MACvB,IAEV,CAGF,MAAM,EAAe,GACZ,IAAI,QAAS,GAAY,CAC9B,IAAM,EAAO,EAAW,SAAS,CAC3B,EAAS,EAAiB,EAAK,CACrC,EAAO,GAAG,OAAS,GAAU,EAAK,OAAO,EAAM,CAAC,CAChD,EAAO,GAAG,UAAa,EAAQ,EAAK,OAAO,MAAM,CAAC,CAAC,CACnD,EAAO,GAAG,YAAe,EAAQ,KAAK,CAAC,EACvC,CAGS,EAAqB,MAChC,EACA,EACA,CACE,WAAW,OACX,WACmD,EAAE,GAClC,CAIrB,GAHoB,EAAW,SAAS,CAAC,OAAO,EAAM,EAAS,CAAC,OAAO,MAAM,GACxD,MAAM,EAAY,EAAK,CAG1C,MAAO,GAGL,GACF,MAAM,EAAM,EAAS,CAAE,UAAW,GAAM,CAAC,CAG3C,IAAM,EAAe,GAAG,EAAS,EAAK,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,EAAY,EAAE,CAAC,SAAS,MAAM,CAAC,MACjF,EAAW,EACb,EAAK,EAAS,EAAa,CAC3B,GAAG,EAAK,GAAG,IACf,EAAgB,IAAI,EAAS,CAE7B,GAAI,CACF,IAAI,EACJ,GAAI,CACF,GAAQ,MAAM,EAAK,EAAK,EAAE,UACpB,EAER,MAAM,EAAU,EAAU,EAAM,CAAE,WAAU,CAAC,CAEzC,IAAS,IAAA,IACX,MAAM,EAAM,EAAU,EAAK,CAG7B,MAAM,EAAO,EAAU,EAAK,OACrB,EAAO,CACd,GAAI,CACF,MAAM,EAAG,EAAU,CAAE,MAAO,GAAM,CAAC,MAC7B,EACR,MAAM,SACE,CACR,EAAgB,OAAO,EAAS,CAGlC,MAAO"}
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { getContentDeclarationFileTemplate } from "./getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.js";
|
|
1
2
|
import { initIntlayer } from "./init/index.js";
|
|
2
3
|
import { Platform, SKILLS, SKILLS_METADATA, Skill, installSkills } from "./installSkills/index.js";
|
|
4
|
+
import { listDictionaries, listDictionariesWithStats } from "./listDictionariesPath.js";
|
|
3
5
|
import { DiffMode, ListGitFilesOptions, ListGitLinesOptions, listGitFiles, listGitLines } from "./listGitFiles.js";
|
|
4
6
|
import { ListProjectsOptions, listProjects } from "./listProjects.js";
|
|
5
7
|
import { extractDictionaryKey } from "./transformFiles/extractDictionaryKey.js";
|
|
6
|
-
import { ATTRIBUTES_TO_EXTRACT, ExtractIntlayerOptions, PackageName, extractIntlayer,
|
|
8
|
+
import { ATTRIBUTES_TO_EXTRACT, ExtractIntlayerOptions, PackageName, extractIntlayer, shouldExtract, transformFiles } from "./transformFiles/transformFiles.js";
|
|
7
9
|
import "./transformFiles/index.js";
|
|
8
|
-
export { ATTRIBUTES_TO_EXTRACT, DiffMode, ExtractIntlayerOptions, ListGitFilesOptions, ListGitLinesOptions, ListProjectsOptions, PackageName, Platform, SKILLS, SKILLS_METADATA, Skill, extractDictionaryKey, extractIntlayer,
|
|
10
|
+
export { ATTRIBUTES_TO_EXTRACT, DiffMode, ExtractIntlayerOptions, ListGitFilesOptions, ListGitLinesOptions, ListProjectsOptions, PackageName, Platform, SKILLS, SKILLS_METADATA, Skill, extractDictionaryKey, extractIntlayer, getContentDeclarationFileTemplate, initIntlayer, installSkills, listDictionaries, listDictionariesWithStats, listGitFiles, listGitLines, listProjects, shouldExtract, transformFiles };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -24,14 +24,16 @@ import { transformJSFile } from "./writeContentDeclaration/transformJSFile.js";
|
|
|
24
24
|
import { writeContentDeclaration } from "./writeContentDeclaration/writeContentDeclaration.js";
|
|
25
25
|
import { writeJSFile } from "./writeContentDeclaration/writeJSFile.js";
|
|
26
26
|
import "./build.js";
|
|
27
|
+
import { Extension, Format, getExtensionFromFormat, getFormatFromExtension } from "./utils/getFormatFromExtension.js";
|
|
28
|
+
import { getContentDeclarationFileTemplate } from "./getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.js";
|
|
27
29
|
import { initIntlayer } from "./init/index.js";
|
|
28
30
|
import { Platform, SKILLS, SKILLS_METADATA, Skill, installSkills } from "./installSkills/index.js";
|
|
31
|
+
import { listDictionaries, listDictionariesWithStats } from "./listDictionariesPath.js";
|
|
29
32
|
import { DiffMode, ListGitFilesOptions, ListGitLinesOptions, listGitFiles, listGitLines } from "./listGitFiles.js";
|
|
30
33
|
import { ListProjectsOptions, listProjects } from "./listProjects.js";
|
|
31
34
|
import { extractDictionaryKey } from "./transformFiles/extractDictionaryKey.js";
|
|
32
|
-
import { ATTRIBUTES_TO_EXTRACT, ExtractIntlayerOptions, PackageName, extractIntlayer,
|
|
35
|
+
import { ATTRIBUTES_TO_EXTRACT, ExtractIntlayerOptions, PackageName, extractIntlayer, shouldExtract, transformFiles } from "./transformFiles/transformFiles.js";
|
|
33
36
|
import "./cli.js";
|
|
34
|
-
import { Extension, Format, getExtensionFromFormat, getFormatFromExtension } from "./utils/getFormatFromExtension.js";
|
|
35
37
|
import { autoDecorateContent } from "./utils/autoDecorateContent.js";
|
|
36
38
|
import { BuildFilesListOptions, buildFilesList } from "./utils/buildFilesList.js";
|
|
37
39
|
import { JSONObject, JsonChunk, assembleJSON, chunkJSON, reconstructFromSingleChunk } from "./utils/chunkJSON.js";
|
|
@@ -52,4 +54,4 @@ import { splitTextByLines } from "./utils/splitTextByLine.js";
|
|
|
52
54
|
import { verifyIdenticObjectFormat } from "./utils/verifyIdenticObjectFormat.js";
|
|
53
55
|
import "./utils/index.js";
|
|
54
56
|
import { buildAndWatchIntlayer, watch } from "./watcher.js";
|
|
55
|
-
export { ATTRIBUTES_TO_EXTRACT, BuildFilesListOptions, CreateDictionaryEntryPointOptions, DictionariesStatus, DictionaryStatus, DiffMode, Extension, ExtractIntlayerOptions, Format, JSONObject, JsonChunk, ListGitFilesOptions, ListGitLinesOptions, ListProjectsOptions, PackageName, ParallelHandle, Platform, Queue, SKILLS, SKILLS_METADATA, Skill, assembleJSON, autoDecorateContent, buildAndWatchIntlayer, buildDictionary, buildFilesList, chunkJSON, cleanOutputDir, createDictionaryEntryPoint, createModuleAugmentation, createTypes, detectExportedComponentName, detectFormatCommand, extractDictionaryKey, extractIntlayer, formatDictionaries, formatDictionariesOutput, formatDictionary, formatDictionaryOutput, formatDistantDictionaries, formatLocalDictionaries, formatLocale, formatPath, generateDictionaryListContent,
|
|
57
|
+
export { ATTRIBUTES_TO_EXTRACT, BuildFilesListOptions, CreateDictionaryEntryPointOptions, DictionariesStatus, DictionaryStatus, DiffMode, Extension, ExtractIntlayerOptions, Format, JSONObject, JsonChunk, ListGitFilesOptions, ListGitLinesOptions, ListProjectsOptions, PackageName, ParallelHandle, Platform, Queue, SKILLS, SKILLS_METADATA, Skill, assembleJSON, autoDecorateContent, buildAndWatchIntlayer, buildDictionary, buildFilesList, chunkJSON, cleanOutputDir, createDictionaryEntryPoint, createModuleAugmentation, createTypes, detectExportedComponentName, detectFormatCommand, extractDictionaryKey, extractIntlayer, formatDictionaries, formatDictionariesOutput, formatDictionary, formatDictionaryOutput, formatDistantDictionaries, formatLocalDictionaries, formatLocale, formatPath, generateDictionaryListContent, generateTypeScriptType, getBuiltDictionariesPath, getBuiltDynamicDictionariesPath, getBuiltFetchDictionariesPath, getBuiltRemoteDictionariesPath, getBuiltUnmergedDictionariesPath, getChunk, getComponentTransformPattern, getComponentTransformPatternSync, getContentDeclarationFileTemplate, getExtensionFromFormat, getFileHash, getFormatFromExtension, getGlobalLimiter, getTaskLimiter, getTypeName, initIntlayer, installSkills, isCachedConfigurationUpToDate, listDictionaries, listDictionariesWithStats, listGitFiles, listGitLines, listProjects, loadContentDeclarations, loadDictionaries, loadLocalDictionaries, loadRemoteDictionaries, mergeChunks, pLimit, parallelize, parallelizeGlobal, prepareIntlayer, processContentDeclaration, reconstructFromSingleChunk, reduceObjectFormat, resolveObjectPromises, runOnce, runParallel, shouldExtract, sortAlphabetically, splitTextByLines, transformFiles, transformJSFile, verifyIdenticObjectFormat, watch, writeConfiguration, writeContentDeclaration, writeJSFile };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadContentDeclaration.d.ts","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"loadContentDeclaration.d.ts","names":[],"sources":["../../../src/loadDictionaries/loadContentDeclaration.ts"],"mappings":";;;;cAYa,uBAAA,GACX,kBAAA,EAAoB,MAAA,SAAe,UAAA,GACnC,aAAA,EAAe,cAAA,KACd,UAAA;AAAA,cAQU,uBAAA,GACX,0BAAA,YACA,aAAA,EAAe,cAAA,EACf,cAAA,IAAkB,MAAA,EAAQ,kBAAA,gBACzB,OAAA,CAAQ,UAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { IntlayerConfig } from "@intlayer/types";
|
|
2
|
+
|
|
3
|
+
//#region src/loadDictionaries/logTypeScriptErrors.d.ts
|
|
4
|
+
declare const logTypeScriptErrors: (filePaths: string[], configuration: IntlayerConfig) => Promise<void>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { logTypeScriptErrors };
|
|
7
|
+
//# sourceMappingURL=logTypeScriptErrors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logTypeScriptErrors.d.ts","names":[],"sources":["../../../src/loadDictionaries/logTypeScriptErrors.ts"],"mappings":";;;cAMa,mBAAA,GACX,SAAA,YAEA,aAAA,EAAe,cAAA,KAAc,OAAA"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { extractDictionaryKey } from "./extractDictionaryKey.js";
|
|
2
|
-
import { ATTRIBUTES_TO_EXTRACT, ExtractIntlayerOptions, PackageName, extractIntlayer,
|
|
3
|
-
export { ATTRIBUTES_TO_EXTRACT, ExtractIntlayerOptions, PackageName, extractDictionaryKey, extractIntlayer,
|
|
2
|
+
import { ATTRIBUTES_TO_EXTRACT, ExtractIntlayerOptions, PackageName, extractIntlayer, shouldExtract, transformFiles } from "./transformFiles.js";
|
|
3
|
+
export { ATTRIBUTES_TO_EXTRACT, ExtractIntlayerOptions, PackageName, extractDictionaryKey, extractIntlayer, shouldExtract, transformFiles };
|
|
@@ -10,10 +10,6 @@ declare const ATTRIBUTES_TO_EXTRACT: string[];
|
|
|
10
10
|
* Default function to determine if a string should be extracted for localization
|
|
11
11
|
*/
|
|
12
12
|
declare const shouldExtract: (text: string) => boolean;
|
|
13
|
-
/**
|
|
14
|
-
* Generate a unique key from text for use as a dictionary key
|
|
15
|
-
*/
|
|
16
|
-
declare const generateKey: (text: string, existingKeys: Set<string>) => string;
|
|
17
13
|
type PackageName = 'next-intlayer' | 'react-intlayer' | 'vue-intlayer' | 'svelte-intlayer' | 'preact-intlayer' | 'solid-intlayer' | 'angular-intlayer' | 'express-intlayer';
|
|
18
14
|
type ExtractIntlayerOptions = {
|
|
19
15
|
configOptions?: GetConfigurationOptions;
|
|
@@ -24,5 +20,5 @@ type ExtractIntlayerOptions = {
|
|
|
24
20
|
declare const extractIntlayer: (filePath: string, packageName: PackageName, options?: ExtractIntlayerOptions, project?: Project) => Promise<void>;
|
|
25
21
|
declare const transformFiles: (filePaths: string[], packageName: PackageName, options?: ExtractIntlayerOptions) => Promise<void>;
|
|
26
22
|
//#endregion
|
|
27
|
-
export { ATTRIBUTES_TO_EXTRACT, ExtractIntlayerOptions, PackageName, extractIntlayer,
|
|
23
|
+
export { ATTRIBUTES_TO_EXTRACT, ExtractIntlayerOptions, PackageName, extractIntlayer, shouldExtract, transformFiles };
|
|
28
24
|
//# sourceMappingURL=transformFiles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformFiles.d.ts","names":[],"sources":["../../../src/transformFiles/transformFiles.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"transformFiles.d.ts","names":[],"sources":["../../../src/transformFiles/transformFiles.ts"],"mappings":";;;;;;AA2BA;cAAa,qBAAA;;;;cAWA,aAAA,GAAiB,IAAA;AAAA,KAiQlB,WAAA;AAAA,KAUA,sBAAA;EACV,aAAA,GAAgB,uBAAA;EAChB,SAAA;EACA,QAAA;EACA,eAAA;AAAA;AAAA,cAGW,eAAA,GACX,QAAA,UACA,WAAA,EAAa,WAAA,EACb,OAAA,GAAU,sBAAA,EACV,OAAA,GAAU,OAAA,KAAO,OAAA;AAAA,cA8HN,cAAA,GACX,SAAA,YACA,WAAA,EAAa,WAAA,EACb,OAAA,GAAU,sBAAA,KAAsB,OAAA"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
//#region src/writeFileIfChanged.d.ts
|
|
2
|
-
declare const writeFileIfChanged: (path: string,
|
|
3
|
-
encoding
|
|
2
|
+
declare const writeFileIfChanged: (path: string, data: string, {
|
|
3
|
+
encoding,
|
|
4
|
+
tempDir
|
|
4
5
|
}?: {
|
|
5
6
|
encoding?: BufferEncoding;
|
|
7
|
+
tempDir?: string;
|
|
6
8
|
}) => Promise<boolean>;
|
|
7
9
|
//#endregion
|
|
8
10
|
export { writeFileIfChanged };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writeFileIfChanged.d.ts","names":[],"sources":["../../src/writeFileIfChanged.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"writeFileIfChanged.d.ts","names":[],"sources":["../../src/writeFileIfChanged.ts"],"mappings":";cA2Ba,kBAAA,GACX,IAAA,UACA,IAAA;EACA,QAAA;EAAA;AAAA;EAGK,QAAA,GAAW,cAAA;EAAgB,OAAA;AAAA,MAC/B,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intlayer/chokidar",
|
|
3
|
-
"version": "8.1.
|
|
3
|
+
"version": "8.1.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Uses chokidar to scan and build Intlayer declaration files into dictionaries based on Intlayer configuration.",
|
|
6
6
|
"keywords": [
|
|
@@ -102,13 +102,13 @@
|
|
|
102
102
|
"typecheck": "tsc --noEmit --project tsconfig.types.json"
|
|
103
103
|
},
|
|
104
104
|
"dependencies": {
|
|
105
|
-
"@intlayer/api": "8.1.
|
|
106
|
-
"@intlayer/config": "8.1.
|
|
107
|
-
"@intlayer/core": "8.1.
|
|
108
|
-
"@intlayer/dictionaries-entry": "8.1.
|
|
109
|
-
"@intlayer/remote-dictionaries-entry": "8.1.
|
|
110
|
-
"@intlayer/types": "8.1.
|
|
111
|
-
"@intlayer/unmerged-dictionaries-entry": "8.1.
|
|
105
|
+
"@intlayer/api": "8.1.6",
|
|
106
|
+
"@intlayer/config": "8.1.6",
|
|
107
|
+
"@intlayer/core": "8.1.6",
|
|
108
|
+
"@intlayer/dictionaries-entry": "8.1.6",
|
|
109
|
+
"@intlayer/remote-dictionaries-entry": "8.1.6",
|
|
110
|
+
"@intlayer/types": "8.1.6",
|
|
111
|
+
"@intlayer/unmerged-dictionaries-entry": "8.1.6",
|
|
112
112
|
"chokidar": "3.6.0",
|
|
113
113
|
"crypto-js": "4.2.0",
|
|
114
114
|
"defu": "6.1.4",
|
|
@@ -130,8 +130,8 @@
|
|
|
130
130
|
"zod": "4.3.6"
|
|
131
131
|
},
|
|
132
132
|
"peerDependencies": {
|
|
133
|
-
"@intlayer/svelte-transformer": "8.1.
|
|
134
|
-
"@intlayer/vue-transformer": "8.1.
|
|
133
|
+
"@intlayer/svelte-transformer": "8.1.6",
|
|
134
|
+
"@intlayer/vue-transformer": "8.1.6"
|
|
135
135
|
},
|
|
136
136
|
"peerDependenciesMeta": {
|
|
137
137
|
"@intlayer/svelte-transformer": {
|