@intlayer/engine 9.0.0-canary.17 → 9.0.0-canary.18
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/_virtual/_utils_asset.cjs +4 -3
- package/dist/cjs/buildIntlayerDictionary/buildIntlayerDictionary.cjs +0 -1
- package/dist/cjs/buildIntlayerDictionary/buildIntlayerDictionary.cjs.map +1 -1
- package/dist/cjs/buildIntlayerDictionary/processContentDeclaration.cjs +0 -1
- package/dist/cjs/buildIntlayerDictionary/processContentDeclaration.cjs.map +1 -1
- package/dist/cjs/buildIntlayerDictionary/writeDynamicDictionary.cjs +0 -1
- package/dist/cjs/buildIntlayerDictionary/writeDynamicDictionary.cjs.map +1 -1
- package/dist/cjs/buildIntlayerDictionary/writeFetchDictionary.cjs +0 -1
- package/dist/cjs/buildIntlayerDictionary/writeFetchDictionary.cjs.map +1 -1
- package/dist/cjs/buildIntlayerDictionary/writeMergedDictionary.cjs +2 -2
- package/dist/cjs/buildIntlayerDictionary/writeMergedDictionary.cjs.map +1 -1
- package/dist/cjs/buildIntlayerDictionary/writeRemoteDictionary.cjs +2 -2
- package/dist/cjs/buildIntlayerDictionary/writeRemoteDictionary.cjs.map +1 -1
- package/dist/cjs/buildIntlayerDictionary/writeUnmergedDictionary.cjs +4 -3
- package/dist/cjs/buildIntlayerDictionary/writeUnmergedDictionary.cjs.map +1 -1
- package/dist/cjs/cleanOutputDir.cjs +0 -1
- package/dist/cjs/cleanOutputDir.cjs.map +1 -1
- package/dist/cjs/cleanRemovedContentDeclaration.cjs.map +1 -1
- package/dist/cjs/createDictionaryEntryPoint/createDictionaryEntryPoint.cjs +0 -1
- package/dist/cjs/createDictionaryEntryPoint/createDictionaryEntryPoint.cjs.map +1 -1
- package/dist/cjs/createDictionaryEntryPoint/generateDictionaryListContent.cjs +0 -1
- package/dist/cjs/createDictionaryEntryPoint/generateDictionaryListContent.cjs.map +1 -1
- package/dist/cjs/createDictionaryEntryPoint/getBuiltDictionariesPath.cjs.map +1 -1
- package/dist/cjs/createDictionaryEntryPoint/getBuiltDynamicDictionariesPath.cjs.map +1 -1
- package/dist/cjs/createDictionaryEntryPoint/getBuiltFetchDictionariesPath.cjs.map +1 -1
- package/dist/cjs/createDictionaryEntryPoint/getBuiltRemoteDictionariesPath.cjs.map +1 -1
- package/dist/cjs/createDictionaryEntryPoint/getBuiltUnmergedDictionariesPath.cjs.map +1 -1
- package/dist/cjs/createType/createModuleAugmentation.cjs.map +1 -1
- package/dist/cjs/createType/createType.cjs +0 -1
- package/dist/cjs/createType/createType.cjs.map +1 -1
- package/dist/cjs/detectFormatCommand.cjs +0 -1
- package/dist/cjs/detectFormatCommand.cjs.map +1 -1
- package/dist/cjs/docReview/alignBlocks.cjs.map +1 -1
- package/dist/cjs/docReview/computeSimilarity.cjs +1 -1
- package/dist/cjs/docReview/computeSimilarity.cjs.map +1 -1
- package/dist/cjs/docReview/fingerprintBlock.cjs +3 -1
- package/dist/cjs/docReview/fingerprintBlock.cjs.map +1 -1
- package/dist/cjs/docReview/mapChangedLinesToBlocks.cjs.map +1 -1
- package/dist/cjs/docReview/normalizeBlock.cjs +4 -2
- package/dist/cjs/docReview/normalizeBlock.cjs.map +1 -1
- package/dist/cjs/docReview/pipeline.cjs +3 -2
- package/dist/cjs/docReview/pipeline.cjs.map +1 -1
- package/dist/cjs/docReview/planActions.cjs.map +1 -1
- package/dist/cjs/docReview/rebuildDocument.cjs.map +1 -1
- package/dist/cjs/docReview/reviewReport.cjs.map +1 -1
- package/dist/cjs/docReview/segmentDocument.cjs.map +1 -1
- package/dist/cjs/fetchDistantDictionaries.cjs +0 -1
- package/dist/cjs/fetchDistantDictionaries.cjs.map +1 -1
- package/dist/cjs/filterInvalidDictionaries.cjs.map +1 -1
- package/dist/cjs/formatDictionary.cjs +0 -1
- package/dist/cjs/formatDictionary.cjs.map +1 -1
- package/dist/cjs/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.cjs +0 -1
- package/dist/cjs/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.cjs.map +1 -1
- package/dist/cjs/handleAdditionalContentDeclarationFile.cjs +0 -1
- package/dist/cjs/handleAdditionalContentDeclarationFile.cjs.map +1 -1
- package/dist/cjs/handleContentDeclarationFileChange.cjs +0 -1
- package/dist/cjs/handleContentDeclarationFileChange.cjs.map +1 -1
- package/dist/cjs/handleContentDeclarationFileMoved.cjs +0 -1
- package/dist/cjs/handleContentDeclarationFileMoved.cjs.map +1 -1
- package/dist/cjs/handleUnlinkedContentDeclarationFile.cjs +0 -1
- package/dist/cjs/handleUnlinkedContentDeclarationFile.cjs.map +1 -1
- package/dist/cjs/init/cms.cjs.map +1 -1
- package/dist/cjs/init/frameworkSetup/index.cjs.map +1 -1
- package/dist/cjs/init/frameworkSetup/nextAppRouter/detect.cjs +0 -1
- package/dist/cjs/init/frameworkSetup/nextAppRouter/detect.cjs.map +1 -1
- package/dist/cjs/init/frameworkSetup/nextAppRouter/index.cjs.map +1 -1
- package/dist/cjs/init/frameworkSetup/nextAppRouter/restructure.cjs +4 -3
- package/dist/cjs/init/frameworkSetup/nextAppRouter/restructure.cjs.map +1 -1
- package/dist/cjs/init/frameworkSetup/nextAppRouter/transforms.cjs.map +1 -1
- package/dist/cjs/init/frameworkSetup/tanstackStart/detect.cjs +0 -1
- package/dist/cjs/init/frameworkSetup/tanstackStart/detect.cjs.map +1 -1
- package/dist/cjs/init/frameworkSetup/tanstackStart/index.cjs.map +1 -1
- package/dist/cjs/init/frameworkSetup/tanstackStart/restructure.cjs +2 -2
- package/dist/cjs/init/frameworkSetup/tanstackStart/restructure.cjs.map +1 -1
- package/dist/cjs/init/frameworkSetup/tanstackStart/transforms.cjs.map +1 -1
- package/dist/cjs/init/index.cjs.map +1 -1
- package/dist/cjs/init/utils/astImports.cjs.map +1 -1
- package/dist/cjs/init/utils/configManipulation.cjs +12 -6
- package/dist/cjs/init/utils/configManipulation.cjs.map +1 -1
- package/dist/cjs/init/utils/fileSystem.cjs +1 -1
- package/dist/cjs/init/utils/fileSystem.cjs.map +1 -1
- package/dist/cjs/init/utils/githubActions.cjs +0 -1
- package/dist/cjs/init/utils/githubActions.cjs.map +1 -1
- package/dist/cjs/init/utils/jsonParser.cjs.map +1 -1
- package/dist/cjs/init/utils/nextCompilerBabel.cjs.map +1 -1
- package/dist/cjs/init/utils/packageManager.cjs +4 -3
- package/dist/cjs/init/utils/packageManager.cjs.map +1 -1
- package/dist/cjs/init/utils/tsConfig.cjs +0 -1
- package/dist/cjs/init/utils/tsConfig.cjs.map +1 -1
- package/dist/cjs/init/utils/version.cjs.map +1 -1
- package/dist/cjs/initConfig/index.cjs +0 -1
- package/dist/cjs/initConfig/index.cjs.map +1 -1
- package/dist/cjs/installLSP.cjs.map +1 -1
- package/dist/cjs/installMCP/installMCP.cjs.map +1 -1
- package/dist/cjs/installSkills/index.cjs +1 -1
- package/dist/cjs/installSkills/index.cjs.map +1 -1
- package/dist/cjs/listDictionariesPath.cjs.map +1 -1
- package/dist/cjs/listGitFiles.cjs.map +1 -1
- package/dist/cjs/listProjects.cjs.map +1 -1
- package/dist/cjs/loadDictionaries/getIntlayerBundle.cjs +0 -1
- package/dist/cjs/loadDictionaries/getIntlayerBundle.cjs.map +1 -1
- package/dist/cjs/loadDictionaries/loadContentDeclaration.cjs +3 -3
- package/dist/cjs/loadDictionaries/loadContentDeclaration.cjs.map +1 -1
- package/dist/cjs/loadDictionaries/loadDictionaries.cjs +3 -2
- package/dist/cjs/loadDictionaries/loadDictionaries.cjs.map +1 -1
- package/dist/cjs/loadDictionaries/loadLocalDictionaries.cjs +0 -1
- package/dist/cjs/loadDictionaries/loadLocalDictionaries.cjs.map +1 -1
- package/dist/cjs/loadDictionaries/loadMarkdownContentDeclaration.cjs +0 -1
- package/dist/cjs/loadDictionaries/loadMarkdownContentDeclaration.cjs.map +1 -1
- package/dist/cjs/loadDictionaries/loadRemoteDictionaries.cjs +2 -2
- package/dist/cjs/loadDictionaries/loadRemoteDictionaries.cjs.map +1 -1
- package/dist/cjs/loadDictionaries/loadYamlContentDeclaration.cjs +0 -1
- package/dist/cjs/loadDictionaries/loadYamlContentDeclaration.cjs.map +1 -1
- package/dist/cjs/loadDictionaries/log.cjs.map +1 -1
- package/dist/cjs/loadDictionaries/logTypeScriptErrors.cjs +0 -1
- package/dist/cjs/loadDictionaries/logTypeScriptErrors.cjs.map +1 -1
- package/dist/cjs/logConfigDetails.cjs +6 -3
- package/dist/cjs/logConfigDetails.cjs.map +1 -1
- package/dist/cjs/prepareIntlayer.cjs +2 -1
- package/dist/cjs/prepareIntlayer.cjs.map +1 -1
- package/dist/cjs/reduceDictionaryContent/applyMask.cjs.map +1 -1
- package/dist/cjs/reduceDictionaryContent/reduceDictionaryContent.cjs +0 -1
- package/dist/cjs/reduceDictionaryContent/reduceDictionaryContent.cjs.map +1 -1
- package/dist/cjs/scan/analyzeBundleContent.cjs +0 -1
- package/dist/cjs/scan/analyzeBundleContent.cjs.map +1 -1
- package/dist/cjs/scan/calculateScore.cjs.map +1 -1
- package/dist/cjs/scan/checks.cjs +0 -1
- package/dist/cjs/scan/checks.cjs.map +1 -1
- package/dist/cjs/scan/parseHtml.cjs.map +1 -1
- package/dist/cjs/scan/scanWebsite.cjs +2 -2
- package/dist/cjs/scan/scanWebsite.cjs.map +1 -1
- package/dist/cjs/syncPluginKit/createFileAdapter.cjs.map +1 -1
- package/dist/cjs/syncPluginKit/createSyncPlugin.cjs +9 -4
- package/dist/cjs/syncPluginKit/createSyncPlugin.cjs.map +1 -1
- package/dist/cjs/syncPluginKit/extractKeyAndLocaleFromPath.cjs.map +1 -1
- package/dist/cjs/syncPluginKit/filePathPatternHelpers.cjs.map +1 -1
- package/dist/cjs/utils/autoDecorateContent.cjs.map +1 -1
- package/dist/cjs/utils/buildComponentFilesList.cjs +2 -2
- package/dist/cjs/utils/buildComponentFilesList.cjs.map +1 -1
- package/dist/cjs/utils/buildFilesList.cjs +2 -1
- package/dist/cjs/utils/buildFilesList.cjs.map +1 -1
- package/dist/cjs/utils/chunkJSON.cjs +2 -1
- package/dist/cjs/utils/chunkJSON.cjs.map +1 -1
- package/dist/cjs/utils/formatter.cjs.map +1 -1
- package/dist/cjs/utils/getChunk.cjs.map +1 -1
- package/dist/cjs/utils/getContentExtension.cjs.map +1 -1
- package/dist/cjs/utils/getFormatFromExtension.cjs.map +1 -1
- package/dist/cjs/utils/getPathHash.cjs.map +1 -1
- package/dist/cjs/utils/mergeChunks.cjs.map +1 -1
- package/dist/cjs/utils/pLimit.cjs.map +1 -1
- package/dist/cjs/utils/parallelize.cjs.map +1 -1
- package/dist/cjs/utils/parallelizeGlobal.cjs.map +1 -1
- package/dist/cjs/utils/readDictionariesFromDisk.cjs +0 -1
- package/dist/cjs/utils/readDictionariesFromDisk.cjs.map +1 -1
- package/dist/cjs/utils/recastBabelParser.cjs +3 -4
- package/dist/cjs/utils/recastBabelParser.cjs.map +1 -1
- package/dist/cjs/utils/reduceObjectFormat.cjs.map +1 -1
- package/dist/cjs/utils/resolveObjectPromises.cjs +8 -2
- package/dist/cjs/utils/resolveObjectPromises.cjs.map +1 -1
- package/dist/cjs/utils/resolveRelativePath.cjs +0 -1
- package/dist/cjs/utils/resolveRelativePath.cjs.map +1 -1
- package/dist/cjs/utils/runOnce.cjs.map +1 -1
- package/dist/cjs/utils/runParallel/bin.cjs +0 -1
- package/dist/cjs/utils/runParallel/bin.cjs.map +1 -1
- package/dist/cjs/utils/runParallel/bootstrap.cjs.map +1 -1
- package/dist/cjs/utils/runParallel/index.cjs +2 -3
- package/dist/cjs/utils/runParallel/index.cjs.map +1 -1
- package/dist/cjs/utils/runParallel/pidTree.cjs.map +1 -1
- package/dist/cjs/utils/runParallel/ps.cjs.map +1 -1
- package/dist/cjs/utils/runParallel/runTask.cjs +0 -1
- package/dist/cjs/utils/runParallel/runTask.cjs.map +1 -1
- package/dist/cjs/utils/runParallel/spawnPosix.cjs +0 -1
- package/dist/cjs/utils/runParallel/spawnPosix.cjs.map +1 -1
- package/dist/cjs/utils/runParallel/spawnWin32.cjs +0 -1
- package/dist/cjs/utils/runParallel/spawnWin32.cjs.map +1 -1
- package/dist/cjs/utils/runParallel/wmic.cjs.map +1 -1
- package/dist/cjs/utils/sortAlphabetically.cjs.map +1 -1
- package/dist/cjs/utils/splitTextByLine.cjs.map +1 -1
- package/dist/cjs/utils/verifyIdenticObjectFormat.cjs.map +1 -1
- package/dist/cjs/watcher.cjs.map +1 -1
- package/dist/cjs/writeConfiguration/generateConfigurationContent.cjs.map +1 -1
- package/dist/cjs/writeConfiguration/index.cjs +0 -1
- package/dist/cjs/writeConfiguration/index.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/detectExportedComponentName.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/processContentDeclarationContent.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/transformJSFile.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/transformJSONFile.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/writeContentDeclaration.cjs +3 -4
- package/dist/cjs/writeContentDeclaration/writeContentDeclaration.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/writeJSFile.cjs +0 -1
- package/dist/cjs/writeContentDeclaration/writeJSFile.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/writeMarkdownFile.cjs +5 -4
- package/dist/cjs/writeContentDeclaration/writeMarkdownFile.cjs.map +1 -1
- package/dist/cjs/writeContentDeclaration/writeYamlFile.cjs +1 -2
- package/dist/cjs/writeContentDeclaration/writeYamlFile.cjs.map +1 -1
- package/dist/cjs/writeFileIfChanged.cjs +0 -1
- package/dist/cjs/writeFileIfChanged.cjs.map +1 -1
- package/dist/cjs/writeJsonIfChanged.cjs.map +1 -1
- package/dist/esm/_virtual/_utils_asset.mjs +4 -2
- package/dist/esm/buildIntlayerDictionary/buildIntlayerDictionary.mjs.map +1 -1
- package/dist/esm/buildIntlayerDictionary/processContentDeclaration.mjs.map +1 -1
- package/dist/esm/buildIntlayerDictionary/writeDynamicDictionary.mjs.map +1 -1
- package/dist/esm/buildIntlayerDictionary/writeFetchDictionary.mjs.map +1 -1
- package/dist/esm/buildIntlayerDictionary/writeMergedDictionary.mjs +2 -1
- package/dist/esm/buildIntlayerDictionary/writeMergedDictionary.mjs.map +1 -1
- package/dist/esm/buildIntlayerDictionary/writeRemoteDictionary.mjs +2 -1
- package/dist/esm/buildIntlayerDictionary/writeRemoteDictionary.mjs.map +1 -1
- package/dist/esm/buildIntlayerDictionary/writeUnmergedDictionary.mjs +4 -2
- package/dist/esm/buildIntlayerDictionary/writeUnmergedDictionary.mjs.map +1 -1
- package/dist/esm/cleanOutputDir.mjs.map +1 -1
- package/dist/esm/cleanRemovedContentDeclaration.mjs.map +1 -1
- package/dist/esm/createDictionaryEntryPoint/createDictionaryEntryPoint.mjs.map +1 -1
- package/dist/esm/createDictionaryEntryPoint/generateDictionaryListContent.mjs.map +1 -1
- package/dist/esm/createDictionaryEntryPoint/getBuiltDictionariesPath.mjs.map +1 -1
- package/dist/esm/createDictionaryEntryPoint/getBuiltDynamicDictionariesPath.mjs.map +1 -1
- package/dist/esm/createDictionaryEntryPoint/getBuiltFetchDictionariesPath.mjs.map +1 -1
- package/dist/esm/createDictionaryEntryPoint/getBuiltRemoteDictionariesPath.mjs.map +1 -1
- package/dist/esm/createDictionaryEntryPoint/getBuiltUnmergedDictionariesPath.mjs.map +1 -1
- package/dist/esm/createType/createModuleAugmentation.mjs.map +1 -1
- package/dist/esm/createType/createType.mjs.map +1 -1
- package/dist/esm/detectFormatCommand.mjs.map +1 -1
- package/dist/esm/docReview/alignBlocks.mjs.map +1 -1
- package/dist/esm/docReview/computeSimilarity.mjs +1 -1
- package/dist/esm/docReview/computeSimilarity.mjs.map +1 -1
- package/dist/esm/docReview/fingerprintBlock.mjs +3 -1
- package/dist/esm/docReview/fingerprintBlock.mjs.map +1 -1
- package/dist/esm/docReview/mapChangedLinesToBlocks.mjs.map +1 -1
- package/dist/esm/docReview/normalizeBlock.mjs +4 -2
- package/dist/esm/docReview/normalizeBlock.mjs.map +1 -1
- package/dist/esm/docReview/pipeline.mjs +3 -2
- package/dist/esm/docReview/pipeline.mjs.map +1 -1
- package/dist/esm/docReview/planActions.mjs.map +1 -1
- package/dist/esm/docReview/rebuildDocument.mjs.map +1 -1
- package/dist/esm/docReview/reviewReport.mjs.map +1 -1
- package/dist/esm/docReview/segmentDocument.mjs.map +1 -1
- package/dist/esm/fetchDistantDictionaries.mjs.map +1 -1
- package/dist/esm/filterInvalidDictionaries.mjs.map +1 -1
- package/dist/esm/formatDictionary.mjs.map +1 -1
- package/dist/esm/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.mjs.map +1 -1
- package/dist/esm/handleAdditionalContentDeclarationFile.mjs.map +1 -1
- package/dist/esm/handleContentDeclarationFileChange.mjs.map +1 -1
- package/dist/esm/handleContentDeclarationFileMoved.mjs.map +1 -1
- package/dist/esm/handleUnlinkedContentDeclarationFile.mjs.map +1 -1
- package/dist/esm/init/cms.mjs.map +1 -1
- package/dist/esm/init/frameworkSetup/index.mjs.map +1 -1
- package/dist/esm/init/frameworkSetup/nextAppRouter/detect.mjs.map +1 -1
- package/dist/esm/init/frameworkSetup/nextAppRouter/index.mjs.map +1 -1
- package/dist/esm/init/frameworkSetup/nextAppRouter/restructure.mjs +4 -3
- package/dist/esm/init/frameworkSetup/nextAppRouter/restructure.mjs.map +1 -1
- package/dist/esm/init/frameworkSetup/nextAppRouter/transforms.mjs.map +1 -1
- package/dist/esm/init/frameworkSetup/tanstackStart/detect.mjs.map +1 -1
- package/dist/esm/init/frameworkSetup/tanstackStart/index.mjs.map +1 -1
- package/dist/esm/init/frameworkSetup/tanstackStart/restructure.mjs +2 -2
- package/dist/esm/init/frameworkSetup/tanstackStart/restructure.mjs.map +1 -1
- package/dist/esm/init/frameworkSetup/tanstackStart/transforms.mjs.map +1 -1
- package/dist/esm/init/index.mjs.map +1 -1
- package/dist/esm/init/utils/astImports.mjs.map +1 -1
- package/dist/esm/init/utils/configManipulation.mjs +12 -6
- package/dist/esm/init/utils/configManipulation.mjs.map +1 -1
- package/dist/esm/init/utils/fileSystem.mjs +1 -1
- package/dist/esm/init/utils/fileSystem.mjs.map +1 -1
- package/dist/esm/init/utils/githubActions.mjs.map +1 -1
- package/dist/esm/init/utils/jsonParser.mjs.map +1 -1
- package/dist/esm/init/utils/nextCompilerBabel.mjs.map +1 -1
- package/dist/esm/init/utils/packageManager.mjs +4 -2
- package/dist/esm/init/utils/packageManager.mjs.map +1 -1
- package/dist/esm/init/utils/tsConfig.mjs.map +1 -1
- package/dist/esm/init/utils/version.mjs.map +1 -1
- package/dist/esm/initConfig/index.mjs.map +1 -1
- package/dist/esm/installLSP.mjs.map +1 -1
- package/dist/esm/installMCP/installMCP.mjs.map +1 -1
- package/dist/esm/installSkills/index.mjs +1 -1
- package/dist/esm/installSkills/index.mjs.map +1 -1
- package/dist/esm/listDictionariesPath.mjs.map +1 -1
- package/dist/esm/listGitFiles.mjs.map +1 -1
- package/dist/esm/listProjects.mjs.map +1 -1
- package/dist/esm/loadDictionaries/getIntlayerBundle.mjs.map +1 -1
- package/dist/esm/loadDictionaries/loadContentDeclaration.mjs +3 -2
- package/dist/esm/loadDictionaries/loadContentDeclaration.mjs.map +1 -1
- package/dist/esm/loadDictionaries/loadDictionaries.mjs +3 -2
- package/dist/esm/loadDictionaries/loadDictionaries.mjs.map +1 -1
- package/dist/esm/loadDictionaries/loadLocalDictionaries.mjs.map +1 -1
- package/dist/esm/loadDictionaries/loadMarkdownContentDeclaration.mjs.map +1 -1
- package/dist/esm/loadDictionaries/loadRemoteDictionaries.mjs +2 -1
- package/dist/esm/loadDictionaries/loadRemoteDictionaries.mjs.map +1 -1
- package/dist/esm/loadDictionaries/loadYamlContentDeclaration.mjs.map +1 -1
- package/dist/esm/loadDictionaries/log.mjs.map +1 -1
- package/dist/esm/loadDictionaries/logTypeScriptErrors.mjs.map +1 -1
- package/dist/esm/logConfigDetails.mjs +6 -3
- package/dist/esm/logConfigDetails.mjs.map +1 -1
- package/dist/esm/prepareIntlayer.mjs +2 -1
- package/dist/esm/prepareIntlayer.mjs.map +1 -1
- package/dist/esm/reduceDictionaryContent/applyMask.mjs.map +1 -1
- package/dist/esm/reduceDictionaryContent/reduceDictionaryContent.mjs.map +1 -1
- package/dist/esm/scan/analyzeBundleContent.mjs.map +1 -1
- package/dist/esm/scan/calculateScore.mjs.map +1 -1
- package/dist/esm/scan/checks.mjs.map +1 -1
- package/dist/esm/scan/parseHtml.mjs.map +1 -1
- package/dist/esm/scan/scanWebsite.mjs +2 -1
- package/dist/esm/scan/scanWebsite.mjs.map +1 -1
- package/dist/esm/syncPluginKit/createFileAdapter.mjs.map +1 -1
- package/dist/esm/syncPluginKit/createSyncPlugin.mjs +9 -3
- package/dist/esm/syncPluginKit/createSyncPlugin.mjs.map +1 -1
- package/dist/esm/syncPluginKit/extractKeyAndLocaleFromPath.mjs.map +1 -1
- package/dist/esm/syncPluginKit/filePathPatternHelpers.mjs.map +1 -1
- package/dist/esm/utils/autoDecorateContent.mjs.map +1 -1
- package/dist/esm/utils/buildComponentFilesList.mjs +2 -2
- package/dist/esm/utils/buildComponentFilesList.mjs.map +1 -1
- package/dist/esm/utils/buildFilesList.mjs +2 -1
- package/dist/esm/utils/buildFilesList.mjs.map +1 -1
- package/dist/esm/utils/chunkJSON.mjs +2 -1
- package/dist/esm/utils/chunkJSON.mjs.map +1 -1
- package/dist/esm/utils/formatter.mjs.map +1 -1
- package/dist/esm/utils/getChunk.mjs.map +1 -1
- package/dist/esm/utils/getContentExtension.mjs.map +1 -1
- package/dist/esm/utils/getFormatFromExtension.mjs.map +1 -1
- package/dist/esm/utils/getPathHash.mjs.map +1 -1
- package/dist/esm/utils/mergeChunks.mjs.map +1 -1
- package/dist/esm/utils/pLimit.mjs.map +1 -1
- package/dist/esm/utils/parallelize.mjs.map +1 -1
- package/dist/esm/utils/parallelizeGlobal.mjs.map +1 -1
- package/dist/esm/utils/readDictionariesFromDisk.mjs.map +1 -1
- package/dist/esm/utils/recastBabelParser.mjs +1 -1
- package/dist/esm/utils/recastBabelParser.mjs.map +1 -1
- package/dist/esm/utils/reduceObjectFormat.mjs.map +1 -1
- package/dist/esm/utils/resolveObjectPromises.mjs +8 -2
- package/dist/esm/utils/resolveObjectPromises.mjs.map +1 -1
- package/dist/esm/utils/resolveRelativePath.mjs.map +1 -1
- package/dist/esm/utils/runOnce.mjs.map +1 -1
- package/dist/esm/utils/runParallel/bin.mjs.map +1 -1
- package/dist/esm/utils/runParallel/bootstrap.mjs.map +1 -1
- package/dist/esm/utils/runParallel/index.mjs +2 -2
- package/dist/esm/utils/runParallel/index.mjs.map +1 -1
- package/dist/esm/utils/runParallel/pidTree.mjs.map +1 -1
- package/dist/esm/utils/runParallel/ps.mjs.map +1 -1
- package/dist/esm/utils/runParallel/runTask.mjs.map +1 -1
- package/dist/esm/utils/runParallel/spawnPosix.mjs.map +1 -1
- package/dist/esm/utils/runParallel/spawnWin32.mjs.map +1 -1
- package/dist/esm/utils/runParallel/wmic.mjs.map +1 -1
- package/dist/esm/utils/sortAlphabetically.mjs.map +1 -1
- package/dist/esm/utils/splitTextByLine.mjs.map +1 -1
- package/dist/esm/utils/verifyIdenticObjectFormat.mjs.map +1 -1
- package/dist/esm/watcher.mjs.map +1 -1
- package/dist/esm/writeConfiguration/generateConfigurationContent.mjs.map +1 -1
- package/dist/esm/writeConfiguration/index.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/detectExportedComponentName.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/processContentDeclarationContent.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/transformJSFile.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/transformJSONFile.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/writeContentDeclaration.mjs +3 -3
- package/dist/esm/writeContentDeclaration/writeContentDeclaration.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/writeJSFile.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/writeMarkdownFile.mjs +5 -3
- package/dist/esm/writeContentDeclaration/writeMarkdownFile.mjs.map +1 -1
- package/dist/esm/writeContentDeclaration/writeYamlFile.mjs +1 -1
- package/dist/esm/writeContentDeclaration/writeYamlFile.mjs.map +1 -1
- package/dist/esm/writeFileIfChanged.mjs.map +1 -1
- package/dist/esm/writeJsonIfChanged.mjs.map +1 -1
- package/dist/types/build.d.ts +5 -0
- package/dist/types/buildIntlayerDictionary/buildIntlayerDictionary.d.ts +0 -1
- package/dist/types/buildIntlayerDictionary/buildIntlayerDictionary.d.ts.map +1 -1
- package/dist/types/buildIntlayerDictionary/processContentDeclaration.d.ts +0 -1
- package/dist/types/buildIntlayerDictionary/processContentDeclaration.d.ts.map +1 -1
- package/dist/types/buildIntlayerDictionary/writeDynamicDictionary.d.ts +4 -5
- package/dist/types/buildIntlayerDictionary/writeDynamicDictionary.d.ts.map +1 -1
- package/dist/types/buildIntlayerDictionary/writeFetchDictionary.d.ts +2 -3
- package/dist/types/buildIntlayerDictionary/writeFetchDictionary.d.ts.map +1 -1
- package/dist/types/buildIntlayerDictionary/writeMergedDictionary.d.ts +0 -1
- package/dist/types/buildIntlayerDictionary/writeMergedDictionary.d.ts.map +1 -1
- package/dist/types/buildIntlayerDictionary/writeRemoteDictionary.d.ts +0 -1
- package/dist/types/buildIntlayerDictionary/writeRemoteDictionary.d.ts.map +1 -1
- package/dist/types/buildIntlayerDictionary/writeUnmergedDictionary.d.ts +1 -2
- package/dist/types/buildIntlayerDictionary/writeUnmergedDictionary.d.ts.map +1 -1
- package/dist/types/cleanOutputDir.d.ts +0 -1
- package/dist/types/cleanOutputDir.d.ts.map +1 -1
- package/dist/types/cleanRemovedContentDeclaration.d.ts +0 -1
- package/dist/types/cleanRemovedContentDeclaration.d.ts.map +1 -1
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/createDictionaryEntryPoint/createDictionaryEntryPoint.d.ts +1 -3
- package/dist/types/createDictionaryEntryPoint/createDictionaryEntryPoint.d.ts.map +1 -1
- package/dist/types/createDictionaryEntryPoint/generateDictionaryListContent.d.ts +1 -3
- package/dist/types/createDictionaryEntryPoint/generateDictionaryListContent.d.ts.map +1 -1
- package/dist/types/createDictionaryEntryPoint/getBuiltDictionariesPath.d.ts +0 -1
- package/dist/types/createDictionaryEntryPoint/getBuiltDictionariesPath.d.ts.map +1 -1
- package/dist/types/createDictionaryEntryPoint/getBuiltDynamicDictionariesPath.d.ts +1 -2
- package/dist/types/createDictionaryEntryPoint/getBuiltDynamicDictionariesPath.d.ts.map +1 -1
- package/dist/types/createDictionaryEntryPoint/getBuiltFetchDictionariesPath.d.ts +1 -2
- package/dist/types/createDictionaryEntryPoint/getBuiltFetchDictionariesPath.d.ts.map +1 -1
- package/dist/types/createDictionaryEntryPoint/getBuiltRemoteDictionariesPath.d.ts +0 -1
- package/dist/types/createDictionaryEntryPoint/getBuiltRemoteDictionariesPath.d.ts.map +1 -1
- package/dist/types/createDictionaryEntryPoint/getBuiltUnmergedDictionariesPath.d.ts +0 -1
- package/dist/types/createDictionaryEntryPoint/getBuiltUnmergedDictionariesPath.d.ts.map +1 -1
- package/dist/types/createType/createModuleAugmentation.d.ts +0 -1
- package/dist/types/createType/createModuleAugmentation.d.ts.map +1 -1
- package/dist/types/createType/createType.d.ts +0 -1
- package/dist/types/createType/createType.d.ts.map +1 -1
- package/dist/types/detectFormatCommand.d.ts +0 -1
- package/dist/types/detectFormatCommand.d.ts.map +1 -1
- package/dist/types/docReview/alignBlocks.d.ts +0 -1
- package/dist/types/docReview/alignBlocks.d.ts.map +1 -1
- package/dist/types/docReview/computeSimilarity.d.ts.map +1 -1
- package/dist/types/docReview/fingerprintBlock.d.ts +0 -1
- package/dist/types/docReview/fingerprintBlock.d.ts.map +1 -1
- package/dist/types/docReview/mapChangedLinesToBlocks.d.ts +0 -1
- package/dist/types/docReview/mapChangedLinesToBlocks.d.ts.map +1 -1
- package/dist/types/docReview/normalizeBlock.d.ts +0 -1
- package/dist/types/docReview/normalizeBlock.d.ts.map +1 -1
- package/dist/types/docReview/pipeline.d.ts +6 -8
- package/dist/types/docReview/pipeline.d.ts.map +1 -1
- package/dist/types/docReview/planActions.d.ts +0 -1
- package/dist/types/docReview/planActions.d.ts.map +1 -1
- package/dist/types/docReview/rebuildDocument.d.ts +6 -8
- package/dist/types/docReview/rebuildDocument.d.ts.map +1 -1
- package/dist/types/docReview/reviewReport.d.ts +23 -14
- package/dist/types/docReview/reviewReport.d.ts.map +1 -1
- package/dist/types/docReview/segmentDocument.d.ts +0 -1
- package/dist/types/docReview/segmentDocument.d.ts.map +1 -1
- package/dist/types/docReview/types.d.ts +10 -4
- package/dist/types/docReview/types.d.ts.map +1 -1
- package/dist/types/fetchDistantDictionaries.d.ts +1 -1
- package/dist/types/fetchDistantDictionaries.d.ts.map +1 -1
- package/dist/types/filterInvalidDictionaries.d.ts +0 -1
- package/dist/types/filterInvalidDictionaries.d.ts.map +1 -1
- package/dist/types/formatDictionary.d.ts +27 -30
- package/dist/types/formatDictionary.d.ts.map +1 -1
- package/dist/types/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.d.ts +0 -1
- package/dist/types/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.d.ts.map +1 -1
- package/dist/types/handleAdditionalContentDeclarationFile.d.ts +0 -1
- package/dist/types/handleAdditionalContentDeclarationFile.d.ts.map +1 -1
- package/dist/types/handleContentDeclarationFileChange.d.ts +0 -1
- package/dist/types/handleContentDeclarationFileChange.d.ts.map +1 -1
- package/dist/types/handleContentDeclarationFileMoved.d.ts +0 -1
- package/dist/types/handleContentDeclarationFileMoved.d.ts.map +1 -1
- package/dist/types/handleUnlinkedContentDeclarationFile.d.ts +0 -1
- package/dist/types/handleUnlinkedContentDeclarationFile.d.ts.map +1 -1
- package/dist/types/init/cms.d.ts +2 -6
- package/dist/types/init/cms.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/index.d.ts +0 -1
- package/dist/types/init/frameworkSetup/index.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/nextAppRouter/detect.d.ts +3 -2
- package/dist/types/init/frameworkSetup/nextAppRouter/detect.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/nextAppRouter/index.d.ts +0 -1
- package/dist/types/init/frameworkSetup/nextAppRouter/index.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/nextAppRouter/restructure.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/nextAppRouter/templates.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/nextAppRouter/transforms.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/tanstackStart/detect.d.ts +3 -1
- package/dist/types/init/frameworkSetup/tanstackStart/detect.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/tanstackStart/index.d.ts +0 -1
- package/dist/types/init/frameworkSetup/tanstackStart/index.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/tanstackStart/restructure.d.ts +0 -1
- package/dist/types/init/frameworkSetup/tanstackStart/restructure.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/tanstackStart/templates.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/tanstackStart/transforms.d.ts.map +1 -1
- package/dist/types/init/frameworkSetup/types.d.ts +9 -5
- package/dist/types/init/frameworkSetup/types.d.ts.map +1 -1
- package/dist/types/init/index.d.ts +7 -3
- package/dist/types/init/index.d.ts.map +1 -1
- package/dist/types/init/utils/astImports.d.ts.map +1 -1
- package/dist/types/init/utils/configManipulation.d.ts +0 -1
- package/dist/types/init/utils/configManipulation.d.ts.map +1 -1
- package/dist/types/init/utils/fileSystem.d.ts +6 -3
- package/dist/types/init/utils/fileSystem.d.ts.map +1 -1
- package/dist/types/init/utils/githubActions.d.ts +7 -4
- package/dist/types/init/utils/githubActions.d.ts.map +1 -1
- package/dist/types/init/utils/jsonParser.d.ts.map +1 -1
- package/dist/types/init/utils/nextCompilerBabel.d.ts +2 -8
- package/dist/types/init/utils/nextCompilerBabel.d.ts.map +1 -1
- package/dist/types/init/utils/packageManager.d.ts +9 -3
- package/dist/types/init/utils/packageManager.d.ts.map +1 -1
- package/dist/types/init/utils/tsConfig.d.ts.map +1 -1
- package/dist/types/init/utils/version.d.ts.map +1 -1
- package/dist/types/initConfig/index.d.ts +2 -2
- package/dist/types/initConfig/index.d.ts.map +1 -1
- package/dist/types/installLSP.d.ts.map +1 -1
- package/dist/types/installMCP/installMCP.d.ts +0 -1
- package/dist/types/installMCP/installMCP.d.ts.map +1 -1
- package/dist/types/installSkills/index.d.ts +14 -14
- package/dist/types/installSkills/index.d.ts.map +1 -1
- package/dist/types/listDictionariesPath.d.ts +1 -3
- package/dist/types/listDictionariesPath.d.ts.map +1 -1
- package/dist/types/listGitFiles.d.ts +2 -11
- package/dist/types/listGitFiles.d.ts.map +1 -1
- package/dist/types/listProjects.d.ts.map +1 -1
- package/dist/types/loadDictionaries/getIntlayerBundle.d.ts +0 -1
- package/dist/types/loadDictionaries/getIntlayerBundle.d.ts.map +1 -1
- package/dist/types/loadDictionaries/loadContentDeclaration.d.ts +0 -1
- package/dist/types/loadDictionaries/loadContentDeclaration.d.ts.map +1 -1
- package/dist/types/loadDictionaries/loadDictionaries.d.ts +0 -1
- package/dist/types/loadDictionaries/loadDictionaries.d.ts.map +1 -1
- package/dist/types/loadDictionaries/loadLocalDictionaries.d.ts +0 -1
- package/dist/types/loadDictionaries/loadLocalDictionaries.d.ts.map +1 -1
- package/dist/types/loadDictionaries/loadMarkdownContentDeclaration.d.ts +0 -1
- package/dist/types/loadDictionaries/loadMarkdownContentDeclaration.d.ts.map +1 -1
- package/dist/types/loadDictionaries/loadRemoteDictionaries.d.ts +1 -3
- package/dist/types/loadDictionaries/loadRemoteDictionaries.d.ts.map +1 -1
- package/dist/types/loadDictionaries/loadYamlContentDeclaration.d.ts +0 -1
- package/dist/types/loadDictionaries/loadYamlContentDeclaration.d.ts.map +1 -1
- package/dist/types/loadDictionaries/log.d.ts +0 -1
- package/dist/types/loadDictionaries/log.d.ts.map +1 -1
- package/dist/types/loadDictionaries/logTypeScriptErrors.d.ts +0 -1
- package/dist/types/loadDictionaries/logTypeScriptErrors.d.ts.map +1 -1
- package/dist/types/logConfigDetails.d.ts +0 -1
- package/dist/types/logConfigDetails.d.ts.map +1 -1
- package/dist/types/prepareIntlayer.d.ts +0 -1
- package/dist/types/prepareIntlayer.d.ts.map +1 -1
- package/dist/types/reduceDictionaryContent/applyMask.d.ts +0 -1
- package/dist/types/reduceDictionaryContent/applyMask.d.ts.map +1 -1
- package/dist/types/reduceDictionaryContent/reduceDictionaryContent.d.ts +0 -1
- package/dist/types/reduceDictionaryContent/reduceDictionaryContent.d.ts.map +1 -1
- package/dist/types/scan/analyzeBundleContent.d.ts +0 -1
- package/dist/types/scan/analyzeBundleContent.d.ts.map +1 -1
- package/dist/types/scan/calculateScore.d.ts +3 -1
- package/dist/types/scan/calculateScore.d.ts.map +1 -1
- package/dist/types/scan/checks.d.ts +0 -1
- package/dist/types/scan/checks.d.ts.map +1 -1
- package/dist/types/scan/parseHtml.d.ts.map +1 -1
- package/dist/types/scan/scanWebsite.d.ts +0 -1
- package/dist/types/scan/scanWebsite.d.ts.map +1 -1
- package/dist/types/scan/types.d.ts +32 -17
- package/dist/types/scan/types.d.ts.map +1 -1
- package/dist/types/syncPluginKit/createFileAdapter.d.ts +0 -1
- package/dist/types/syncPluginKit/createFileAdapter.d.ts.map +1 -1
- package/dist/types/syncPluginKit/createSyncPlugin.d.ts +0 -1
- package/dist/types/syncPluginKit/createSyncPlugin.d.ts.map +1 -1
- package/dist/types/syncPluginKit/extractKeyAndLocaleFromPath.d.ts +0 -1
- package/dist/types/syncPluginKit/extractKeyAndLocaleFromPath.d.ts.map +1 -1
- package/dist/types/syncPluginKit/filePathPatternHelpers.d.ts +0 -1
- package/dist/types/syncPluginKit/filePathPatternHelpers.d.ts.map +1 -1
- package/dist/types/syncPluginKit/types.d.ts +8 -4
- package/dist/types/syncPluginKit/types.d.ts.map +1 -1
- package/dist/types/utils/autoDecorateContent.d.ts.map +1 -1
- package/dist/types/utils/buildComponentFilesList.d.ts +0 -1
- package/dist/types/utils/buildComponentFilesList.d.ts.map +1 -1
- package/dist/types/utils/buildFilesList.d.ts +0 -1
- package/dist/types/utils/buildFilesList.d.ts.map +1 -1
- package/dist/types/utils/chunkJSON.d.ts.map +1 -1
- package/dist/types/utils/formatter.d.ts +0 -1
- package/dist/types/utils/formatter.d.ts.map +1 -1
- package/dist/types/utils/getChunk.d.ts.map +1 -1
- package/dist/types/utils/getContentExtension.d.ts +1 -2
- package/dist/types/utils/getContentExtension.d.ts.map +1 -1
- package/dist/types/utils/getFormatFromExtension.d.ts.map +1 -1
- package/dist/types/utils/getPathHash.d.ts.map +1 -1
- package/dist/types/utils/mergeChunks.d.ts.map +1 -1
- package/dist/types/utils/pLimit.d.ts.map +1 -1
- package/dist/types/utils/parallelize.d.ts.map +1 -1
- package/dist/types/utils/parallelizeGlobal.d.ts +3 -2
- package/dist/types/utils/parallelizeGlobal.d.ts.map +1 -1
- package/dist/types/utils/readDictionariesFromDisk.d.ts.map +1 -1
- package/dist/types/utils/recastBabelParser.d.ts.map +1 -1
- package/dist/types/utils/reduceObjectFormat.d.ts.map +1 -1
- package/dist/types/utils/resolveObjectPromises.d.ts.map +1 -1
- package/dist/types/utils/resolveRelativePath.d.ts.map +1 -1
- package/dist/types/utils/runOnce.d.ts.map +1 -1
- package/dist/types/utils/runParallel/bin.d.ts +0 -1
- package/dist/types/utils/runParallel/bin.d.ts.map +1 -1
- package/dist/types/utils/runParallel/bootstrap.d.ts.map +1 -1
- package/dist/types/utils/runParallel/index.d.ts.map +1 -1
- package/dist/types/utils/runParallel/pidTree.d.ts.map +1 -1
- package/dist/types/utils/runParallel/ps.d.ts.map +1 -1
- package/dist/types/utils/runParallel/runTask.d.ts.map +1 -1
- package/dist/types/utils/runParallel/spawnPosix.d.ts +0 -1
- package/dist/types/utils/runParallel/spawnPosix.d.ts.map +1 -1
- package/dist/types/utils/runParallel/spawnWin32.d.ts +0 -1
- package/dist/types/utils/runParallel/spawnWin32.d.ts.map +1 -1
- package/dist/types/utils/runParallel/wmic.d.ts.map +1 -1
- package/dist/types/utils/sortAlphabetically.d.ts.map +1 -1
- package/dist/types/utils/splitTextByLine.d.ts.map +1 -1
- package/dist/types/utils/verifyIdenticObjectFormat.d.ts.map +1 -1
- package/dist/types/watcher.d.ts +0 -1
- package/dist/types/watcher.d.ts.map +1 -1
- package/dist/types/writeConfiguration/generateConfigurationContent.d.ts +1 -2
- package/dist/types/writeConfiguration/generateConfigurationContent.d.ts.map +1 -1
- package/dist/types/writeConfiguration/index.d.ts +0 -1
- package/dist/types/writeConfiguration/index.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/detectExportedComponentName.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/dictionaryStatus.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/processContentDeclarationContent.d.ts +0 -1
- package/dist/types/writeContentDeclaration/processContentDeclarationContent.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/transformJSFile.d.ts +0 -1
- package/dist/types/writeContentDeclaration/transformJSFile.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/transformJSONFile.d.ts +0 -1
- package/dist/types/writeContentDeclaration/transformJSONFile.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/writeContentDeclaration.d.ts +0 -1
- package/dist/types/writeContentDeclaration/writeContentDeclaration.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/writeJSFile.d.ts +0 -1
- package/dist/types/writeContentDeclaration/writeJSFile.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/writeMarkdownFile.d.ts +0 -1
- package/dist/types/writeContentDeclaration/writeMarkdownFile.d.ts.map +1 -1
- package/dist/types/writeContentDeclaration/writeYamlFile.d.ts +0 -1
- package/dist/types/writeContentDeclaration/writeYamlFile.d.ts.map +1 -1
- package/dist/types/writeFileIfChanged.d.ts +4 -6
- package/dist/types/writeFileIfChanged.d.ts.map +1 -1
- package/dist/types/writeJsonIfChanged.d.ts +1 -3
- package/dist/types/writeJsonIfChanged.d.ts.map +1 -1
- package/package.json +20 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detectFormatCommand.mjs","names":[],"sources":["../../src/detectFormatCommand.ts"],"sourcesContent":["import { getProjectRequire } from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\n\nlet cachedFormatCommand: string | undefined | null = null;\n\nexport const detectFormatCommand = (\n configuration: IntlayerConfig,\n projectRequireProp?: NodeJS.Require\n) => {\n const { baseDir } = configuration.system;\n const { formatCommand } = configuration.content;\n const projectRequire = projectRequireProp ?? getProjectRequire(baseDir);\n\n // Priority: Explicit configuration\n // We do not cache this because the user might change their config file active-session.\n if (formatCommand) {\n return formatCommand;\n }\n\n // Priority: Cached detection\n // If not null, we have already performed the expensive checks.\n if (cachedFormatCommand !== null) {\n return cachedFormatCommand;\n }\n\n // Perform Detection\n\n // Try Prettier\n try {\n projectRequire.resolve('prettier');\n cachedFormatCommand = 'prettier --write \"{{file}}\" --log-level silent';\n return cachedFormatCommand;\n } catch (_error) {\n // Prettier not found, continue\n }\n\n // Try Biome\n try {\n projectRequire.resolve('biome');\n cachedFormatCommand = 'biome format \"{{file}}\" --write --log-level none';\n return cachedFormatCommand;\n } catch (_error) {\n // Biome not found, continue\n }\n\n // Try ESLint\n try {\n projectRequire.resolve('eslint');\n cachedFormatCommand =\n 'eslint --fix \"{{file}}\" --quiet || node -e \"process.exit(0)\"';\n return cachedFormatCommand;\n } catch (_error) {\n // ESLint not found\n }\n\n // No formatter found\n // Set to undefined (not null) so we know we checked and found nothing.\n cachedFormatCommand = undefined;\n return undefined;\n};\n"],"mappings":";;;AAGA,IAAI,sBAAiD;AAErD,MAAa,uBACX,eACA,uBACG;CACH,MAAM,EAAE,YAAY,cAAc;CAClC,MAAM,EAAE,kBAAkB,cAAc;CACxC,MAAM,iBAAiB,sBAAsB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"detectFormatCommand.mjs","names":[],"sources":["../../src/detectFormatCommand.ts"],"sourcesContent":["import { getProjectRequire } from '@intlayer/config/utils';\nimport type { IntlayerConfig } from '@intlayer/types/config';\n\nlet cachedFormatCommand: string | undefined | null = null;\n\nexport const detectFormatCommand = (\n configuration: IntlayerConfig,\n projectRequireProp?: NodeJS.Require\n) => {\n const { baseDir } = configuration.system;\n const { formatCommand } = configuration.content;\n const projectRequire = projectRequireProp ?? getProjectRequire(baseDir);\n\n // Priority: Explicit configuration\n // We do not cache this because the user might change their config file active-session.\n if (formatCommand) {\n return formatCommand;\n }\n\n // Priority: Cached detection\n // If not null, we have already performed the expensive checks.\n if (cachedFormatCommand !== null) {\n return cachedFormatCommand;\n }\n\n // Perform Detection\n\n // Try Prettier\n try {\n projectRequire.resolve('prettier');\n cachedFormatCommand = 'prettier --write \"{{file}}\" --log-level silent';\n return cachedFormatCommand;\n } catch (_error) {\n // Prettier not found, continue\n }\n\n // Try Biome\n try {\n projectRequire.resolve('biome');\n cachedFormatCommand = 'biome format \"{{file}}\" --write --log-level none';\n return cachedFormatCommand;\n } catch (_error) {\n // Biome not found, continue\n }\n\n // Try ESLint\n try {\n projectRequire.resolve('eslint');\n cachedFormatCommand =\n 'eslint --fix \"{{file}}\" --quiet || node -e \"process.exit(0)\"';\n return cachedFormatCommand;\n } catch (_error) {\n // ESLint not found\n }\n\n // No formatter found\n // Set to undefined (not null) so we know we checked and found nothing.\n cachedFormatCommand = undefined;\n return undefined;\n};\n"],"mappings":";;;AAGA,IAAI,sBAAiD;AAErD,MAAa,uBACX,eACA,uBACG;CACH,MAAM,EAAE,YAAY,cAAc;CAClC,MAAM,EAAE,kBAAkB,cAAc;CACxC,MAAM,iBAAiB,sBAAsB,kBAAkB,OAAO;CAItE,IAAI,eACF,OAAO;CAKT,IAAI,wBAAwB,MAC1B,OAAO;CAMT,IAAI;EACF,eAAe,QAAQ,UAAU;EACjC,sBAAsB;EACtB,OAAO;CACT,SAAS,QAAQ,CAEjB;CAGA,IAAI;EACF,eAAe,QAAQ,OAAO;EAC9B,sBAAsB;EACtB,OAAO;CACT,SAAS,QAAQ,CAEjB;CAGA,IAAI;EACF,eAAe,QAAQ,QAAQ;EAC/B,sBACE;EACF,OAAO;CACT,SAAS,QAAQ,CAEjB;CAIA,sBAAsB;AAExB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alignBlocks.mjs","names":[],"sources":["../../../src/docReview/alignBlocks.ts"],"sourcesContent":["import { computeJaccardSimilarity } from './computeSimilarity';\nimport type { AlignmentPair, FingerprintedBlock } from './types';\n\n/**\n * Align the blocks of a base document with the blocks of its translation using a\n * Needleman–Wunsch global alignment over anchor similarity and block type.\n *\n * Because prose differs across languages, the score is weighted toward the\n * structural anchor (digits and symbols) rather than the words themselves.\n *\n * @param baseBlocks - Blocks of the base (source) document.\n * @param targetBlocks - Blocks of the target (translated) document.\n * @returns The ordered list of alignment pairs, including insertions and deletions.\n */\nexport const alignBaseAndTargetBlocks = (\n baseBlocks: FingerprintedBlock[],\n targetBlocks: FingerprintedBlock[]\n): AlignmentPair[] => {\n const baseLength = baseBlocks.length;\n const targetLength = targetBlocks.length;\n\n const scoreMatrix: number[][] = Array.from({ length: baseLength + 1 }, () =>\n Array.from({ length: targetLength + 1 }, () => 0)\n );\n const traceMatrix: ('diagonal' | 'up' | 'left')[][] = Array.from(\n { length: baseLength + 1 },\n () => Array.from({ length: targetLength + 1 }, () => 'diagonal')\n );\n\n const gapPenalty = -2;\n\n const computeMatchScore = (\n baseIndex: number,\n targetIndex: number\n ): number => {\n const baseBlock = baseBlocks[baseIndex];\n const targetBlock = targetBlocks[targetIndex];\n const typeBonus = baseBlock.type === targetBlock.type ? 2 : 0;\n const anchorSimilarity = computeJaccardSimilarity(\n baseBlock.anchorText,\n targetBlock.anchorText,\n 3\n );\n const lengthRatio =\n Math.min(baseBlock.content.length, targetBlock.content.length) /\n Math.max(baseBlock.content.length, targetBlock.content.length);\n const lengthBonus = lengthRatio > 0.75 ? 1 : 0;\n return typeBonus + lengthBonus + anchorSimilarity * 8; // weighted toward anchor similarity\n };\n\n // initialize first row and column\n for (let i = 1; i <= baseLength; i += 1) {\n scoreMatrix[i][0] = scoreMatrix[i - 1][0] + gapPenalty;\n traceMatrix[i][0] = 'up';\n }\n for (let j = 1; j <= targetLength; j += 1) {\n scoreMatrix[0][j] = scoreMatrix[0][j - 1] + gapPenalty;\n traceMatrix[0][j] = 'left';\n }\n\n // fill\n for (let i = 1; i <= baseLength; i += 1) {\n for (let j = 1; j <= targetLength; j += 1) {\n const match = scoreMatrix[i - 1][j - 1] + computeMatchScore(i - 1, j - 1);\n const deleteGap = scoreMatrix[i - 1][j] + gapPenalty;\n const insertGap = scoreMatrix[i][j - 1] + gapPenalty;\n\n const best = Math.max(match, deleteGap, insertGap);\n scoreMatrix[i][j] = best;\n traceMatrix[i][j] =\n best === match ? 'diagonal' : best === deleteGap ? 'up' : 'left';\n }\n }\n\n // traceback\n const result: AlignmentPair[] = [];\n let i = baseLength;\n let j = targetLength;\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && traceMatrix[i][j] === 'diagonal') {\n const baseIndex = i - 1;\n const targetIndex = j - 1;\n const similarityScore = computeJaccardSimilarity(\n baseBlocks[baseIndex].anchorText,\n targetBlocks[targetIndex].anchorText,\n 3\n );\n result.unshift({ baseIndex, targetIndex, similarityScore });\n i -= 1;\n j -= 1;\n } else if (i > 0 && (j === 0 || traceMatrix[i][j] === 'up')) {\n result.unshift({\n baseIndex: i - 1,\n targetIndex: null,\n similarityScore: 0,\n });\n i -= 1;\n } else if (j > 0 && (i === 0 || traceMatrix[i][j] === 'left')) {\n // target block has no corresponding base block (deleted)\n result.unshift({\n baseIndex: -1,\n targetIndex: j - 1,\n similarityScore: 0,\n });\n j -= 1;\n }\n }\n return result;\n};\n"],"mappings":";;;;;;;;;;;;;;AAcA,MAAa,4BACX,YACA,iBACoB;CACpB,MAAM,aAAa,WAAW;CAC9B,MAAM,eAAe,aAAa;CAElC,MAAM,cAA0B,MAAM,KAAK,EAAE,QAAQ,aAAa,
|
|
1
|
+
{"version":3,"file":"alignBlocks.mjs","names":[],"sources":["../../../src/docReview/alignBlocks.ts"],"sourcesContent":["import { computeJaccardSimilarity } from './computeSimilarity';\nimport type { AlignmentPair, FingerprintedBlock } from './types';\n\n/**\n * Align the blocks of a base document with the blocks of its translation using a\n * Needleman–Wunsch global alignment over anchor similarity and block type.\n *\n * Because prose differs across languages, the score is weighted toward the\n * structural anchor (digits and symbols) rather than the words themselves.\n *\n * @param baseBlocks - Blocks of the base (source) document.\n * @param targetBlocks - Blocks of the target (translated) document.\n * @returns The ordered list of alignment pairs, including insertions and deletions.\n */\nexport const alignBaseAndTargetBlocks = (\n baseBlocks: FingerprintedBlock[],\n targetBlocks: FingerprintedBlock[]\n): AlignmentPair[] => {\n const baseLength = baseBlocks.length;\n const targetLength = targetBlocks.length;\n\n const scoreMatrix: number[][] = Array.from({ length: baseLength + 1 }, () =>\n Array.from({ length: targetLength + 1 }, () => 0)\n );\n const traceMatrix: ('diagonal' | 'up' | 'left')[][] = Array.from(\n { length: baseLength + 1 },\n () => Array.from({ length: targetLength + 1 }, () => 'diagonal')\n );\n\n const gapPenalty = -2;\n\n const computeMatchScore = (\n baseIndex: number,\n targetIndex: number\n ): number => {\n const baseBlock = baseBlocks[baseIndex];\n const targetBlock = targetBlocks[targetIndex];\n const typeBonus = baseBlock.type === targetBlock.type ? 2 : 0;\n const anchorSimilarity = computeJaccardSimilarity(\n baseBlock.anchorText,\n targetBlock.anchorText,\n 3\n );\n const lengthRatio =\n Math.min(baseBlock.content.length, targetBlock.content.length) /\n Math.max(baseBlock.content.length, targetBlock.content.length);\n const lengthBonus = lengthRatio > 0.75 ? 1 : 0;\n return typeBonus + lengthBonus + anchorSimilarity * 8; // weighted toward anchor similarity\n };\n\n // initialize first row and column\n for (let i = 1; i <= baseLength; i += 1) {\n scoreMatrix[i][0] = scoreMatrix[i - 1][0] + gapPenalty;\n traceMatrix[i][0] = 'up';\n }\n for (let j = 1; j <= targetLength; j += 1) {\n scoreMatrix[0][j] = scoreMatrix[0][j - 1] + gapPenalty;\n traceMatrix[0][j] = 'left';\n }\n\n // fill\n for (let i = 1; i <= baseLength; i += 1) {\n for (let j = 1; j <= targetLength; j += 1) {\n const match = scoreMatrix[i - 1][j - 1] + computeMatchScore(i - 1, j - 1);\n const deleteGap = scoreMatrix[i - 1][j] + gapPenalty;\n const insertGap = scoreMatrix[i][j - 1] + gapPenalty;\n\n const best = Math.max(match, deleteGap, insertGap);\n scoreMatrix[i][j] = best;\n traceMatrix[i][j] =\n best === match ? 'diagonal' : best === deleteGap ? 'up' : 'left';\n }\n }\n\n // traceback\n const result: AlignmentPair[] = [];\n let i = baseLength;\n let j = targetLength;\n while (i > 0 || j > 0) {\n if (i > 0 && j > 0 && traceMatrix[i][j] === 'diagonal') {\n const baseIndex = i - 1;\n const targetIndex = j - 1;\n const similarityScore = computeJaccardSimilarity(\n baseBlocks[baseIndex].anchorText,\n targetBlocks[targetIndex].anchorText,\n 3\n );\n result.unshift({ baseIndex, targetIndex, similarityScore });\n i -= 1;\n j -= 1;\n } else if (i > 0 && (j === 0 || traceMatrix[i][j] === 'up')) {\n result.unshift({\n baseIndex: i - 1,\n targetIndex: null,\n similarityScore: 0,\n });\n i -= 1;\n } else if (j > 0 && (i === 0 || traceMatrix[i][j] === 'left')) {\n // target block has no corresponding base block (deleted)\n result.unshift({\n baseIndex: -1,\n targetIndex: j - 1,\n similarityScore: 0,\n });\n j -= 1;\n }\n }\n return result;\n};\n"],"mappings":";;;;;;;;;;;;;;AAcA,MAAa,4BACX,YACA,iBACoB;CACpB,MAAM,aAAa,WAAW;CAC9B,MAAM,eAAe,aAAa;CAElC,MAAM,cAA0B,MAAM,KAAK,EAAE,QAAQ,aAAa,EAAE,SAClE,MAAM,KAAK,EAAE,QAAQ,eAAe,EAAE,SAAS,CAAC,CAClD;CACA,MAAM,cAAgD,MAAM,KAC1D,EAAE,QAAQ,aAAa,EAAE,SACnB,MAAM,KAAK,EAAE,QAAQ,eAAe,EAAE,SAAS,UAAU,CACjE;CAEA,MAAM,aAAa;CAEnB,MAAM,qBACJ,WACA,gBACW;EACX,MAAM,YAAY,WAAW;EAC7B,MAAM,cAAc,aAAa;EACjC,MAAM,YAAY,UAAU,SAAS,YAAY,OAAO,IAAI;EAC5D,MAAM,mBAAmB,yBACvB,UAAU,YACV,YAAY,YACZ,CACF;EAKA,OAAO,aAHL,KAAK,IAAI,UAAU,QAAQ,QAAQ,YAAY,QAAQ,MAAM,IAC7D,KAAK,IAAI,UAAU,QAAQ,QAAQ,YAAY,QAAQ,MAAM,IAC7B,MAAO,IAAI,KACZ,mBAAmB;CACtD;CAGA,KAAK,IAAI,IAAI,GAAG,KAAK,YAAY,KAAK,GAAG;EACvC,YAAY,EAAE,CAAC,KAAK,YAAY,IAAI,EAAE,CAAC,KAAK;EAC5C,YAAY,EAAE,CAAC,KAAK;CACtB;CACA,KAAK,IAAI,IAAI,GAAG,KAAK,cAAc,KAAK,GAAG;EACzC,YAAY,EAAE,CAAC,KAAK,YAAY,EAAE,CAAC,IAAI,KAAK;EAC5C,YAAY,EAAE,CAAC,KAAK;CACtB;CAGA,KAAK,IAAI,IAAI,GAAG,KAAK,YAAY,KAAK,GACpC,KAAK,IAAI,IAAI,GAAG,KAAK,cAAc,KAAK,GAAG;EACzC,MAAM,QAAQ,YAAY,IAAI,EAAE,CAAC,IAAI,KAAK,kBAAkB,IAAI,GAAG,IAAI,CAAC;EACxE,MAAM,YAAY,YAAY,IAAI,EAAE,CAAC,KAAK;EAC1C,MAAM,YAAY,YAAY,EAAE,CAAC,IAAI,KAAK;EAE1C,MAAM,OAAO,KAAK,IAAI,OAAO,WAAW,SAAS;EACjD,YAAY,EAAE,CAAC,KAAK;EACpB,YAAY,EAAE,CAAC,KACb,SAAS,QAAQ,aAAa,SAAS,YAAY,OAAO;CAC9D;CAIF,MAAM,SAA0B,CAAC;CACjC,IAAI,IAAI;CACR,IAAI,IAAI;CACR,OAAO,IAAI,KAAK,IAAI,GAClB,IAAI,IAAI,KAAK,IAAI,KAAK,YAAY,EAAE,CAAC,OAAO,YAAY;EACtD,MAAM,YAAY,IAAI;EACtB,MAAM,cAAc,IAAI;EACxB,MAAM,kBAAkB,yBACtB,WAAW,UAAU,CAAC,YACtB,aAAa,YAAY,CAAC,YAC1B,CACF;EACA,OAAO,QAAQ;GAAE;GAAW;GAAa;EAAgB,CAAC;EAC1D,KAAK;EACL,KAAK;CACP,OAAO,IAAI,IAAI,MAAM,MAAM,KAAK,YAAY,EAAE,CAAC,OAAO,OAAO;EAC3D,OAAO,QAAQ;GACb,WAAW,IAAI;GACf,aAAa;GACb,iBAAiB;EACnB,CAAC;EACD,KAAK;CACP,OAAO,IAAI,IAAI,MAAM,MAAM,KAAK,YAAY,EAAE,CAAC,OAAO,SAAS;EAE7D,OAAO,QAAQ;GACb,WAAW;GACX,aAAa,IAAI;GACjB,iBAAiB;EACnB,CAAC;EACD,KAAK;CACP;CAEF,OAAO;AACT"}
|
|
@@ -30,7 +30,7 @@ const computeJaccardSimilarity = (a, b, shingleLength = 3) => {
|
|
|
30
30
|
const setB = generateCharacterShingles(b, shingleLength);
|
|
31
31
|
if (setA.size === 0 && setB.size === 0) return 1;
|
|
32
32
|
const intersectionSize = Array.from(setA).filter((token) => setB.has(token)).length;
|
|
33
|
-
const unionSize = new Set([...Array.from(setA), ...Array.from(setB)]).size;
|
|
33
|
+
const unionSize = (/* @__PURE__ */ new Set([...Array.from(setA), ...Array.from(setB)])).size;
|
|
34
34
|
return unionSize === 0 ? 0 : intersectionSize / unionSize;
|
|
35
35
|
};
|
|
36
36
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"computeSimilarity.mjs","names":[],"sources":["../../../src/docReview/computeSimilarity.ts"],"sourcesContent":["/**\n * Generate the set of character shingles (substrings of a fixed length) for a\n * piece of text. Whitespace is collapsed so the result is language agnostic.\n *\n * @param text - The text to shingle.\n * @param shingleLength - The length of each shingle.\n * @returns The set of unique shingles found in the text.\n */\nexport const generateCharacterShingles = (\n text: string,\n shingleLength: number\n): Set<string> => {\n const normalized = text.replace(/\\s+/g, ' ').trim();\n const set = new Set<string>();\n if (normalized.length < shingleLength) {\n if (normalized.length > 0) {\n set.add(normalized);\n }\n return set;\n }\n for (let index = 0; index <= normalized.length - shingleLength; index += 1) {\n set.add(normalized.slice(index, index + shingleLength));\n }\n return set;\n};\n\n/**\n * Compute the Jaccard similarity between two strings using character shingles.\n *\n * @param a - First string.\n * @param b - Second string.\n * @param shingleLength - The shingle length (defaults to 3).\n * @returns A score between 0 (disjoint) and 1 (identical).\n */\nexport const computeJaccardSimilarity = (\n a: string,\n b: string,\n shingleLength: number = 3\n): number => {\n const setA = generateCharacterShingles(a, shingleLength);\n const setB = generateCharacterShingles(b, shingleLength);\n if (setA.size === 0 && setB.size === 0) return 1;\n const intersectionSize = Array.from(setA).filter((token) =>\n setB.has(token)\n ).length;\n const unionSize = new Set([...Array.from(setA), ...Array.from(setB)]).size;\n return unionSize === 0 ? 0 : intersectionSize / unionSize;\n};\n"],"mappings":";;;;;;;;;AAQA,MAAa,6BACX,MACA,kBACgB;CAChB,MAAM,aAAa,KAAK,QAAQ,QAAQ,
|
|
1
|
+
{"version":3,"file":"computeSimilarity.mjs","names":[],"sources":["../../../src/docReview/computeSimilarity.ts"],"sourcesContent":["/**\n * Generate the set of character shingles (substrings of a fixed length) for a\n * piece of text. Whitespace is collapsed so the result is language agnostic.\n *\n * @param text - The text to shingle.\n * @param shingleLength - The length of each shingle.\n * @returns The set of unique shingles found in the text.\n */\nexport const generateCharacterShingles = (\n text: string,\n shingleLength: number\n): Set<string> => {\n const normalized = text.replace(/\\s+/g, ' ').trim();\n const set = new Set<string>();\n if (normalized.length < shingleLength) {\n if (normalized.length > 0) {\n set.add(normalized);\n }\n return set;\n }\n for (let index = 0; index <= normalized.length - shingleLength; index += 1) {\n set.add(normalized.slice(index, index + shingleLength));\n }\n return set;\n};\n\n/**\n * Compute the Jaccard similarity between two strings using character shingles.\n *\n * @param a - First string.\n * @param b - Second string.\n * @param shingleLength - The shingle length (defaults to 3).\n * @returns A score between 0 (disjoint) and 1 (identical).\n */\nexport const computeJaccardSimilarity = (\n a: string,\n b: string,\n shingleLength: number = 3\n): number => {\n const setA = generateCharacterShingles(a, shingleLength);\n const setB = generateCharacterShingles(b, shingleLength);\n if (setA.size === 0 && setB.size === 0) return 1;\n const intersectionSize = Array.from(setA).filter((token) =>\n setB.has(token)\n ).length;\n const unionSize = new Set([...Array.from(setA), ...Array.from(setB)]).size;\n return unionSize === 0 ? 0 : intersectionSize / unionSize;\n};\n"],"mappings":";;;;;;;;;AAQA,MAAa,6BACX,MACA,kBACgB;CAChB,MAAM,aAAa,KAAK,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK;CAClD,MAAM,sBAAM,IAAI,IAAY;CAC5B,IAAI,WAAW,SAAS,eAAe;EACrC,IAAI,WAAW,SAAS,GACtB,IAAI,IAAI,UAAU;EAEpB,OAAO;CACT;CACA,KAAK,IAAI,QAAQ,GAAG,SAAS,WAAW,SAAS,eAAe,SAAS,GACvE,IAAI,IAAI,WAAW,MAAM,OAAO,QAAQ,aAAa,CAAC;CAExD,OAAO;AACT;;;;;;;;;AAUA,MAAa,4BACX,GACA,GACA,gBAAwB,MACb;CACX,MAAM,OAAO,0BAA0B,GAAG,aAAa;CACvD,MAAM,OAAO,0BAA0B,GAAG,aAAa;CACvD,IAAI,KAAK,SAAS,KAAK,KAAK,SAAS,GAAG,OAAO;CAC/C,MAAM,mBAAmB,MAAM,KAAK,IAAI,CAAC,CAAC,QAAQ,UAChD,KAAK,IAAI,KAAK,CAChB,CAAC,CAAC;CACF,MAAM,6BAAY,IAAI,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,GAAG,GAAG,MAAM,KAAK,IAAI,CAAC,CAAC,EAAC,CAAC;CACtE,OAAO,cAAc,IAAI,IAAI,mBAAmB;AAClD"}
|
|
@@ -17,7 +17,9 @@ const fingerprintBlock = (block, previousBlock, nextBlock) => {
|
|
|
17
17
|
const semanticDigest = computeStringDigest(block.semanticText);
|
|
18
18
|
const anchorDigest = computeStringDigest(block.anchorText);
|
|
19
19
|
const compositeKey = `${semanticDigest}:${anchorDigest}`;
|
|
20
|
-
const
|
|
20
|
+
const previousDigest = computeStringDigest(previousBlock?.semanticText ?? "");
|
|
21
|
+
const nextDigest = computeStringDigest(nextBlock?.semanticText ?? "");
|
|
22
|
+
const contextKey = computeStringDigest(`${previousDigest}:${nextDigest}`);
|
|
21
23
|
return {
|
|
22
24
|
...block,
|
|
23
25
|
semanticDigest,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fingerprintBlock.mjs","names":[],"sources":["../../../src/docReview/fingerprintBlock.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport type { FingerprintedBlock, NormalizedBlock } from './types';\n\nconst computeStringDigest = (text: string): string =>\n crypto.createHash('sha256').update(text).digest('hex');\n\n/**\n * Compute content and context digests for a normalized block.\n *\n * The context key (digest of the surrounding blocks) lets the planner tell apart\n * two blocks that share the same content but live in different sections.\n *\n * @param block - The block to fingerprint.\n * @param previousBlock - The block immediately before, or `null` at the start.\n * @param nextBlock - The block immediately after, or `null` at the end.\n * @returns The block enriched with its digests.\n */\nexport const fingerprintBlock = (\n block: NormalizedBlock,\n previousBlock: NormalizedBlock | null,\n nextBlock: NormalizedBlock | null\n): FingerprintedBlock => {\n const semanticDigest = computeStringDigest(block.semanticText);\n const anchorDigest = computeStringDigest(block.anchorText);\n const compositeKey = `${semanticDigest}:${anchorDigest}`;\n\n const previousDigest = computeStringDigest(previousBlock?.semanticText ?? '');\n const nextDigest = computeStringDigest(nextBlock?.semanticText ?? '');\n const contextKey = computeStringDigest(`${previousDigest}:${nextDigest}`);\n\n return {\n ...block,\n semanticDigest,\n anchorDigest,\n compositeKey,\n contextKey,\n };\n};\n"],"mappings":";;;AAGA,MAAM,uBAAuB,SAC3B,OAAO,WAAW,
|
|
1
|
+
{"version":3,"file":"fingerprintBlock.mjs","names":[],"sources":["../../../src/docReview/fingerprintBlock.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport type { FingerprintedBlock, NormalizedBlock } from './types';\n\nconst computeStringDigest = (text: string): string =>\n crypto.createHash('sha256').update(text).digest('hex');\n\n/**\n * Compute content and context digests for a normalized block.\n *\n * The context key (digest of the surrounding blocks) lets the planner tell apart\n * two blocks that share the same content but live in different sections.\n *\n * @param block - The block to fingerprint.\n * @param previousBlock - The block immediately before, or `null` at the start.\n * @param nextBlock - The block immediately after, or `null` at the end.\n * @returns The block enriched with its digests.\n */\nexport const fingerprintBlock = (\n block: NormalizedBlock,\n previousBlock: NormalizedBlock | null,\n nextBlock: NormalizedBlock | null\n): FingerprintedBlock => {\n const semanticDigest = computeStringDigest(block.semanticText);\n const anchorDigest = computeStringDigest(block.anchorText);\n const compositeKey = `${semanticDigest}:${anchorDigest}`;\n\n const previousDigest = computeStringDigest(previousBlock?.semanticText ?? '');\n const nextDigest = computeStringDigest(nextBlock?.semanticText ?? '');\n const contextKey = computeStringDigest(`${previousDigest}:${nextDigest}`);\n\n return {\n ...block,\n semanticDigest,\n anchorDigest,\n compositeKey,\n contextKey,\n };\n};\n"],"mappings":";;;AAGA,MAAM,uBAAuB,SAC3B,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK;;;;;;;;;;;;AAavD,MAAa,oBACX,OACA,eACA,cACuB;CACvB,MAAM,iBAAiB,oBAAoB,MAAM,YAAY;CAC7D,MAAM,eAAe,oBAAoB,MAAM,UAAU;CACzD,MAAM,eAAe,GAAG,eAAe,GAAG;CAE1C,MAAM,iBAAiB,oBAAoB,eAAe,gBAAgB,EAAE;CAC5E,MAAM,aAAa,oBAAoB,WAAW,gBAAgB,EAAE;CACpE,MAAM,aAAa,oBAAoB,GAAG,eAAe,GAAG,YAAY;CAExE,OAAO;EACL,GAAG;EACH;EACA;EACA;EACA;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapChangedLinesToBlocks.mjs","names":[],"sources":["../../../src/docReview/mapChangedLinesToBlocks.ts"],"sourcesContent":["import type { Block, LineChange } from './types';\n\n/**\n * Map a set of changed line numbers onto the indexes of the blocks that contain\n * them.\n *\n * @param blocks - The ordered blocks of the base document.\n * @param changedLines - 1-based line numbers that changed in the base document.\n * @returns The set of block indexes touched by at least one changed line.\n */\nexport const mapChangedLinesToBlocks = (\n blocks: Block[],\n changedLines: LineChange[]\n): Set<number> => {\n const changedSet = new Set<number>();\n if (!changedLines || changedLines.length === 0) return changedSet;\n\n const changedLookup = new Set<number>(changedLines);\n\n blocks.forEach((block, index) => {\n for (let line = block.lineStart; line <= block.lineEnd; line += 1) {\n if (changedLookup.has(line)) {\n changedSet.add(index);\n break;\n }\n }\n });\n\n return changedSet;\n};\n"],"mappings":";;;;;;;;;AAUA,MAAa,2BACX,QACA,iBACgB;CAChB,MAAM,6BAAa,IAAI,
|
|
1
|
+
{"version":3,"file":"mapChangedLinesToBlocks.mjs","names":[],"sources":["../../../src/docReview/mapChangedLinesToBlocks.ts"],"sourcesContent":["import type { Block, LineChange } from './types';\n\n/**\n * Map a set of changed line numbers onto the indexes of the blocks that contain\n * them.\n *\n * @param blocks - The ordered blocks of the base document.\n * @param changedLines - 1-based line numbers that changed in the base document.\n * @returns The set of block indexes touched by at least one changed line.\n */\nexport const mapChangedLinesToBlocks = (\n blocks: Block[],\n changedLines: LineChange[]\n): Set<number> => {\n const changedSet = new Set<number>();\n if (!changedLines || changedLines.length === 0) return changedSet;\n\n const changedLookup = new Set<number>(changedLines);\n\n blocks.forEach((block, index) => {\n for (let line = block.lineStart; line <= block.lineEnd; line += 1) {\n if (changedLookup.has(line)) {\n changedSet.add(index);\n break;\n }\n }\n });\n\n return changedSet;\n};\n"],"mappings":";;;;;;;;;AAUA,MAAa,2BACX,QACA,iBACgB;CAChB,MAAM,6BAAa,IAAI,IAAY;CACnC,IAAI,CAAC,gBAAgB,aAAa,WAAW,GAAG,OAAO;CAEvD,MAAM,gBAAgB,IAAI,IAAY,YAAY;CAElD,OAAO,SAAS,OAAO,UAAU;EAC/B,KAAK,IAAI,OAAO,MAAM,WAAW,QAAQ,MAAM,SAAS,QAAQ,GAC9D,IAAI,cAAc,IAAI,IAAI,GAAG;GAC3B,WAAW,IAAI,KAAK;GACpB;EACF;CAEJ,CAAC;CAED,OAAO;AACT"}
|
|
@@ -18,8 +18,10 @@ const stripLettersKeepDigitsAndSymbols = (text) => {
|
|
|
18
18
|
* @returns The block enriched with its normalized texts.
|
|
19
19
|
*/
|
|
20
20
|
const normalizeBlock = (block) => {
|
|
21
|
-
const
|
|
22
|
-
const
|
|
21
|
+
const semanticLowercased = removeMarkdownFormatting(block.content).toLowerCase();
|
|
22
|
+
const semanticCollapsed = collapseWhitespace(semanticLowercased);
|
|
23
|
+
const anchorOnlySymbols = stripLettersKeepDigitsAndSymbols(block.content);
|
|
24
|
+
const anchorCollapsed = collapseWhitespace(anchorOnlySymbols);
|
|
23
25
|
return {
|
|
24
26
|
...block,
|
|
25
27
|
semanticText: semanticCollapsed,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalizeBlock.mjs","names":[],"sources":["../../../src/docReview/normalizeBlock.ts"],"sourcesContent":["import type { Block, NormalizedBlock } from './types';\n\nconst removeMarkdownFormatting = (text: string): string => {\n return text\n .replace(/`{1,3}[^`]*`{1,3}/g, ' ')\n .replace(/\\*\\*([^*]+)\\*\\*/g, '$1')\n .replace(/\\*([^*]+)\\*/g, '$1')\n .replace(/_([^_]+)_/g, '$1')\n .replace(/~~([^~]+)~~/g, '$1')\n .replace(/!?\\[[^\\]]*\\]\\([^)]*\\)/g, ' ')\n .replace(/^\\s*#{1,6}\\s+/gm, '')\n .replace(/^\\s*>\\s?/gm, '')\n .replace(/^\\s*[-*+]\\s+/gm, '')\n .replace(/^\\s*\\d+\\.\\s+/gm, '');\n};\n\nconst collapseWhitespace = (text: string): string =>\n text.replace(/\\s+/g, ' ').trim();\n\nconst stripLettersKeepDigitsAndSymbols = (text: string): string => {\n // Keep digits and non-letter characters, remove all letters (including accents)\n return text.replace(/\\p{L}+/gu, '');\n};\n\n/**\n * Derive the normalized representations of a block used for matching.\n *\n * - `semanticText`: markdown-stripped, lower-cased text (used to detect identical\n * content across versions of the same language).\n * - `anchorText`: only digits/symbols (used to align blocks across languages, as\n * prose differs but structure such as numbers and punctuation is preserved).\n *\n * @param block - The block to normalize.\n * @returns The block enriched with its normalized texts.\n */\nexport const normalizeBlock = (block: Block): NormalizedBlock => {\n const contentWithoutMarkdown = removeMarkdownFormatting(block.content);\n const semanticLowercased = contentWithoutMarkdown.toLowerCase();\n const semanticCollapsed = collapseWhitespace(semanticLowercased);\n\n const anchorOnlySymbols = stripLettersKeepDigitsAndSymbols(block.content);\n const anchorCollapsed = collapseWhitespace(anchorOnlySymbols);\n\n return {\n ...block,\n semanticText: semanticCollapsed,\n anchorText: anchorCollapsed,\n };\n};\n"],"mappings":";AAEA,MAAM,4BAA4B,SAAyB;
|
|
1
|
+
{"version":3,"file":"normalizeBlock.mjs","names":[],"sources":["../../../src/docReview/normalizeBlock.ts"],"sourcesContent":["import type { Block, NormalizedBlock } from './types';\n\nconst removeMarkdownFormatting = (text: string): string => {\n return text\n .replace(/`{1,3}[^`]*`{1,3}/g, ' ')\n .replace(/\\*\\*([^*]+)\\*\\*/g, '$1')\n .replace(/\\*([^*]+)\\*/g, '$1')\n .replace(/_([^_]+)_/g, '$1')\n .replace(/~~([^~]+)~~/g, '$1')\n .replace(/!?\\[[^\\]]*\\]\\([^)]*\\)/g, ' ')\n .replace(/^\\s*#{1,6}\\s+/gm, '')\n .replace(/^\\s*>\\s?/gm, '')\n .replace(/^\\s*[-*+]\\s+/gm, '')\n .replace(/^\\s*\\d+\\.\\s+/gm, '');\n};\n\nconst collapseWhitespace = (text: string): string =>\n text.replace(/\\s+/g, ' ').trim();\n\nconst stripLettersKeepDigitsAndSymbols = (text: string): string => {\n // Keep digits and non-letter characters, remove all letters (including accents)\n return text.replace(/\\p{L}+/gu, '');\n};\n\n/**\n * Derive the normalized representations of a block used for matching.\n *\n * - `semanticText`: markdown-stripped, lower-cased text (used to detect identical\n * content across versions of the same language).\n * - `anchorText`: only digits/symbols (used to align blocks across languages, as\n * prose differs but structure such as numbers and punctuation is preserved).\n *\n * @param block - The block to normalize.\n * @returns The block enriched with its normalized texts.\n */\nexport const normalizeBlock = (block: Block): NormalizedBlock => {\n const contentWithoutMarkdown = removeMarkdownFormatting(block.content);\n const semanticLowercased = contentWithoutMarkdown.toLowerCase();\n const semanticCollapsed = collapseWhitespace(semanticLowercased);\n\n const anchorOnlySymbols = stripLettersKeepDigitsAndSymbols(block.content);\n const anchorCollapsed = collapseWhitespace(anchorOnlySymbols);\n\n return {\n ...block,\n semanticText: semanticCollapsed,\n anchorText: anchorCollapsed,\n };\n};\n"],"mappings":";AAEA,MAAM,4BAA4B,SAAyB;CACzD,OAAO,KACJ,QAAQ,sBAAsB,GAAG,CAAC,CAClC,QAAQ,oBAAoB,IAAI,CAAC,CACjC,QAAQ,gBAAgB,IAAI,CAAC,CAC7B,QAAQ,cAAc,IAAI,CAAC,CAC3B,QAAQ,gBAAgB,IAAI,CAAC,CAC7B,QAAQ,0BAA0B,GAAG,CAAC,CACtC,QAAQ,mBAAmB,EAAE,CAAC,CAC9B,QAAQ,cAAc,EAAE,CAAC,CACzB,QAAQ,kBAAkB,EAAE,CAAC,CAC7B,QAAQ,kBAAkB,EAAE;AACjC;AAEA,MAAM,sBAAsB,SAC1B,KAAK,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK;AAEjC,MAAM,oCAAoC,SAAyB;CAEjE,OAAO,KAAK,QAAQ,YAAY,EAAE;AACpC;;;;;;;;;;;;AAaA,MAAa,kBAAkB,UAAkC;CAE/D,MAAM,qBADyB,yBAAyB,MAAM,OACd,CAAC,CAAC,YAAY;CAC9D,MAAM,oBAAoB,mBAAmB,kBAAkB;CAE/D,MAAM,oBAAoB,iCAAiC,MAAM,OAAO;CACxE,MAAM,kBAAkB,mBAAmB,iBAAiB;CAE5D,OAAO;EACL,GAAG;EACH,cAAc;EACd,YAAY;CACd;AACF"}
|
|
@@ -17,11 +17,12 @@ const fingerprintBlockList = (blocks) => {
|
|
|
17
17
|
*/
|
|
18
18
|
const fingerprintSectionFineBlocks = (section) => {
|
|
19
19
|
const lineOffset = section.lineStart - 1;
|
|
20
|
-
|
|
20
|
+
const fineBlocks = segmentDocument(section.content).map((block) => ({
|
|
21
21
|
...block,
|
|
22
22
|
lineStart: block.lineStart + lineOffset,
|
|
23
23
|
lineEnd: block.lineEnd + lineOffset
|
|
24
|
-
}))
|
|
24
|
+
}));
|
|
25
|
+
return fingerprintBlockList(fineBlocks);
|
|
25
26
|
};
|
|
26
27
|
/**
|
|
27
28
|
* Build the block-aware alignment plan between a base document and its
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.mjs","names":[],"sources":["../../../src/docReview/pipeline.ts"],"sourcesContent":["import { alignBaseAndTargetBlocks } from './alignBlocks';\nimport { fingerprintBlock } from './fingerprintBlock';\nimport { mapChangedLinesToBlocks } from './mapChangedLinesToBlocks';\nimport { normalizeBlock } from './normalizeBlock';\nimport {\n identifySegmentsToReview,\n mergeReviewedSegments,\n type SegmentToReview,\n} from './rebuildDocument';\nimport { segmentDocument, segmentSections } from './segmentDocument';\nimport type { Block, FingerprintedBlock, PlannedAction } from './types';\n\nexport type BuildAlignmentPlanInput = {\n /** The base (source) document, used as the translation reference. */\n baseText: string;\n /** The existing target (translated) document, possibly empty. */\n targetText: string;\n /** 1-based line numbers that changed in the base document, when known. */\n changedLines: number[] | undefined;\n};\n\nexport type BuildAlignmentPlanOutput = {\n baseBlocks: FingerprintedBlock[];\n targetBlocks: FingerprintedBlock[];\n plan: AlignmentPlan;\n segmentsToReview: SegmentToReview[];\n};\n\n/** Fingerprint a list of already-segmented blocks (context = neighbours). */\nconst fingerprintBlockList = (blocks: Block[]): FingerprintedBlock[] => {\n const normalized = blocks.map(normalizeBlock);\n\n return normalized.map((block, index, array) =>\n fingerprintBlock(block, array[index - 1] ?? null, array[index + 1] ?? null)\n );\n};\n\n/**\n * Re-segment a section's own text into fine blocks, shifting their relative line\n * numbers back to absolute document positions so changed-line mapping and the\n * review report keep reporting real file coordinates.\n */\nconst fingerprintSectionFineBlocks = (section: Block): FingerprintedBlock[] => {\n const lineOffset = section.lineStart - 1;\n\n const fineBlocks = segmentDocument(section.content).map(\n (block): Block => ({\n ...block,\n lineStart: block.lineStart + lineOffset,\n lineEnd: block.lineEnd + lineOffset,\n })\n );\n\n return fingerprintBlockList(fineBlocks);\n};\n\n/**\n * Build the block-aware alignment plan between a base document and its\n * translation, in two levels.\n *\n * 1. **Sections** (heading-anchored) are aligned first. Because a document and\n * its translation share the same heading structure, this alignment is robust\n * and never drops a section just because the prose was split into a different\n * number of paragraphs.\n * 2. Only the sections **touched by a changed line** are then re-segmented into\n * fine blocks (paragraphs, code fences) and aligned within the section, so a\n * small edit re-translates only the affected paragraph(s) instead of the\n * whole section. Within a changed section a target block with no base\n * counterpart is **kept as-is** (reused) rather than deleted, so a translation\n * that has extra paragraphs never loses content.\n *\n * Section-level insertions and deletions stay whole: a brand-new section is\n * translated as one unit, and a target section with no base counterpart is\n * reported as `delete` for visibility but never dropped by the merge (see\n * {@link mergeReviewedSegments}), so a review can never lose translated content.\n *\n * @param input - The base/target texts and optional changed lines.\n * @returns The (flattened) blocks, the plan, and the segments that need translation.\n */\nexport const buildAlignmentPlan = ({\n baseText,\n targetText,\n changedLines,\n}: BuildAlignmentPlanInput): BuildAlignmentPlanOutput => {\n const changedLineNumbers = Array.isArray(changedLines) ? changedLines : [];\n\n const baseSections = fingerprintBlockList(segmentSections(baseText));\n const targetSections = fingerprintBlockList(segmentSections(targetText));\n\n const sectionAlignment = alignBaseAndTargetBlocks(\n baseSections,\n targetSections\n );\n const changedSectionIndexes = mapChangedLinesToBlocks(\n baseSections,\n changedLineNumbers\n );\n\n // Flattened blocks the plan refers to by index. Reused/deleted/inserted\n // sections contribute their whole-section block; changed sections contribute\n // their fine sub-blocks.\n const baseBlocks: FingerprintedBlock[] = [];\n const targetBlocks: FingerprintedBlock[] = [];\n const actions: PlannedAction[] = [];\n\n const pushBaseBlock = (block: FingerprintedBlock): number =>\n baseBlocks.push(block) - 1;\n const pushTargetBlock = (block: FingerprintedBlock): number =>\n targetBlocks.push(block) - 1;\n\n for (const pair of sectionAlignment) {\n // Section present only in the target → reported as `delete` for visibility,\n // but kept verbatim by the merge (the aligner may simply have failed to\n // follow a reordered section), never silently dropped.\n if (pair.baseIndex === -1 && pair.targetIndex !== null) {\n const targetIndex = pushTargetBlock(targetSections[pair.targetIndex]!);\n actions.push({ kind: 'delete', targetIndex });\n continue;\n }\n\n // Section present only in the base → brand new, translate as one unit.\n if (pair.baseIndex >= 0 && pair.targetIndex === null) {\n const baseIndex = pushBaseBlock(baseSections[pair.baseIndex]!);\n actions.push({ kind: 'insert_new', baseIndex });\n continue;\n }\n\n if (pair.baseIndex < 0 || pair.targetIndex === null) continue;\n\n const baseSection = baseSections[pair.baseIndex]!;\n const targetSection = targetSections[pair.targetIndex]!;\n\n // Unchanged section → reuse the existing translation verbatim.\n if (!changedSectionIndexes.has(pair.baseIndex)) {\n const baseIndex = pushBaseBlock(baseSection);\n const targetIndex = pushTargetBlock(targetSection);\n actions.push({ kind: 'reuse', baseIndex, targetIndex });\n continue;\n }\n\n // Changed section → align its fine blocks and review only what changed.\n const baseFineBlocks = fingerprintSectionFineBlocks(baseSection);\n const targetFineBlocks = fingerprintSectionFineBlocks(targetSection);\n const fineAlignment = alignBaseAndTargetBlocks(\n baseFineBlocks,\n targetFineBlocks\n );\n const changedFineIndexes = mapChangedLinesToBlocks(\n baseFineBlocks,\n changedLineNumbers\n );\n\n for (const finePair of fineAlignment) {\n // Target-only fine block: keep it (no data loss), do not delete.\n if (finePair.baseIndex === -1 && finePair.targetIndex !== null) {\n const targetIndex = pushTargetBlock(\n targetFineBlocks[finePair.targetIndex]!\n );\n actions.push({ kind: 'reuse', baseIndex: -1, targetIndex });\n continue;\n }\n\n // Base-only fine block: a new paragraph inside the section, translate it.\n if (finePair.baseIndex >= 0 && finePair.targetIndex === null) {\n const baseIndex = pushBaseBlock(baseFineBlocks[finePair.baseIndex]!);\n actions.push({ kind: 'insert_new', baseIndex });\n continue;\n }\n\n if (finePair.baseIndex < 0 || finePair.targetIndex === null) continue;\n\n const baseIndex = pushBaseBlock(baseFineBlocks[finePair.baseIndex]!);\n const targetIndex = pushTargetBlock(\n targetFineBlocks[finePair.targetIndex]!\n );\n\n actions.push(\n changedFineIndexes.has(finePair.baseIndex)\n ? { kind: 'review', baseIndex, targetIndex }\n : { kind: 'reuse', baseIndex, targetIndex }\n );\n }\n }\n\n const plan = { actions };\n\n const { segmentsToReview } = identifySegmentsToReview({\n baseBlocks,\n targetBlocks,\n plan,\n });\n\n return { baseBlocks, targetBlocks, plan, segmentsToReview };\n};\n\nexport type { SegmentToReview };\nexport { mergeReviewedSegments };\n"],"mappings":";;;;;;;;;AA6BA,MAAM,wBAAwB,WAA0C;
|
|
1
|
+
{"version":3,"file":"pipeline.mjs","names":[],"sources":["../../../src/docReview/pipeline.ts"],"sourcesContent":["import { alignBaseAndTargetBlocks } from './alignBlocks';\nimport { fingerprintBlock } from './fingerprintBlock';\nimport { mapChangedLinesToBlocks } from './mapChangedLinesToBlocks';\nimport { normalizeBlock } from './normalizeBlock';\nimport {\n identifySegmentsToReview,\n mergeReviewedSegments,\n type SegmentToReview,\n} from './rebuildDocument';\nimport { segmentDocument, segmentSections } from './segmentDocument';\nimport type { Block, FingerprintedBlock, PlannedAction } from './types';\n\nexport type BuildAlignmentPlanInput = {\n /** The base (source) document, used as the translation reference. */\n baseText: string;\n /** The existing target (translated) document, possibly empty. */\n targetText: string;\n /** 1-based line numbers that changed in the base document, when known. */\n changedLines: number[] | undefined;\n};\n\nexport type BuildAlignmentPlanOutput = {\n baseBlocks: FingerprintedBlock[];\n targetBlocks: FingerprintedBlock[];\n plan: AlignmentPlan;\n segmentsToReview: SegmentToReview[];\n};\n\n/** Fingerprint a list of already-segmented blocks (context = neighbours). */\nconst fingerprintBlockList = (blocks: Block[]): FingerprintedBlock[] => {\n const normalized = blocks.map(normalizeBlock);\n\n return normalized.map((block, index, array) =>\n fingerprintBlock(block, array[index - 1] ?? null, array[index + 1] ?? null)\n );\n};\n\n/**\n * Re-segment a section's own text into fine blocks, shifting their relative line\n * numbers back to absolute document positions so changed-line mapping and the\n * review report keep reporting real file coordinates.\n */\nconst fingerprintSectionFineBlocks = (section: Block): FingerprintedBlock[] => {\n const lineOffset = section.lineStart - 1;\n\n const fineBlocks = segmentDocument(section.content).map(\n (block): Block => ({\n ...block,\n lineStart: block.lineStart + lineOffset,\n lineEnd: block.lineEnd + lineOffset,\n })\n );\n\n return fingerprintBlockList(fineBlocks);\n};\n\n/**\n * Build the block-aware alignment plan between a base document and its\n * translation, in two levels.\n *\n * 1. **Sections** (heading-anchored) are aligned first. Because a document and\n * its translation share the same heading structure, this alignment is robust\n * and never drops a section just because the prose was split into a different\n * number of paragraphs.\n * 2. Only the sections **touched by a changed line** are then re-segmented into\n * fine blocks (paragraphs, code fences) and aligned within the section, so a\n * small edit re-translates only the affected paragraph(s) instead of the\n * whole section. Within a changed section a target block with no base\n * counterpart is **kept as-is** (reused) rather than deleted, so a translation\n * that has extra paragraphs never loses content.\n *\n * Section-level insertions and deletions stay whole: a brand-new section is\n * translated as one unit, and a target section with no base counterpart is\n * reported as `delete` for visibility but never dropped by the merge (see\n * {@link mergeReviewedSegments}), so a review can never lose translated content.\n *\n * @param input - The base/target texts and optional changed lines.\n * @returns The (flattened) blocks, the plan, and the segments that need translation.\n */\nexport const buildAlignmentPlan = ({\n baseText,\n targetText,\n changedLines,\n}: BuildAlignmentPlanInput): BuildAlignmentPlanOutput => {\n const changedLineNumbers = Array.isArray(changedLines) ? changedLines : [];\n\n const baseSections = fingerprintBlockList(segmentSections(baseText));\n const targetSections = fingerprintBlockList(segmentSections(targetText));\n\n const sectionAlignment = alignBaseAndTargetBlocks(\n baseSections,\n targetSections\n );\n const changedSectionIndexes = mapChangedLinesToBlocks(\n baseSections,\n changedLineNumbers\n );\n\n // Flattened blocks the plan refers to by index. Reused/deleted/inserted\n // sections contribute their whole-section block; changed sections contribute\n // their fine sub-blocks.\n const baseBlocks: FingerprintedBlock[] = [];\n const targetBlocks: FingerprintedBlock[] = [];\n const actions: PlannedAction[] = [];\n\n const pushBaseBlock = (block: FingerprintedBlock): number =>\n baseBlocks.push(block) - 1;\n const pushTargetBlock = (block: FingerprintedBlock): number =>\n targetBlocks.push(block) - 1;\n\n for (const pair of sectionAlignment) {\n // Section present only in the target → reported as `delete` for visibility,\n // but kept verbatim by the merge (the aligner may simply have failed to\n // follow a reordered section), never silently dropped.\n if (pair.baseIndex === -1 && pair.targetIndex !== null) {\n const targetIndex = pushTargetBlock(targetSections[pair.targetIndex]!);\n actions.push({ kind: 'delete', targetIndex });\n continue;\n }\n\n // Section present only in the base → brand new, translate as one unit.\n if (pair.baseIndex >= 0 && pair.targetIndex === null) {\n const baseIndex = pushBaseBlock(baseSections[pair.baseIndex]!);\n actions.push({ kind: 'insert_new', baseIndex });\n continue;\n }\n\n if (pair.baseIndex < 0 || pair.targetIndex === null) continue;\n\n const baseSection = baseSections[pair.baseIndex]!;\n const targetSection = targetSections[pair.targetIndex]!;\n\n // Unchanged section → reuse the existing translation verbatim.\n if (!changedSectionIndexes.has(pair.baseIndex)) {\n const baseIndex = pushBaseBlock(baseSection);\n const targetIndex = pushTargetBlock(targetSection);\n actions.push({ kind: 'reuse', baseIndex, targetIndex });\n continue;\n }\n\n // Changed section → align its fine blocks and review only what changed.\n const baseFineBlocks = fingerprintSectionFineBlocks(baseSection);\n const targetFineBlocks = fingerprintSectionFineBlocks(targetSection);\n const fineAlignment = alignBaseAndTargetBlocks(\n baseFineBlocks,\n targetFineBlocks\n );\n const changedFineIndexes = mapChangedLinesToBlocks(\n baseFineBlocks,\n changedLineNumbers\n );\n\n for (const finePair of fineAlignment) {\n // Target-only fine block: keep it (no data loss), do not delete.\n if (finePair.baseIndex === -1 && finePair.targetIndex !== null) {\n const targetIndex = pushTargetBlock(\n targetFineBlocks[finePair.targetIndex]!\n );\n actions.push({ kind: 'reuse', baseIndex: -1, targetIndex });\n continue;\n }\n\n // Base-only fine block: a new paragraph inside the section, translate it.\n if (finePair.baseIndex >= 0 && finePair.targetIndex === null) {\n const baseIndex = pushBaseBlock(baseFineBlocks[finePair.baseIndex]!);\n actions.push({ kind: 'insert_new', baseIndex });\n continue;\n }\n\n if (finePair.baseIndex < 0 || finePair.targetIndex === null) continue;\n\n const baseIndex = pushBaseBlock(baseFineBlocks[finePair.baseIndex]!);\n const targetIndex = pushTargetBlock(\n targetFineBlocks[finePair.targetIndex]!\n );\n\n actions.push(\n changedFineIndexes.has(finePair.baseIndex)\n ? { kind: 'review', baseIndex, targetIndex }\n : { kind: 'reuse', baseIndex, targetIndex }\n );\n }\n }\n\n const plan = { actions };\n\n const { segmentsToReview } = identifySegmentsToReview({\n baseBlocks,\n targetBlocks,\n plan,\n });\n\n return { baseBlocks, targetBlocks, plan, segmentsToReview };\n};\n\nexport type { SegmentToReview };\nexport { mergeReviewedSegments };\n"],"mappings":";;;;;;;;;AA6BA,MAAM,wBAAwB,WAA0C;CAGtE,OAFmB,OAAO,IAAI,cAEd,CAAC,CAAC,KAAK,OAAO,OAAO,UACnC,iBAAiB,OAAO,MAAM,QAAQ,MAAM,MAAM,MAAM,QAAQ,MAAM,IAAI,CAC5E;AACF;;;;;;AAOA,MAAM,gCAAgC,YAAyC;CAC7E,MAAM,aAAa,QAAQ,YAAY;CAEvC,MAAM,aAAa,gBAAgB,QAAQ,OAAO,CAAC,CAAC,KACjD,WAAkB;EACjB,GAAG;EACH,WAAW,MAAM,YAAY;EAC7B,SAAS,MAAM,UAAU;CAC3B,EACF;CAEA,OAAO,qBAAqB,UAAU;AACxC;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAa,sBAAsB,EACjC,UACA,YACA,mBACuD;CACvD,MAAM,qBAAqB,MAAM,QAAQ,YAAY,IAAI,eAAe,CAAC;CAEzE,MAAM,eAAe,qBAAqB,gBAAgB,QAAQ,CAAC;CACnE,MAAM,iBAAiB,qBAAqB,gBAAgB,UAAU,CAAC;CAEvE,MAAM,mBAAmB,yBACvB,cACA,cACF;CACA,MAAM,wBAAwB,wBAC5B,cACA,kBACF;CAKA,MAAM,aAAmC,CAAC;CAC1C,MAAM,eAAqC,CAAC;CAC5C,MAAM,UAA2B,CAAC;CAElC,MAAM,iBAAiB,UACrB,WAAW,KAAK,KAAK,IAAI;CAC3B,MAAM,mBAAmB,UACvB,aAAa,KAAK,KAAK,IAAI;CAE7B,KAAK,MAAM,QAAQ,kBAAkB;EAInC,IAAI,KAAK,cAAc,MAAM,KAAK,gBAAgB,MAAM;GACtD,MAAM,cAAc,gBAAgB,eAAe,KAAK,YAAa;GACrE,QAAQ,KAAK;IAAE,MAAM;IAAU;GAAY,CAAC;GAC5C;EACF;EAGA,IAAI,KAAK,aAAa,KAAK,KAAK,gBAAgB,MAAM;GACpD,MAAM,YAAY,cAAc,aAAa,KAAK,UAAW;GAC7D,QAAQ,KAAK;IAAE,MAAM;IAAc;GAAU,CAAC;GAC9C;EACF;EAEA,IAAI,KAAK,YAAY,KAAK,KAAK,gBAAgB,MAAM;EAErD,MAAM,cAAc,aAAa,KAAK;EACtC,MAAM,gBAAgB,eAAe,KAAK;EAG1C,IAAI,CAAC,sBAAsB,IAAI,KAAK,SAAS,GAAG;GAC9C,MAAM,YAAY,cAAc,WAAW;GAC3C,MAAM,cAAc,gBAAgB,aAAa;GACjD,QAAQ,KAAK;IAAE,MAAM;IAAS;IAAW;GAAY,CAAC;GACtD;EACF;EAGA,MAAM,iBAAiB,6BAA6B,WAAW;EAC/D,MAAM,mBAAmB,6BAA6B,aAAa;EACnE,MAAM,gBAAgB,yBACpB,gBACA,gBACF;EACA,MAAM,qBAAqB,wBACzB,gBACA,kBACF;EAEA,KAAK,MAAM,YAAY,eAAe;GAEpC,IAAI,SAAS,cAAc,MAAM,SAAS,gBAAgB,MAAM;IAC9D,MAAM,cAAc,gBAClB,iBAAiB,SAAS,YAC5B;IACA,QAAQ,KAAK;KAAE,MAAM;KAAS,WAAW;KAAI;IAAY,CAAC;IAC1D;GACF;GAGA,IAAI,SAAS,aAAa,KAAK,SAAS,gBAAgB,MAAM;IAC5D,MAAM,YAAY,cAAc,eAAe,SAAS,UAAW;IACnE,QAAQ,KAAK;KAAE,MAAM;KAAc;IAAU,CAAC;IAC9C;GACF;GAEA,IAAI,SAAS,YAAY,KAAK,SAAS,gBAAgB,MAAM;GAE7D,MAAM,YAAY,cAAc,eAAe,SAAS,UAAW;GACnE,MAAM,cAAc,gBAClB,iBAAiB,SAAS,YAC5B;GAEA,QAAQ,KACN,mBAAmB,IAAI,SAAS,SAAS,IACrC;IAAE,MAAM;IAAU;IAAW;GAAY,IACzC;IAAE,MAAM;IAAS;IAAW;GAAY,CAC9C;EACF;CACF;CAEA,MAAM,OAAO,EAAE,QAAQ;CAEvB,MAAM,EAAE,qBAAqB,yBAAyB;EACpD;EACA;EACA;CACF,CAAC;CAED,OAAO;EAAE;EAAY;EAAc;EAAM;CAAiB;AAC5D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"planActions.mjs","names":[],"sources":["../../../src/docReview/planActions.ts"],"sourcesContent":["import type { AlignmentPair, AlignmentPlan, PlannedAction } from './types';\n\n/**\n * Turn raw alignment pairs into an ordered list of merge actions.\n *\n * A block aligned in both documents is reused when its base counterpart is not\n * marked as changed, and reviewed otherwise. Blocks present only in the base are\n * inserted, blocks present only in the target are deleted.\n *\n * @param alignment - The alignment pairs produced by the aligner.\n * @param changedBaseBlockIndexes - Indexes of base blocks reported as changed.\n * @returns The plan of actions to merge the documents.\n */\nexport const planAlignmentActions = (\n alignment: AlignmentPair[],\n changedBaseBlockIndexes: Set<number>\n): AlignmentPlan => {\n const actions: PlannedAction[] = [];\n const seenTarget = new Set<number>();\n\n alignment.forEach((pair) => {\n const baseIndex = pair.baseIndex;\n const targetIndex = pair.targetIndex;\n\n // Case 1: Deletion (Exists in target, not in base)\n if (baseIndex === -1 && targetIndex !== null) {\n if (!seenTarget.has(targetIndex)) {\n actions.push({ kind: 'delete', targetIndex });\n seenTarget.add(targetIndex);\n }\n return;\n }\n\n // Case 2: New Insertion (Exists in base, not in target)\n if (baseIndex >= 0 && targetIndex === null) {\n actions.push({ kind: 'insert_new', baseIndex });\n return;\n }\n\n // Case 3: Alignment (Exists in both)\n if (baseIndex >= 0 && targetIndex !== null) {\n const isChanged = changedBaseBlockIndexes.has(baseIndex);\n\n // If the block is NOT marked as changed, we REUSE it. We assume the existing\n // translation is correct because the source hasn't been touched. We ignore\n // 'similarityScore' here because base vs target text will always have low\n // similarity.\n if (!isChanged) {\n actions.push({ kind: 'reuse', baseIndex, targetIndex });\n } else {\n // If the block IS changed, we Review it.\n actions.push({ kind: 'review', baseIndex, targetIndex });\n }\n\n seenTarget.add(targetIndex);\n return;\n }\n });\n\n return { actions };\n};\n"],"mappings":";;;;;;;;;;;;AAaA,MAAa,wBACX,WACA,4BACkB;CAClB,MAAM,UAA2B,
|
|
1
|
+
{"version":3,"file":"planActions.mjs","names":[],"sources":["../../../src/docReview/planActions.ts"],"sourcesContent":["import type { AlignmentPair, AlignmentPlan, PlannedAction } from './types';\n\n/**\n * Turn raw alignment pairs into an ordered list of merge actions.\n *\n * A block aligned in both documents is reused when its base counterpart is not\n * marked as changed, and reviewed otherwise. Blocks present only in the base are\n * inserted, blocks present only in the target are deleted.\n *\n * @param alignment - The alignment pairs produced by the aligner.\n * @param changedBaseBlockIndexes - Indexes of base blocks reported as changed.\n * @returns The plan of actions to merge the documents.\n */\nexport const planAlignmentActions = (\n alignment: AlignmentPair[],\n changedBaseBlockIndexes: Set<number>\n): AlignmentPlan => {\n const actions: PlannedAction[] = [];\n const seenTarget = new Set<number>();\n\n alignment.forEach((pair) => {\n const baseIndex = pair.baseIndex;\n const targetIndex = pair.targetIndex;\n\n // Case 1: Deletion (Exists in target, not in base)\n if (baseIndex === -1 && targetIndex !== null) {\n if (!seenTarget.has(targetIndex)) {\n actions.push({ kind: 'delete', targetIndex });\n seenTarget.add(targetIndex);\n }\n return;\n }\n\n // Case 2: New Insertion (Exists in base, not in target)\n if (baseIndex >= 0 && targetIndex === null) {\n actions.push({ kind: 'insert_new', baseIndex });\n return;\n }\n\n // Case 3: Alignment (Exists in both)\n if (baseIndex >= 0 && targetIndex !== null) {\n const isChanged = changedBaseBlockIndexes.has(baseIndex);\n\n // If the block is NOT marked as changed, we REUSE it. We assume the existing\n // translation is correct because the source hasn't been touched. We ignore\n // 'similarityScore' here because base vs target text will always have low\n // similarity.\n if (!isChanged) {\n actions.push({ kind: 'reuse', baseIndex, targetIndex });\n } else {\n // If the block IS changed, we Review it.\n actions.push({ kind: 'review', baseIndex, targetIndex });\n }\n\n seenTarget.add(targetIndex);\n return;\n }\n });\n\n return { actions };\n};\n"],"mappings":";;;;;;;;;;;;AAaA,MAAa,wBACX,WACA,4BACkB;CAClB,MAAM,UAA2B,CAAC;CAClC,MAAM,6BAAa,IAAI,IAAY;CAEnC,UAAU,SAAS,SAAS;EAC1B,MAAM,YAAY,KAAK;EACvB,MAAM,cAAc,KAAK;EAGzB,IAAI,cAAc,MAAM,gBAAgB,MAAM;GAC5C,IAAI,CAAC,WAAW,IAAI,WAAW,GAAG;IAChC,QAAQ,KAAK;KAAE,MAAM;KAAU;IAAY,CAAC;IAC5C,WAAW,IAAI,WAAW;GAC5B;GACA;EACF;EAGA,IAAI,aAAa,KAAK,gBAAgB,MAAM;GAC1C,QAAQ,KAAK;IAAE,MAAM;IAAc;GAAU,CAAC;GAC9C;EACF;EAGA,IAAI,aAAa,KAAK,gBAAgB,MAAM;GAO1C,IAAI,CANc,wBAAwB,IAAI,SAMjC,GACX,QAAQ,KAAK;IAAE,MAAM;IAAS;IAAW;GAAY,CAAC;QAGtD,QAAQ,KAAK;IAAE,MAAM;IAAU;IAAW;GAAY,CAAC;GAGzD,WAAW,IAAI,WAAW;GAC1B;EACF;CACF,CAAC;CAED,OAAO,EAAE,QAAQ;AACnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rebuildDocument.mjs","names":[],"sources":["../../../src/docReview/rebuildDocument.ts"],"sourcesContent":["import type { AlignmentPlan, FingerprintedBlock } from './types';\n\n/**\n * A block that needs to be translated or re-translated by an external consumer\n * (an AI client, a human, or an agent).\n */\nexport type SegmentToReview = {\n /** The base block to translate. */\n baseBlock: FingerprintedBlock;\n /** Existing target translation, or `null` when the block is new. */\n targetBlockText: string | null;\n /** Index of the originating action within {@link AlignmentPlan.actions}. */\n actionIndex: number;\n};\n\nexport type RebuildInput = {\n baseBlocks: FingerprintedBlock[];\n targetBlocks: FingerprintedBlock[];\n plan: AlignmentPlan;\n};\n\nexport type RebuildResult = {\n segmentsToReview: SegmentToReview[];\n};\n\n/**\n * Analyze the alignment plan and return only the segments that need\n * review/translation. Does not generate output text - that is done by\n * {@link mergeReviewedSegments} once the translations are available.\n *\n * @param input - The base/target blocks and the alignment plan.\n * @returns The list of segments that require translation.\n */\nexport const identifySegmentsToReview = ({\n baseBlocks,\n targetBlocks,\n plan,\n}: RebuildInput): RebuildResult => {\n const segmentsToReview: SegmentToReview[] = [];\n\n plan.actions.forEach((action, actionIndex) => {\n if (action.kind === 'review') {\n const baseBlock = baseBlocks[action.baseIndex];\n const targetBlockText =\n action.targetIndex !== null\n ? targetBlocks[action.targetIndex].content\n : null;\n\n segmentsToReview.push({ baseBlock, targetBlockText, actionIndex });\n } else if (action.kind === 'insert_new') {\n const baseBlock = baseBlocks[action.baseIndex];\n\n segmentsToReview.push({\n baseBlock,\n targetBlockText: null,\n actionIndex,\n });\n }\n });\n\n return { segmentsToReview };\n};\n\n/**\n * Merge reviewed translations back into the final document following the\n * alignment plan, reusing untouched target blocks as-is.\n *\n * @param plan - The alignment plan.\n * @param targetBlocks - Blocks of the existing target document.\n * @param reviewedSegments - Map of action index to its reviewed translation.\n * @returns The rebuilt target document.\n */\nexport const mergeReviewedSegments = (\n plan: AlignmentPlan,\n targetBlocks: FingerprintedBlock[],\n reviewedSegments: Map<number, string>\n): string => {\n const outputParts: string[] = [];\n\n plan.actions.forEach((action, actionIndex) => {\n if (action.kind === 'reuse') {\n outputParts.push(targetBlocks[action.targetIndex].content);\n } else if (action.kind === 'review' || action.kind === 'insert_new') {\n const reviewedContent = reviewedSegments.get(actionIndex);\n\n if (reviewedContent !== undefined) {\n outputParts.push(reviewedContent);\n } else {\n // Fallback: if review failed, use existing or blank\n if (action.kind === 'review' && action.targetIndex !== null) {\n outputParts.push(targetBlocks[action.targetIndex].content);\n } else {\n outputParts.push('\\n');\n }\n }\n } else if (action.kind === 'delete') {\n const reviewedContent = reviewedSegments.get(actionIndex);\n if (reviewedContent !== undefined) {\n // Caller explicitly resolved this block: empty string = actually delete,\n // non-empty string = replacement content.\n if (reviewedContent) outputParts.push(reviewedContent);\n } else {\n // Default: keep verbatim. A target block with no base counterpart may\n // just be a section the aligner could not follow (reordering, split\n // prose) — keeping it prevents accidental data loss in log/read-only mode.\n outputParts.push(targetBlocks[action.targetIndex].content);\n }\n }\n });\n\n return outputParts.join('');\n};\n"],"mappings":";;;;;;;;;AAiCA,MAAa,4BAA4B,EACvC,YACA,cACA,WACiC;CACjC,MAAM,mBAAsC,
|
|
1
|
+
{"version":3,"file":"rebuildDocument.mjs","names":[],"sources":["../../../src/docReview/rebuildDocument.ts"],"sourcesContent":["import type { AlignmentPlan, FingerprintedBlock } from './types';\n\n/**\n * A block that needs to be translated or re-translated by an external consumer\n * (an AI client, a human, or an agent).\n */\nexport type SegmentToReview = {\n /** The base block to translate. */\n baseBlock: FingerprintedBlock;\n /** Existing target translation, or `null` when the block is new. */\n targetBlockText: string | null;\n /** Index of the originating action within {@link AlignmentPlan.actions}. */\n actionIndex: number;\n};\n\nexport type RebuildInput = {\n baseBlocks: FingerprintedBlock[];\n targetBlocks: FingerprintedBlock[];\n plan: AlignmentPlan;\n};\n\nexport type RebuildResult = {\n segmentsToReview: SegmentToReview[];\n};\n\n/**\n * Analyze the alignment plan and return only the segments that need\n * review/translation. Does not generate output text - that is done by\n * {@link mergeReviewedSegments} once the translations are available.\n *\n * @param input - The base/target blocks and the alignment plan.\n * @returns The list of segments that require translation.\n */\nexport const identifySegmentsToReview = ({\n baseBlocks,\n targetBlocks,\n plan,\n}: RebuildInput): RebuildResult => {\n const segmentsToReview: SegmentToReview[] = [];\n\n plan.actions.forEach((action, actionIndex) => {\n if (action.kind === 'review') {\n const baseBlock = baseBlocks[action.baseIndex];\n const targetBlockText =\n action.targetIndex !== null\n ? targetBlocks[action.targetIndex].content\n : null;\n\n segmentsToReview.push({ baseBlock, targetBlockText, actionIndex });\n } else if (action.kind === 'insert_new') {\n const baseBlock = baseBlocks[action.baseIndex];\n\n segmentsToReview.push({\n baseBlock,\n targetBlockText: null,\n actionIndex,\n });\n }\n });\n\n return { segmentsToReview };\n};\n\n/**\n * Merge reviewed translations back into the final document following the\n * alignment plan, reusing untouched target blocks as-is.\n *\n * @param plan - The alignment plan.\n * @param targetBlocks - Blocks of the existing target document.\n * @param reviewedSegments - Map of action index to its reviewed translation.\n * @returns The rebuilt target document.\n */\nexport const mergeReviewedSegments = (\n plan: AlignmentPlan,\n targetBlocks: FingerprintedBlock[],\n reviewedSegments: Map<number, string>\n): string => {\n const outputParts: string[] = [];\n\n plan.actions.forEach((action, actionIndex) => {\n if (action.kind === 'reuse') {\n outputParts.push(targetBlocks[action.targetIndex].content);\n } else if (action.kind === 'review' || action.kind === 'insert_new') {\n const reviewedContent = reviewedSegments.get(actionIndex);\n\n if (reviewedContent !== undefined) {\n outputParts.push(reviewedContent);\n } else {\n // Fallback: if review failed, use existing or blank\n if (action.kind === 'review' && action.targetIndex !== null) {\n outputParts.push(targetBlocks[action.targetIndex].content);\n } else {\n outputParts.push('\\n');\n }\n }\n } else if (action.kind === 'delete') {\n const reviewedContent = reviewedSegments.get(actionIndex);\n if (reviewedContent !== undefined) {\n // Caller explicitly resolved this block: empty string = actually delete,\n // non-empty string = replacement content.\n if (reviewedContent) outputParts.push(reviewedContent);\n } else {\n // Default: keep verbatim. A target block with no base counterpart may\n // just be a section the aligner could not follow (reordering, split\n // prose) — keeping it prevents accidental data loss in log/read-only mode.\n outputParts.push(targetBlocks[action.targetIndex].content);\n }\n }\n });\n\n return outputParts.join('');\n};\n"],"mappings":";;;;;;;;;AAiCA,MAAa,4BAA4B,EACvC,YACA,cACA,WACiC;CACjC,MAAM,mBAAsC,CAAC;CAE7C,KAAK,QAAQ,SAAS,QAAQ,gBAAgB;EAC5C,IAAI,OAAO,SAAS,UAAU;GAC5B,MAAM,YAAY,WAAW,OAAO;GACpC,MAAM,kBACJ,OAAO,gBAAgB,OACnB,aAAa,OAAO,YAAY,CAAC,UACjC;GAEN,iBAAiB,KAAK;IAAE;IAAW;IAAiB;GAAY,CAAC;EACnE,OAAO,IAAI,OAAO,SAAS,cAAc;GACvC,MAAM,YAAY,WAAW,OAAO;GAEpC,iBAAiB,KAAK;IACpB;IACA,iBAAiB;IACjB;GACF,CAAC;EACH;CACF,CAAC;CAED,OAAO,EAAE,iBAAiB;AAC5B;;;;;;;;;;AAWA,MAAa,yBACX,MACA,cACA,qBACW;CACX,MAAM,cAAwB,CAAC;CAE/B,KAAK,QAAQ,SAAS,QAAQ,gBAAgB;EAC5C,IAAI,OAAO,SAAS,SAClB,YAAY,KAAK,aAAa,OAAO,YAAY,CAAC,OAAO;OACpD,IAAI,OAAO,SAAS,YAAY,OAAO,SAAS,cAAc;GACnE,MAAM,kBAAkB,iBAAiB,IAAI,WAAW;GAExD,IAAI,oBAAoB,QACtB,YAAY,KAAK,eAAe;QAGhC,IAAI,OAAO,SAAS,YAAY,OAAO,gBAAgB,MACrD,YAAY,KAAK,aAAa,OAAO,YAAY,CAAC,OAAO;QAEzD,YAAY,KAAK,IAAI;EAG3B,OAAO,IAAI,OAAO,SAAS,UAAU;GACnC,MAAM,kBAAkB,iBAAiB,IAAI,WAAW;GACxD,IAAI,oBAAoB,QAGtB;QAAI,iBAAiB,YAAY,KAAK,eAAe;GAAC,OAKtD,YAAY,KAAK,aAAa,OAAO,YAAY,CAAC,OAAO;EAE7D;CACF,CAAC;CAED,OAAO,YAAY,KAAK,EAAE;AAC5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reviewReport.mjs","names":[],"sources":["../../../src/docReview/reviewReport.ts"],"sourcesContent":["import * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizeNumber } from '@intlayer/config/logger';\nimport { buildAlignmentPlan } from './pipeline';\n\n/**\n * The kind of change detected for a block when reviewing a translation against\n * its base document.\n *\n * - `review`: the base block changed and its translation must be updated.\n * - `insert_new`: the base block has no translation yet and must be added.\n * - `delete`: the target block no longer exists in the base and should be removed.\n */\nexport type ReviewBlockAction = 'review' | 'insert_new' | 'delete';\n\n/** A 1-based, inclusive line range within a document. */\nexport type LineRange = {\n start: number;\n end: number;\n};\n\n/**\n * A single block that diverges between the base document and its translation.\n *\n * This is the unit an external translator (AI client, human, or agent) needs to\n * act on: it carries the base content to translate, the existing translation to\n * update, and where each lives so the change can be located in the file.\n */\nexport type ReviewReportBlock = {\n /** What should happen to this block. */\n action: ReviewBlockAction;\n /** Line range of the block in the base document (omitted for pure deletions). */\n baseLineRange?: LineRange;\n /** Line range of the block in the target document (omitted for new insertions). */\n targetLineRange?: LineRange;\n /** Raw markdown of the base block (omitted for pure deletions). */\n baseContent?: string;\n /** Existing translation of the block (omitted for new insertions). */\n targetContent?: string;\n};\n\nexport type ReviewReportSummary = {\n /** Number of blocks reused as-is (unchanged translation). */\n reuse: number;\n /** Number of blocks whose translation must be updated. */\n review: number;\n /** Number of blocks missing a translation. */\n insertNew: number;\n /** Number of stale target blocks to delete. */\n delete: number;\n};\n\nexport type ReviewReport = {\n /** Only the blocks that diverge (review, insert_new, delete). */\n blocks: ReviewReportBlock[];\n /** Counts per action over the whole document, including reused blocks. */\n summary: ReviewReportSummary;\n};\n\nexport type BuildReviewReportInput = {\n /** The base (source) document, used as the translation reference. */\n baseText: string;\n /** The existing target (translated) document, possibly empty. */\n targetText: string;\n /**\n * 1-based line numbers that changed in the base document. When omitted, only\n * inserted and deleted blocks are reported (no aligned block is flagged for\n * review since there is no way to know which ones changed).\n */\n changedLines?: number[];\n};\n\n/**\n * Compare a base markdown document with its translation and report only the\n * blocks that need attention, with their line ranges and content.\n *\n * Reusable across the CLI (`doc review --log`), the backend (comparing two\n * translation contents stored in database), and agents that generate the\n * missing translations.\n *\n * @param input - The base/target texts and optional changed lines.\n * @returns The divergent blocks and a per-action summary.\n */\nexport const buildReviewReport = ({\n baseText,\n targetText,\n changedLines,\n}: BuildReviewReportInput): ReviewReport => {\n const { baseBlocks, targetBlocks, plan } = buildAlignmentPlan({\n baseText,\n targetText,\n changedLines,\n });\n\n const summary: ReviewReportSummary = {\n reuse: 0,\n review: 0,\n insertNew: 0,\n delete: 0,\n };\n\n const blocks: ReviewReportBlock[] = [];\n\n for (const [actionIndex, action] of plan.actions.entries()) {\n if (action.kind === 'reuse') {\n summary.reuse += 1;\n continue;\n }\n\n if (action.kind === 'review') {\n summary.review += 1;\n const baseBlock = baseBlocks[action.baseIndex];\n\n if (!baseBlock) continue;\n\n const targetBlock =\n action.targetIndex !== null ? targetBlocks[action.targetIndex] : null;\n\n blocks.push({\n action: 'review',\n baseLineRange: { start: baseBlock.lineStart, end: baseBlock.lineEnd },\n targetLineRange: targetBlock\n ? { start: targetBlock.lineStart, end: targetBlock.lineEnd }\n : undefined,\n baseContent: baseBlock.content,\n targetContent: targetBlock?.content,\n });\n continue;\n }\n\n if (action.kind === 'insert_new') {\n summary.insertNew += 1;\n const baseBlock = baseBlocks[action.baseIndex];\n\n if (!baseBlock) continue;\n\n // Find the target line after which the new block should be inserted:\n // scan backwards for the last action that produced a target block.\n let insertAfterLine: number | undefined;\n for (let prevIndex = actionIndex - 1; prevIndex >= 0; prevIndex--) {\n const prevAction = plan.actions[prevIndex];\n if (!prevAction) continue;\n\n let targetIdx: number | null = null;\n if (prevAction.kind === 'reuse') targetIdx = prevAction.targetIndex;\n else if (\n prevAction.kind === 'review' &&\n prevAction.targetIndex !== null\n )\n targetIdx = prevAction.targetIndex;\n else if (prevAction.kind === 'delete')\n targetIdx = prevAction.targetIndex;\n\n if (targetIdx !== null) {\n const prevTargetBlock = targetBlocks[targetIdx];\n if (prevTargetBlock) {\n insertAfterLine = prevTargetBlock.lineEnd + 1;\n break;\n }\n }\n }\n\n blocks.push({\n action: 'insert_new',\n baseLineRange: { start: baseBlock.lineStart, end: baseBlock.lineEnd },\n targetLineRange:\n insertAfterLine !== undefined\n ? { start: insertAfterLine, end: insertAfterLine }\n : undefined,\n baseContent: baseBlock.content,\n });\n continue;\n }\n\n if (action.kind === 'delete') {\n summary.delete += 1;\n const targetBlock = targetBlocks[action.targetIndex];\n\n if (!targetBlock) continue;\n\n blocks.push({\n action: 'delete',\n targetLineRange: {\n start: targetBlock.lineStart,\n end: targetBlock.lineEnd,\n },\n targetContent: targetBlock.content,\n });\n }\n }\n\n return { blocks, summary };\n};\n\n/** Render a line range as a blue colored string, or an orange dash when absent. */\nconst colorizeLineRange = (range?: LineRange): string => {\n if (!range) return colorize('—', ANSIColors.ORANGE);\n const rangeStr =\n range.start === range.end\n ? `L${range.start}`\n : `L${range.start}-${range.end}`;\n return colorize(rangeStr, ANSIColors.BLUE);\n};\n\n/**\n * Colorize a count with green when zero (nothing to do) and a caller-supplied\n * non-zero color (orange for warnings, red for destructive actions).\n */\nconst colorizeCount = (\n count: number,\n nonZeroColor: (typeof ANSIColors)[keyof typeof ANSIColors]\n): string =>\n colorizeNumber(count, {\n zero: ANSIColors.GREEN,\n one: nonZeroColor,\n two: nonZeroColor,\n few: nonZeroColor,\n many: nonZeroColor,\n other: nonZeroColor,\n });\n\n/**\n * Render a {@link ReviewReport} as a human and agent readable log.\n *\n * Each divergent block is printed with its action, the base/target line ranges,\n * the base content to translate, and the existing translation to update.\n *\n * @param report - The report to format.\n * @param options - Optional labels for the base and target locales.\n * @returns A multi-line string describing every block that needs attention.\n */\nexport const formatReviewReport = (\n report: ReviewReport,\n options?: { baseLabel?: string; targetLabel?: string }\n): string => {\n const baseLabel = options?.baseLabel ?? 'base';\n const targetLabel = options?.targetLabel ?? 'target';\n\n const { summary, blocks } = report;\n\n // Build the summary header piece-by-piece so each count uses its own color.\n const header = [\n colorize('Review report: ', ANSIColors.ORANGE),\n colorizeCount(blocks.length, ANSIColors.ORANGE),\n colorize(' block(s) need attention (review=', ANSIColors.ORANGE),\n colorizeCount(summary.review, ANSIColors.ORANGE),\n colorize(', new=', ANSIColors.ORANGE),\n colorizeCount(summary.insertNew, ANSIColors.ORANGE),\n colorize(', delete=', ANSIColors.ORANGE),\n colorizeCount(summary.delete, ANSIColors.RED),\n colorize(', reuse=', ANSIColors.ORANGE),\n colorizeNumber(summary.reuse),\n colorize(').', ANSIColors.ORANGE),\n ].join('');\n\n if (blocks.length === 0) {\n return `${header}\\n${colorize('No changes needed.', ANSIColors.GREEN)}`;\n }\n\n const sections = blocks.map((block, index) => {\n const lines: string[] = [];\n\n // Block header: each token colored individually.\n const blockHeader = [\n colorize('--- Block ', ANSIColors.ORANGE),\n colorizeNumber(index + 1),\n colorize('/', ANSIColors.ORANGE),\n colorizeNumber(blocks.length),\n colorize(` [${block.action}] `, ANSIColors.ORANGE),\n baseLabel,\n colorize(' ', ANSIColors.ORANGE),\n colorizeLineRange(block.baseLineRange),\n colorize(' → ', ANSIColors.ORANGE),\n targetLabel,\n colorize(' ', ANSIColors.ORANGE),\n colorizeLineRange(block.targetLineRange),\n colorize(' ---', ANSIColors.ORANGE),\n ].join('');\n\n lines.push(blockHeader);\n\n if (block.baseContent !== undefined) {\n lines.push(colorize(`[${baseLabel}]`, ANSIColors.BEIGE));\n lines.push(colorize(block.baseContent.trimEnd(), ANSIColors.GREY));\n }\n\n if (block.targetContent !== undefined) {\n lines.push(colorize(`[${targetLabel}]`, ANSIColors.BEIGE));\n lines.push(colorize(block.targetContent.trimEnd(), ANSIColors.GREY));\n } else if (block.action === 'insert_new') {\n lines.push(colorize(`[${targetLabel}]`, ANSIColors.BEIGE));\n lines.push(colorize('(missing — to be translated)', ANSIColors.ORANGE));\n }\n\n return lines.join('\\n');\n });\n\n const editingNote = colorize(\n 'Tip: start editing from the last block — working bottom-up keeps earlier line numbers accurate.',\n ANSIColors.GREY\n );\n\n return [header, '', ...sections, '', editingNote].join('\\n');\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"reviewReport.mjs","names":[],"sources":["../../../src/docReview/reviewReport.ts"],"sourcesContent":["import * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizeNumber } from '@intlayer/config/logger';\nimport { buildAlignmentPlan } from './pipeline';\n\n/**\n * The kind of change detected for a block when reviewing a translation against\n * its base document.\n *\n * - `review`: the base block changed and its translation must be updated.\n * - `insert_new`: the base block has no translation yet and must be added.\n * - `delete`: the target block no longer exists in the base and should be removed.\n */\nexport type ReviewBlockAction = 'review' | 'insert_new' | 'delete';\n\n/** A 1-based, inclusive line range within a document. */\nexport type LineRange = {\n start: number;\n end: number;\n};\n\n/**\n * A single block that diverges between the base document and its translation.\n *\n * This is the unit an external translator (AI client, human, or agent) needs to\n * act on: it carries the base content to translate, the existing translation to\n * update, and where each lives so the change can be located in the file.\n */\nexport type ReviewReportBlock = {\n /** What should happen to this block. */\n action: ReviewBlockAction;\n /** Line range of the block in the base document (omitted for pure deletions). */\n baseLineRange?: LineRange;\n /** Line range of the block in the target document (omitted for new insertions). */\n targetLineRange?: LineRange;\n /** Raw markdown of the base block (omitted for pure deletions). */\n baseContent?: string;\n /** Existing translation of the block (omitted for new insertions). */\n targetContent?: string;\n};\n\nexport type ReviewReportSummary = {\n /** Number of blocks reused as-is (unchanged translation). */\n reuse: number;\n /** Number of blocks whose translation must be updated. */\n review: number;\n /** Number of blocks missing a translation. */\n insertNew: number;\n /** Number of stale target blocks to delete. */\n delete: number;\n};\n\nexport type ReviewReport = {\n /** Only the blocks that diverge (review, insert_new, delete). */\n blocks: ReviewReportBlock[];\n /** Counts per action over the whole document, including reused blocks. */\n summary: ReviewReportSummary;\n};\n\nexport type BuildReviewReportInput = {\n /** The base (source) document, used as the translation reference. */\n baseText: string;\n /** The existing target (translated) document, possibly empty. */\n targetText: string;\n /**\n * 1-based line numbers that changed in the base document. When omitted, only\n * inserted and deleted blocks are reported (no aligned block is flagged for\n * review since there is no way to know which ones changed).\n */\n changedLines?: number[];\n};\n\n/**\n * Compare a base markdown document with its translation and report only the\n * blocks that need attention, with their line ranges and content.\n *\n * Reusable across the CLI (`doc review --log`), the backend (comparing two\n * translation contents stored in database), and agents that generate the\n * missing translations.\n *\n * @param input - The base/target texts and optional changed lines.\n * @returns The divergent blocks and a per-action summary.\n */\nexport const buildReviewReport = ({\n baseText,\n targetText,\n changedLines,\n}: BuildReviewReportInput): ReviewReport => {\n const { baseBlocks, targetBlocks, plan } = buildAlignmentPlan({\n baseText,\n targetText,\n changedLines,\n });\n\n const summary: ReviewReportSummary = {\n reuse: 0,\n review: 0,\n insertNew: 0,\n delete: 0,\n };\n\n const blocks: ReviewReportBlock[] = [];\n\n for (const [actionIndex, action] of plan.actions.entries()) {\n if (action.kind === 'reuse') {\n summary.reuse += 1;\n continue;\n }\n\n if (action.kind === 'review') {\n summary.review += 1;\n const baseBlock = baseBlocks[action.baseIndex];\n\n if (!baseBlock) continue;\n\n const targetBlock =\n action.targetIndex !== null ? targetBlocks[action.targetIndex] : null;\n\n blocks.push({\n action: 'review',\n baseLineRange: { start: baseBlock.lineStart, end: baseBlock.lineEnd },\n targetLineRange: targetBlock\n ? { start: targetBlock.lineStart, end: targetBlock.lineEnd }\n : undefined,\n baseContent: baseBlock.content,\n targetContent: targetBlock?.content,\n });\n continue;\n }\n\n if (action.kind === 'insert_new') {\n summary.insertNew += 1;\n const baseBlock = baseBlocks[action.baseIndex];\n\n if (!baseBlock) continue;\n\n // Find the target line after which the new block should be inserted:\n // scan backwards for the last action that produced a target block.\n let insertAfterLine: number | undefined;\n for (let prevIndex = actionIndex - 1; prevIndex >= 0; prevIndex--) {\n const prevAction = plan.actions[prevIndex];\n if (!prevAction) continue;\n\n let targetIdx: number | null = null;\n if (prevAction.kind === 'reuse') targetIdx = prevAction.targetIndex;\n else if (\n prevAction.kind === 'review' &&\n prevAction.targetIndex !== null\n )\n targetIdx = prevAction.targetIndex;\n else if (prevAction.kind === 'delete')\n targetIdx = prevAction.targetIndex;\n\n if (targetIdx !== null) {\n const prevTargetBlock = targetBlocks[targetIdx];\n if (prevTargetBlock) {\n insertAfterLine = prevTargetBlock.lineEnd + 1;\n break;\n }\n }\n }\n\n blocks.push({\n action: 'insert_new',\n baseLineRange: { start: baseBlock.lineStart, end: baseBlock.lineEnd },\n targetLineRange:\n insertAfterLine !== undefined\n ? { start: insertAfterLine, end: insertAfterLine }\n : undefined,\n baseContent: baseBlock.content,\n });\n continue;\n }\n\n if (action.kind === 'delete') {\n summary.delete += 1;\n const targetBlock = targetBlocks[action.targetIndex];\n\n if (!targetBlock) continue;\n\n blocks.push({\n action: 'delete',\n targetLineRange: {\n start: targetBlock.lineStart,\n end: targetBlock.lineEnd,\n },\n targetContent: targetBlock.content,\n });\n }\n }\n\n return { blocks, summary };\n};\n\n/** Render a line range as a blue colored string, or an orange dash when absent. */\nconst colorizeLineRange = (range?: LineRange): string => {\n if (!range) return colorize('—', ANSIColors.ORANGE);\n const rangeStr =\n range.start === range.end\n ? `L${range.start}`\n : `L${range.start}-${range.end}`;\n return colorize(rangeStr, ANSIColors.BLUE);\n};\n\n/**\n * Colorize a count with green when zero (nothing to do) and a caller-supplied\n * non-zero color (orange for warnings, red for destructive actions).\n */\nconst colorizeCount = (\n count: number,\n nonZeroColor: (typeof ANSIColors)[keyof typeof ANSIColors]\n): string =>\n colorizeNumber(count, {\n zero: ANSIColors.GREEN,\n one: nonZeroColor,\n two: nonZeroColor,\n few: nonZeroColor,\n many: nonZeroColor,\n other: nonZeroColor,\n });\n\n/**\n * Render a {@link ReviewReport} as a human and agent readable log.\n *\n * Each divergent block is printed with its action, the base/target line ranges,\n * the base content to translate, and the existing translation to update.\n *\n * @param report - The report to format.\n * @param options - Optional labels for the base and target locales.\n * @returns A multi-line string describing every block that needs attention.\n */\nexport const formatReviewReport = (\n report: ReviewReport,\n options?: { baseLabel?: string; targetLabel?: string }\n): string => {\n const baseLabel = options?.baseLabel ?? 'base';\n const targetLabel = options?.targetLabel ?? 'target';\n\n const { summary, blocks } = report;\n\n // Build the summary header piece-by-piece so each count uses its own color.\n const header = [\n colorize('Review report: ', ANSIColors.ORANGE),\n colorizeCount(blocks.length, ANSIColors.ORANGE),\n colorize(' block(s) need attention (review=', ANSIColors.ORANGE),\n colorizeCount(summary.review, ANSIColors.ORANGE),\n colorize(', new=', ANSIColors.ORANGE),\n colorizeCount(summary.insertNew, ANSIColors.ORANGE),\n colorize(', delete=', ANSIColors.ORANGE),\n colorizeCount(summary.delete, ANSIColors.RED),\n colorize(', reuse=', ANSIColors.ORANGE),\n colorizeNumber(summary.reuse),\n colorize(').', ANSIColors.ORANGE),\n ].join('');\n\n if (blocks.length === 0) {\n return `${header}\\n${colorize('No changes needed.', ANSIColors.GREEN)}`;\n }\n\n const sections = blocks.map((block, index) => {\n const lines: string[] = [];\n\n // Block header: each token colored individually.\n const blockHeader = [\n colorize('--- Block ', ANSIColors.ORANGE),\n colorizeNumber(index + 1),\n colorize('/', ANSIColors.ORANGE),\n colorizeNumber(blocks.length),\n colorize(` [${block.action}] `, ANSIColors.ORANGE),\n baseLabel,\n colorize(' ', ANSIColors.ORANGE),\n colorizeLineRange(block.baseLineRange),\n colorize(' → ', ANSIColors.ORANGE),\n targetLabel,\n colorize(' ', ANSIColors.ORANGE),\n colorizeLineRange(block.targetLineRange),\n colorize(' ---', ANSIColors.ORANGE),\n ].join('');\n\n lines.push(blockHeader);\n\n if (block.baseContent !== undefined) {\n lines.push(colorize(`[${baseLabel}]`, ANSIColors.BEIGE));\n lines.push(colorize(block.baseContent.trimEnd(), ANSIColors.GREY));\n }\n\n if (block.targetContent !== undefined) {\n lines.push(colorize(`[${targetLabel}]`, ANSIColors.BEIGE));\n lines.push(colorize(block.targetContent.trimEnd(), ANSIColors.GREY));\n } else if (block.action === 'insert_new') {\n lines.push(colorize(`[${targetLabel}]`, ANSIColors.BEIGE));\n lines.push(colorize('(missing — to be translated)', ANSIColors.ORANGE));\n }\n\n return lines.join('\\n');\n });\n\n const editingNote = colorize(\n 'Tip: start editing from the last block — working bottom-up keeps earlier line numbers accurate.',\n ANSIColors.GREY\n );\n\n return [header, '', ...sections, '', editingNote].join('\\n');\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"segmentDocument.mjs","names":[],"sources":["../../../src/docReview/segmentDocument.ts"],"sourcesContent":["import type { Block, BlockType } from './types';\n\nconst isBlankLine = (line: string): boolean => line.trim().length === 0;\nconst isFencedCodeDelimiter = (line: string): boolean => /^\\s*```/.test(line);\nconst isHeading = (line: string): boolean => /^\\s*#{1,6}\\s+/.test(line);\nconst isFrontmatterDelimiter = (line: string): boolean =>\n /^\\s*---\\s*$/.test(line);\n\n/**\n * A content unit (heading, paragraph, code block or frontmatter) spanning a\n * 0-based, inclusive line range. Blank-line runs are not units of their own;\n * they are folded into the preceding unit as trailing separators (see\n * {@link segmentDocument}) so that the concatenation of every block's content\n * reproduces the document byte-for-byte.\n */\ntype ContentUnit = {\n type: BlockType;\n startIndex: number;\n endIndex: number;\n};\n\n/**\n * Split a markdown document into fine-grained blocks.\n *\n * Boundaries are drawn at headings, blank lines (paragraph breaks) and fenced\n * code blocks, while frontmatter and the inside of code fences are kept intact.\n * Each blank-line run is appended to the block that precedes it, so the blocks\n * form an exact partition of the document: concatenating every `content` (in\n * order) yields the original text unchanged. This is what lets the block-aware\n * review re-translate only the paragraphs/snippets that actually changed instead\n * of the whole heading section.\n *\n * @param text - The full markdown document.\n * @returns The ordered list of blocks with their 1-based line ranges.\n */\nexport const segmentDocument = (text: string): Block[] => {\n const lines = text.split('\\n');\n const lineCount = lines.length;\n\n // 1. Tokenize into content units, skipping blank-line runs (folded in below).\n const units: ContentUnit[] = [];\n let index = 0;\n\n while (index < lineCount) {\n const currentLine = lines[index];\n\n if (isBlankLine(currentLine)) {\n index += 1;\n continue;\n }\n\n // Frontmatter: only when it opens the document.\n if (units.length === 0 && isFrontmatterDelimiter(currentLine)) {\n const startIndex = index;\n index += 1;\n while (index < lineCount && !isFrontmatterDelimiter(lines[index])) {\n index += 1;\n }\n // Include the closing delimiter when present.\n if (index < lineCount) index += 1;\n units.push({ type: 'unknown', startIndex, endIndex: index - 1 });\n continue;\n }\n\n // Fenced code block: consumed whole so inner blank lines and `#` lines are\n // never treated as boundaries.\n if (isFencedCodeDelimiter(currentLine)) {\n const startIndex = index;\n index += 1;\n while (index < lineCount && !isFencedCodeDelimiter(lines[index])) {\n index += 1;\n }\n // Include the closing fence when present.\n if (index < lineCount) index += 1;\n units.push({ type: 'code_block', startIndex, endIndex: index - 1 });\n continue;\n }\n\n // Heading: a single self-contained line.\n if (isHeading(currentLine)) {\n units.push({ type: 'heading', startIndex: index, endIndex: index });\n index += 1;\n continue;\n }\n\n // Paragraph: a run of consecutive lines until a blank line, a heading or a\n // code fence. Tables and tight lists stay together (no blank line between\n // their rows/items).\n const startIndex = index;\n while (\n index < lineCount &&\n !isBlankLine(lines[index]) &&\n !isHeading(lines[index]) &&\n !isFencedCodeDelimiter(lines[index])\n ) {\n index += 1;\n }\n units.push({ type: 'paragraph', startIndex, endIndex: index - 1 });\n }\n\n if (units.length === 0) return [];\n\n // 2. Turn each unit into a block whose line range extends to just before the\n // next unit, so the trailing blank-line run is owned by it. The first block\n // also absorbs any leading blank lines, and the last block runs to EOF.\n return units.map((unit, unitIndex): Block => {\n const blockStartIndex = unitIndex === 0 ? 0 : unit.startIndex;\n const blockEndIndex =\n unitIndex === units.length - 1\n ? lineCount - 1\n : units[unitIndex + 1].startIndex - 1;\n\n const blockLines = lines.slice(blockStartIndex, blockEndIndex + 1);\n // Re-append the boundary newline dropped by `split` for every block but the\n // one ending at EOF, so concatenating all blocks rebuilds the document.\n const content =\n blockEndIndex < lineCount - 1\n ? `${blockLines.join('\\n')}\\n`\n : blockLines.join('\\n');\n\n return {\n type: unit.type,\n content,\n lineStart: blockStartIndex + 1,\n lineEnd: blockEndIndex + 1,\n };\n });\n};\n\n/**\n * Split a markdown document into coarse, heading-anchored sections.\n *\n * Built by grouping the fine blocks of {@link segmentDocument}: frontmatter and\n * each heading open a new section, and the following non-heading blocks are\n * folded into it. Because it only concatenates adjacent fine blocks, the result\n * is still an exact partition of the document (sections concatenate back to the\n * source unchanged).\n *\n * Sections are the robust alignment unit between a base document and its\n * translation — both share the same heading structure, so they align almost\n * perfectly and a translation that splits its prose into a different number of\n * paragraphs never causes a section to be dropped. Fine-grained review happens\n * within a section once it is known to have changed.\n *\n * @param text - The full markdown document.\n * @returns The ordered list of sections with their 1-based line ranges.\n */\nexport const segmentSections = (text: string): Block[] => {\n const fineBlocks = segmentDocument(text);\n const sections: Block[] = [];\n let currentBlocks: Block[] = [];\n\n const flushSection = (): void => {\n if (currentBlocks.length === 0) return;\n\n const [firstBlock] = currentBlocks;\n const lastBlock = currentBlocks[currentBlocks.length - 1];\n\n sections.push({\n type: firstBlock.type,\n content: currentBlocks.map((block) => block.content).join(''),\n lineStart: firstBlock.lineStart,\n lineEnd: lastBlock.lineEnd,\n });\n currentBlocks = [];\n };\n\n for (const block of fineBlocks) {\n // Frontmatter (a leading `unknown` block) and every heading open a section.\n const opensSection =\n block.type === 'heading' ||\n (block.type === 'unknown' && sections.length === 0);\n\n if (opensSection) flushSection();\n currentBlocks.push(block);\n if (block.type === 'unknown' && sections.length === 0) flushSection();\n }\n\n flushSection();\n\n return sections;\n};\n"],"mappings":";AAEA,MAAM,eAAe,SAA0B,KAAK,
|
|
1
|
+
{"version":3,"file":"segmentDocument.mjs","names":[],"sources":["../../../src/docReview/segmentDocument.ts"],"sourcesContent":["import type { Block, BlockType } from './types';\n\nconst isBlankLine = (line: string): boolean => line.trim().length === 0;\nconst isFencedCodeDelimiter = (line: string): boolean => /^\\s*```/.test(line);\nconst isHeading = (line: string): boolean => /^\\s*#{1,6}\\s+/.test(line);\nconst isFrontmatterDelimiter = (line: string): boolean =>\n /^\\s*---\\s*$/.test(line);\n\n/**\n * A content unit (heading, paragraph, code block or frontmatter) spanning a\n * 0-based, inclusive line range. Blank-line runs are not units of their own;\n * they are folded into the preceding unit as trailing separators (see\n * {@link segmentDocument}) so that the concatenation of every block's content\n * reproduces the document byte-for-byte.\n */\ntype ContentUnit = {\n type: BlockType;\n startIndex: number;\n endIndex: number;\n};\n\n/**\n * Split a markdown document into fine-grained blocks.\n *\n * Boundaries are drawn at headings, blank lines (paragraph breaks) and fenced\n * code blocks, while frontmatter and the inside of code fences are kept intact.\n * Each blank-line run is appended to the block that precedes it, so the blocks\n * form an exact partition of the document: concatenating every `content` (in\n * order) yields the original text unchanged. This is what lets the block-aware\n * review re-translate only the paragraphs/snippets that actually changed instead\n * of the whole heading section.\n *\n * @param text - The full markdown document.\n * @returns The ordered list of blocks with their 1-based line ranges.\n */\nexport const segmentDocument = (text: string): Block[] => {\n const lines = text.split('\\n');\n const lineCount = lines.length;\n\n // 1. Tokenize into content units, skipping blank-line runs (folded in below).\n const units: ContentUnit[] = [];\n let index = 0;\n\n while (index < lineCount) {\n const currentLine = lines[index];\n\n if (isBlankLine(currentLine)) {\n index += 1;\n continue;\n }\n\n // Frontmatter: only when it opens the document.\n if (units.length === 0 && isFrontmatterDelimiter(currentLine)) {\n const startIndex = index;\n index += 1;\n while (index < lineCount && !isFrontmatterDelimiter(lines[index])) {\n index += 1;\n }\n // Include the closing delimiter when present.\n if (index < lineCount) index += 1;\n units.push({ type: 'unknown', startIndex, endIndex: index - 1 });\n continue;\n }\n\n // Fenced code block: consumed whole so inner blank lines and `#` lines are\n // never treated as boundaries.\n if (isFencedCodeDelimiter(currentLine)) {\n const startIndex = index;\n index += 1;\n while (index < lineCount && !isFencedCodeDelimiter(lines[index])) {\n index += 1;\n }\n // Include the closing fence when present.\n if (index < lineCount) index += 1;\n units.push({ type: 'code_block', startIndex, endIndex: index - 1 });\n continue;\n }\n\n // Heading: a single self-contained line.\n if (isHeading(currentLine)) {\n units.push({ type: 'heading', startIndex: index, endIndex: index });\n index += 1;\n continue;\n }\n\n // Paragraph: a run of consecutive lines until a blank line, a heading or a\n // code fence. Tables and tight lists stay together (no blank line between\n // their rows/items).\n const startIndex = index;\n while (\n index < lineCount &&\n !isBlankLine(lines[index]) &&\n !isHeading(lines[index]) &&\n !isFencedCodeDelimiter(lines[index])\n ) {\n index += 1;\n }\n units.push({ type: 'paragraph', startIndex, endIndex: index - 1 });\n }\n\n if (units.length === 0) return [];\n\n // 2. Turn each unit into a block whose line range extends to just before the\n // next unit, so the trailing blank-line run is owned by it. The first block\n // also absorbs any leading blank lines, and the last block runs to EOF.\n return units.map((unit, unitIndex): Block => {\n const blockStartIndex = unitIndex === 0 ? 0 : unit.startIndex;\n const blockEndIndex =\n unitIndex === units.length - 1\n ? lineCount - 1\n : units[unitIndex + 1].startIndex - 1;\n\n const blockLines = lines.slice(blockStartIndex, blockEndIndex + 1);\n // Re-append the boundary newline dropped by `split` for every block but the\n // one ending at EOF, so concatenating all blocks rebuilds the document.\n const content =\n blockEndIndex < lineCount - 1\n ? `${blockLines.join('\\n')}\\n`\n : blockLines.join('\\n');\n\n return {\n type: unit.type,\n content,\n lineStart: blockStartIndex + 1,\n lineEnd: blockEndIndex + 1,\n };\n });\n};\n\n/**\n * Split a markdown document into coarse, heading-anchored sections.\n *\n * Built by grouping the fine blocks of {@link segmentDocument}: frontmatter and\n * each heading open a new section, and the following non-heading blocks are\n * folded into it. Because it only concatenates adjacent fine blocks, the result\n * is still an exact partition of the document (sections concatenate back to the\n * source unchanged).\n *\n * Sections are the robust alignment unit between a base document and its\n * translation — both share the same heading structure, so they align almost\n * perfectly and a translation that splits its prose into a different number of\n * paragraphs never causes a section to be dropped. Fine-grained review happens\n * within a section once it is known to have changed.\n *\n * @param text - The full markdown document.\n * @returns The ordered list of sections with their 1-based line ranges.\n */\nexport const segmentSections = (text: string): Block[] => {\n const fineBlocks = segmentDocument(text);\n const sections: Block[] = [];\n let currentBlocks: Block[] = [];\n\n const flushSection = (): void => {\n if (currentBlocks.length === 0) return;\n\n const [firstBlock] = currentBlocks;\n const lastBlock = currentBlocks[currentBlocks.length - 1];\n\n sections.push({\n type: firstBlock.type,\n content: currentBlocks.map((block) => block.content).join(''),\n lineStart: firstBlock.lineStart,\n lineEnd: lastBlock.lineEnd,\n });\n currentBlocks = [];\n };\n\n for (const block of fineBlocks) {\n // Frontmatter (a leading `unknown` block) and every heading open a section.\n const opensSection =\n block.type === 'heading' ||\n (block.type === 'unknown' && sections.length === 0);\n\n if (opensSection) flushSection();\n currentBlocks.push(block);\n if (block.type === 'unknown' && sections.length === 0) flushSection();\n }\n\n flushSection();\n\n return sections;\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchDistantDictionaries.mjs","names":[],"sources":["../../src/fetchDistantDictionaries.ts"],"sourcesContent":["import { createIntlayerCMS } from '@intlayer/api';\nimport { dictionaryEndpoint } from '@intlayer/api/dictionary';\n// @ts-ignore @intlayer/backend is not build yet\nimport type { DictionaryAPI } from '@intlayer/backend';\nimport { getAppLogger, x } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { parallelize } from './utils/parallelize';\n\ntype FetchDistantDictionariesOptions = {\n dictionaryKeys: string[];\n newDictionariesPath?: string;\n logPrefix?: string;\n};\n\n/**\n * Fetch distant dictionaries and update the logger with their statuses.\n */\nexport const fetchDistantDictionaries = async (\n options: FetchDistantDictionariesOptions,\n onStatusUpdate?: (status: DictionariesStatus[]) => void\n): Promise<DictionaryAPI[]> => {\n const config = getConfiguration();\n const appLogger = getAppLogger(config);\n try {\n const dictionary = dictionaryEndpoint(createIntlayerCMS(config));\n\n const distantDictionariesKeys = options.dictionaryKeys;\n // Process dictionaries in parallel with a concurrency limit\n const processDictionary = async (\n dictionaryKey: string\n ): Promise<DictionaryAPI | undefined> => {\n onStatusUpdate?.([\n {\n dictionaryKey,\n type: 'remote',\n status: 'fetching',\n },\n ]);\n\n try {\n // Fetch the dictionary\n const getDictionaryResult =\n await dictionary.getDictionary(dictionaryKey);\n\n const distantDictionary = getDictionaryResult.data;\n\n if (!distantDictionary) {\n throw new Error(`Dictionary ${dictionaryKey} not found on remote`);\n }\n\n onStatusUpdate?.([\n { dictionaryKey, type: 'remote', status: 'fetched' },\n ]);\n\n return distantDictionary;\n } catch (error) {\n onStatusUpdate?.([\n {\n dictionaryKey,\n type: 'remote',\n status: 'error',\n error: `Error fetching dictionary ${dictionaryKey}: ${error}`,\n },\n ]);\n return undefined;\n }\n };\n\n const result = await parallelize(\n distantDictionariesKeys,\n async (dictionaryKey) => await processDictionary(dictionaryKey)\n );\n\n // Remove undefined values\n const filteredResult = result.filter(\n (dict: DictionaryAPI | undefined): dict is DictionaryAPI =>\n dict !== undefined\n );\n\n return filteredResult;\n } catch (_error) {\n appLogger(`${x} Failed to fetch distant dictionaries`, { level: 'error' });\n return [];\n }\n};\n"],"mappings":";;;;;;;;;;AAkBA,MAAa,2BAA2B,OACtC,SACA,mBAC6B;CAC7B,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"fetchDistantDictionaries.mjs","names":[],"sources":["../../src/fetchDistantDictionaries.ts"],"sourcesContent":["import { createIntlayerCMS } from '@intlayer/api';\nimport { dictionaryEndpoint } from '@intlayer/api/dictionary';\n// @ts-ignore @intlayer/backend is not build yet\nimport type { DictionaryAPI } from '@intlayer/backend';\nimport { getAppLogger, x } from '@intlayer/config/logger';\nimport { getConfiguration } from '@intlayer/config/node';\nimport type { DictionariesStatus } from './loadDictionaries';\nimport { parallelize } from './utils/parallelize';\n\ntype FetchDistantDictionariesOptions = {\n dictionaryKeys: string[];\n newDictionariesPath?: string;\n logPrefix?: string;\n};\n\n/**\n * Fetch distant dictionaries and update the logger with their statuses.\n */\nexport const fetchDistantDictionaries = async (\n options: FetchDistantDictionariesOptions,\n onStatusUpdate?: (status: DictionariesStatus[]) => void\n): Promise<DictionaryAPI[]> => {\n const config = getConfiguration();\n const appLogger = getAppLogger(config);\n try {\n const dictionary = dictionaryEndpoint(createIntlayerCMS(config));\n\n const distantDictionariesKeys = options.dictionaryKeys;\n // Process dictionaries in parallel with a concurrency limit\n const processDictionary = async (\n dictionaryKey: string\n ): Promise<DictionaryAPI | undefined> => {\n onStatusUpdate?.([\n {\n dictionaryKey,\n type: 'remote',\n status: 'fetching',\n },\n ]);\n\n try {\n // Fetch the dictionary\n const getDictionaryResult =\n await dictionary.getDictionary(dictionaryKey);\n\n const distantDictionary = getDictionaryResult.data;\n\n if (!distantDictionary) {\n throw new Error(`Dictionary ${dictionaryKey} not found on remote`);\n }\n\n onStatusUpdate?.([\n { dictionaryKey, type: 'remote', status: 'fetched' },\n ]);\n\n return distantDictionary;\n } catch (error) {\n onStatusUpdate?.([\n {\n dictionaryKey,\n type: 'remote',\n status: 'error',\n error: `Error fetching dictionary ${dictionaryKey}: ${error}`,\n },\n ]);\n return undefined;\n }\n };\n\n const result = await parallelize(\n distantDictionariesKeys,\n async (dictionaryKey) => await processDictionary(dictionaryKey)\n );\n\n // Remove undefined values\n const filteredResult = result.filter(\n (dict: DictionaryAPI | undefined): dict is DictionaryAPI =>\n dict !== undefined\n );\n\n return filteredResult;\n } catch (_error) {\n appLogger(`${x} Failed to fetch distant dictionaries`, { level: 'error' });\n return [];\n }\n};\n"],"mappings":";;;;;;;;;;AAkBA,MAAa,2BAA2B,OACtC,SACA,mBAC6B;CAC7B,MAAM,SAAS,iBAAiB;CAChC,MAAM,YAAY,aAAa,MAAM;CACrC,IAAI;EACF,MAAM,aAAa,mBAAmB,kBAAkB,MAAM,CAAC;EAE/D,MAAM,0BAA0B,QAAQ;EAExC,MAAM,oBAAoB,OACxB,kBACuC;GACvC,iBAAiB,CACf;IACE;IACA,MAAM;IACN,QAAQ;GACV,CACF,CAAC;GAED,IAAI;IAKF,MAAM,qBAAoB,MAFlB,WAAW,cAAc,aAAa,EAED,CAAC;IAE9C,IAAI,CAAC,mBACH,MAAM,IAAI,MAAM,cAAc,cAAc,qBAAqB;IAGnE,iBAAiB,CACf;KAAE;KAAe,MAAM;KAAU,QAAQ;IAAU,CACrD,CAAC;IAED,OAAO;GACT,SAAS,OAAO;IACd,iBAAiB,CACf;KACE;KACA,MAAM;KACN,QAAQ;KACR,OAAO,6BAA6B,cAAc,IAAI;IACxD,CACF,CAAC;IACD;GACF;EACF;EAaA,QALuB,MANF,YACnB,yBACA,OAAO,kBAAkB,MAAM,kBAAkB,aAAa,CAChE,EAG6B,CAAC,QAC3B,SACC,SAAS,MAGO;CACtB,SAAS,QAAQ;EACf,UAAU,GAAG,EAAE,wCAAwC,EAAE,OAAO,QAAQ,CAAC;EACzE,OAAO,CAAC;CACV;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterInvalidDictionaries.mjs","names":[],"sources":["../../src/filterInvalidDictionaries.ts"],"sourcesContent":["import * as ANSIColors from '@intlayer/config/colors';\nimport {\n colorize,\n colorizeKey,\n colorizePath,\n getAppLogger,\n x,\n} from '@intlayer/config/logger';\nimport { getBasePlugins, getContent } from '@intlayer/core/interpreter';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { formatLocale, formatPath } from './utils/formatter';\n\ntype IsInvalidDictionaryOptions = { checkSchema: boolean };\n\nexport const isInvalidDictionary = (\n dictionary: Dictionary | undefined,\n configuration?: IntlayerConfig,\n options?: IsInvalidDictionaryOptions\n): boolean => {\n const appLogger = getAppLogger(configuration);\n\n if (!dictionary) return false;\n\n const isLocal = Boolean(\n dictionary.location === 'local' || typeof dictionary.filePath === 'string'\n );\n const location = isLocal ? 'Local' : 'Remote';\n const hasKey = Boolean(dictionary.key);\n const hasContent = Boolean(dictionary.content);\n\n if (!hasKey) {\n appLogger(`${location} dictionary has no key`, {\n level: 'error',\n });\n\n return false;\n }\n\n // Reject keys that contain path-unsafe characters.\n // A key is used as a filename component ({key}.json), so slashes, backslashes,\n // null bytes, or pure dot-segments can escape the output directory or break\n // dictionary resolution.\n // Allows alphanumeric characters, dashes, and underscores.\n // Allows dots, but not as the first or last character, and no consecutive dots.\n // Allows chinese or russian characters e.g. 你好\n const isInsecureKey = !/^[\\p{L}\\p{N}]+([._-][\\p{L}\\p{N}]+)*$/u.test(\n dictionary.key\n );\n\n if (isInsecureKey) {\n appLogger(\n `Insecure key ${colorizeKey(dictionary.key)} at ${dictionary.filePath ? formatPath(dictionary.filePath) : colorizePath('Remote')} - dictionary filtered out`,\n { level: 'error' }\n );\n return false;\n }\n\n if (!hasContent) {\n appLogger(\n `${location} dictionary ${colorizeKey(dictionary.key)} has no content - ${dictionary.filePath ? formatPath(dictionary.filePath) : colorizePath('Remote')}`,\n {\n level: 'error',\n }\n );\n return false;\n }\n\n if (dictionary.schema && options?.checkSchema) {\n const isAsync =\n typeof dictionary.content === 'function' ||\n (typeof dictionary.content === 'object' &&\n dictionary.content !== null &&\n typeof (dictionary.content as any).then === 'function');\n\n if (!isAsync) {\n const locales = configuration?.internationalization?.locales ?? [];\n const isStrict =\n configuration?.internationalization.strictMode === 'strict';\n\n const schema =\n typeof dictionary.schema === 'string'\n ? configuration?.schemas?.[dictionary.schema]\n : undefined;\n\n if (schema && typeof schema.safeParse === 'function') {\n for (const locale of locales) {\n const resolvedContent = getContent(\n dictionary.content,\n {\n dictionaryKey: dictionary.key,\n keyPath: [],\n locale,\n },\n getBasePlugins(locale, !isStrict)\n );\n const result = (schema as any).safeParse(resolvedContent);\n\n if (!result.success) {\n appLogger(\n `${location} dictionary ${colorizeKey(dictionary.key)} has invalid content according to schema ${colorize(dictionary.schema as string, ANSIColors.ORANGE)} for locale ${formatLocale(locale)} - ${dictionary.filePath ? formatPath(dictionary.filePath) : colorizePath('Remote')}`,\n {\n level: 'error',\n }\n );\n\n result.error.issues.forEach((issue: any) => {\n appLogger(\n `${x} Error: ${colorizeKey(dictionary.key)} - ${formatLocale(locale)} - ${colorize(`${issue.path.join('.')}:`, ANSIColors.BLUE)} ${colorize(issue.message, ANSIColors.GREY)}`,\n {\n level: 'error',\n }\n );\n });\n\n return false;\n }\n }\n }\n }\n }\n\n return true;\n};\n\nexport const filterInvalidDictionaries = (\n dictionaries: (Dictionary | undefined)[] | undefined,\n configuration: IntlayerConfig,\n options?: IsInvalidDictionaryOptions\n): Dictionary[] =>\n (dictionaries ?? [])?.filter((dictionary) =>\n isInvalidDictionary(dictionary, configuration, options)\n ) as Dictionary[];\n"],"mappings":";;;;;;AAeA,MAAa,uBACX,YACA,eACA,YACY;CACZ,MAAM,YAAY,aAAa,
|
|
1
|
+
{"version":3,"file":"filterInvalidDictionaries.mjs","names":[],"sources":["../../src/filterInvalidDictionaries.ts"],"sourcesContent":["import * as ANSIColors from '@intlayer/config/colors';\nimport {\n colorize,\n colorizeKey,\n colorizePath,\n getAppLogger,\n x,\n} from '@intlayer/config/logger';\nimport { getBasePlugins, getContent } from '@intlayer/core/interpreter';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport type { Dictionary } from '@intlayer/types/dictionary';\nimport { formatLocale, formatPath } from './utils/formatter';\n\ntype IsInvalidDictionaryOptions = { checkSchema: boolean };\n\nexport const isInvalidDictionary = (\n dictionary: Dictionary | undefined,\n configuration?: IntlayerConfig,\n options?: IsInvalidDictionaryOptions\n): boolean => {\n const appLogger = getAppLogger(configuration);\n\n if (!dictionary) return false;\n\n const isLocal = Boolean(\n dictionary.location === 'local' || typeof dictionary.filePath === 'string'\n );\n const location = isLocal ? 'Local' : 'Remote';\n const hasKey = Boolean(dictionary.key);\n const hasContent = Boolean(dictionary.content);\n\n if (!hasKey) {\n appLogger(`${location} dictionary has no key`, {\n level: 'error',\n });\n\n return false;\n }\n\n // Reject keys that contain path-unsafe characters.\n // A key is used as a filename component ({key}.json), so slashes, backslashes,\n // null bytes, or pure dot-segments can escape the output directory or break\n // dictionary resolution.\n // Allows alphanumeric characters, dashes, and underscores.\n // Allows dots, but not as the first or last character, and no consecutive dots.\n // Allows chinese or russian characters e.g. 你好\n const isInsecureKey = !/^[\\p{L}\\p{N}]+([._-][\\p{L}\\p{N}]+)*$/u.test(\n dictionary.key\n );\n\n if (isInsecureKey) {\n appLogger(\n `Insecure key ${colorizeKey(dictionary.key)} at ${dictionary.filePath ? formatPath(dictionary.filePath) : colorizePath('Remote')} - dictionary filtered out`,\n { level: 'error' }\n );\n return false;\n }\n\n if (!hasContent) {\n appLogger(\n `${location} dictionary ${colorizeKey(dictionary.key)} has no content - ${dictionary.filePath ? formatPath(dictionary.filePath) : colorizePath('Remote')}`,\n {\n level: 'error',\n }\n );\n return false;\n }\n\n if (dictionary.schema && options?.checkSchema) {\n const isAsync =\n typeof dictionary.content === 'function' ||\n (typeof dictionary.content === 'object' &&\n dictionary.content !== null &&\n typeof (dictionary.content as any).then === 'function');\n\n if (!isAsync) {\n const locales = configuration?.internationalization?.locales ?? [];\n const isStrict =\n configuration?.internationalization.strictMode === 'strict';\n\n const schema =\n typeof dictionary.schema === 'string'\n ? configuration?.schemas?.[dictionary.schema]\n : undefined;\n\n if (schema && typeof schema.safeParse === 'function') {\n for (const locale of locales) {\n const resolvedContent = getContent(\n dictionary.content,\n {\n dictionaryKey: dictionary.key,\n keyPath: [],\n locale,\n },\n getBasePlugins(locale, !isStrict)\n );\n const result = (schema as any).safeParse(resolvedContent);\n\n if (!result.success) {\n appLogger(\n `${location} dictionary ${colorizeKey(dictionary.key)} has invalid content according to schema ${colorize(dictionary.schema as string, ANSIColors.ORANGE)} for locale ${formatLocale(locale)} - ${dictionary.filePath ? formatPath(dictionary.filePath) : colorizePath('Remote')}`,\n {\n level: 'error',\n }\n );\n\n result.error.issues.forEach((issue: any) => {\n appLogger(\n `${x} Error: ${colorizeKey(dictionary.key)} - ${formatLocale(locale)} - ${colorize(`${issue.path.join('.')}:`, ANSIColors.BLUE)} ${colorize(issue.message, ANSIColors.GREY)}`,\n {\n level: 'error',\n }\n );\n });\n\n return false;\n }\n }\n }\n }\n }\n\n return true;\n};\n\nexport const filterInvalidDictionaries = (\n dictionaries: (Dictionary | undefined)[] | undefined,\n configuration: IntlayerConfig,\n options?: IsInvalidDictionaryOptions\n): Dictionary[] =>\n (dictionaries ?? [])?.filter((dictionary) =>\n isInvalidDictionary(dictionary, configuration, options)\n ) as Dictionary[];\n"],"mappings":";;;;;;AAeA,MAAa,uBACX,YACA,eACA,YACY;CACZ,MAAM,YAAY,aAAa,aAAa;CAE5C,IAAI,CAAC,YAAY,OAAO;CAKxB,MAAM,WAHU,QACd,WAAW,aAAa,WAAW,OAAO,WAAW,aAAa,QAE7C,IAAI,UAAU;CACrC,MAAM,SAAS,QAAQ,WAAW,GAAG;CACrC,MAAM,aAAa,QAAQ,WAAW,OAAO;CAE7C,IAAI,CAAC,QAAQ;EACX,UAAU,GAAG,SAAS,yBAAyB,EAC7C,OAAO,QACT,CAAC;EAED,OAAO;CACT;CAaA,IAAI,CAJmB,wCAAwC,KAC7D,WAAW,GACb,GAEmB;EACjB,UACE,gBAAgB,YAAY,WAAW,GAAG,EAAE,MAAM,WAAW,WAAW,WAAW,WAAW,QAAQ,IAAI,aAAa,QAAQ,EAAE,6BACjI,EAAE,OAAO,QAAQ,CACnB;EACA,OAAO;CACT;CAEA,IAAI,CAAC,YAAY;EACf,UACE,GAAG,SAAS,cAAc,YAAY,WAAW,GAAG,EAAE,oBAAoB,WAAW,WAAW,WAAW,WAAW,QAAQ,IAAI,aAAa,QAAQ,KACvJ,EACE,OAAO,QACT,CACF;EACA,OAAO;CACT;CAEA,IAAI,WAAW,UAAU,SAAS,aAOhC;MAAI,EALF,OAAO,WAAW,YAAY,cAC7B,OAAO,WAAW,YAAY,YAC7B,WAAW,YAAY,QACvB,OAAQ,WAAW,QAAgB,SAAS,aAElC;GACZ,MAAM,UAAU,eAAe,sBAAsB,WAAW,CAAC;GACjE,MAAM,WACJ,eAAe,qBAAqB,eAAe;GAErD,MAAM,SACJ,OAAO,WAAW,WAAW,WACzB,eAAe,UAAU,WAAW,UACpC;GAEN,IAAI,UAAU,OAAO,OAAO,cAAc,YACxC,KAAK,MAAM,UAAU,SAAS;IAC5B,MAAM,kBAAkB,WACtB,WAAW,SACX;KACE,eAAe,WAAW;KAC1B,SAAS,CAAC;KACV;IACF,GACA,eAAe,QAAQ,CAAC,QAAQ,CAClC;IACA,MAAM,SAAU,OAAe,UAAU,eAAe;IAExD,IAAI,CAAC,OAAO,SAAS;KACnB,UACE,GAAG,SAAS,cAAc,YAAY,WAAW,GAAG,EAAE,2CAA2C,SAAS,WAAW,QAAkB,WAAW,MAAM,EAAE,cAAc,aAAa,MAAM,EAAE,KAAK,WAAW,WAAW,WAAW,WAAW,QAAQ,IAAI,aAAa,QAAQ,KAC/Q,EACE,OAAO,QACT,CACF;KAEA,OAAO,MAAM,OAAO,SAAS,UAAe;MAC1C,UACE,GAAG,EAAE,UAAU,YAAY,WAAW,GAAG,EAAE,KAAK,aAAa,MAAM,EAAE,KAAK,SAAS,GAAG,MAAM,KAAK,KAAK,GAAG,EAAE,IAAI,WAAW,IAAI,EAAE,GAAG,SAAS,MAAM,SAAS,WAAW,IAAI,KAC1K,EACE,OAAO,QACT,CACF;KACF,CAAC;KAED,OAAO;IACT;GACF;EAEJ;;CAGF,OAAO;AACT;AAEA,MAAa,6BACX,cACA,eACA,aAEC,gBAAgB,CAAC,EAAC,EAAG,QAAQ,eAC5B,oBAAoB,YAAY,eAAe,OAAO,CACxD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatDictionary.mjs","names":[],"sources":["../../src/formatDictionary.ts"],"sourcesContent":["import {\n i18nextToIntlayerFormatter,\n icuToIntlayerFormatter,\n intlayerToI18nextFormatter,\n intlayerToICUFormatter,\n intlayerToPortableObjectFormatter,\n intlayerToVueI18nFormatter,\n portableObjectToIntlayerFormatter,\n vueI18nToIntlayerFormatter,\n} from '@intlayer/core/messageFormat';\nimport type { Dictionary } from '@intlayer/types/dictionary';\n\nexport const formatDictionary = (dictionary: Dictionary): Dictionary => {\n if (dictionary.format === 'icu') {\n return {\n ...dictionary,\n format: 'intlayer',\n content: icuToIntlayerFormatter(dictionary.content),\n };\n }\n\n if (dictionary.format === 'i18next') {\n return {\n ...dictionary,\n format: 'intlayer',\n content: i18nextToIntlayerFormatter(dictionary.content),\n };\n }\n\n if (dictionary.format === 'vue-i18n') {\n return {\n ...dictionary,\n format: 'intlayer',\n content: vueI18nToIntlayerFormatter(dictionary.content),\n };\n }\n\n if (dictionary.format === 'po') {\n return {\n ...dictionary,\n format: 'intlayer',\n content: portableObjectToIntlayerFormatter(dictionary.content),\n };\n }\n\n return dictionary;\n};\n\nexport const formatDictionaries = async (\n dictionaries: Dictionary[]\n): Promise<Dictionary[]> => Promise.all(dictionaries.map(formatDictionary));\n\nexport const formatDictionaryOutput = (\n dictionary: Dictionary,\n format: Dictionary['format']\n) => {\n if (format === 'icu') {\n return {\n ...dictionary,\n format: 'icu',\n content: intlayerToICUFormatter(dictionary.content),\n };\n }\n\n if (format === 'i18next') {\n return {\n ...dictionary,\n format: 'i18next',\n content: intlayerToI18nextFormatter(dictionary.content),\n };\n }\n\n if (format === 'vue-i18n') {\n return {\n ...dictionary,\n format: 'vue-i18n',\n content: intlayerToVueI18nFormatter(dictionary.content),\n };\n }\n\n if (dictionary.format === 'po') {\n return {\n ...dictionary,\n format: 'po',\n content: intlayerToPortableObjectFormatter(dictionary.content),\n };\n }\n\n return dictionary;\n};\n\nexport const formatDictionariesOutput = (\n dictionaries: Dictionary[],\n format: Dictionary['format']\n) =>\n dictionaries.map((dictionary) => formatDictionaryOutput(dictionary, format));\n"],"mappings":";;;AAYA,MAAa,oBAAoB,eAAuC;
|
|
1
|
+
{"version":3,"file":"formatDictionary.mjs","names":[],"sources":["../../src/formatDictionary.ts"],"sourcesContent":["import {\n i18nextToIntlayerFormatter,\n icuToIntlayerFormatter,\n intlayerToI18nextFormatter,\n intlayerToICUFormatter,\n intlayerToPortableObjectFormatter,\n intlayerToVueI18nFormatter,\n portableObjectToIntlayerFormatter,\n vueI18nToIntlayerFormatter,\n} from '@intlayer/core/messageFormat';\nimport type { Dictionary } from '@intlayer/types/dictionary';\n\nexport const formatDictionary = (dictionary: Dictionary): Dictionary => {\n if (dictionary.format === 'icu') {\n return {\n ...dictionary,\n format: 'intlayer',\n content: icuToIntlayerFormatter(dictionary.content),\n };\n }\n\n if (dictionary.format === 'i18next') {\n return {\n ...dictionary,\n format: 'intlayer',\n content: i18nextToIntlayerFormatter(dictionary.content),\n };\n }\n\n if (dictionary.format === 'vue-i18n') {\n return {\n ...dictionary,\n format: 'intlayer',\n content: vueI18nToIntlayerFormatter(dictionary.content),\n };\n }\n\n if (dictionary.format === 'po') {\n return {\n ...dictionary,\n format: 'intlayer',\n content: portableObjectToIntlayerFormatter(dictionary.content),\n };\n }\n\n return dictionary;\n};\n\nexport const formatDictionaries = async (\n dictionaries: Dictionary[]\n): Promise<Dictionary[]> => Promise.all(dictionaries.map(formatDictionary));\n\nexport const formatDictionaryOutput = (\n dictionary: Dictionary,\n format: Dictionary['format']\n) => {\n if (format === 'icu') {\n return {\n ...dictionary,\n format: 'icu',\n content: intlayerToICUFormatter(dictionary.content),\n };\n }\n\n if (format === 'i18next') {\n return {\n ...dictionary,\n format: 'i18next',\n content: intlayerToI18nextFormatter(dictionary.content),\n };\n }\n\n if (format === 'vue-i18n') {\n return {\n ...dictionary,\n format: 'vue-i18n',\n content: intlayerToVueI18nFormatter(dictionary.content),\n };\n }\n\n if (dictionary.format === 'po') {\n return {\n ...dictionary,\n format: 'po',\n content: intlayerToPortableObjectFormatter(dictionary.content),\n };\n }\n\n return dictionary;\n};\n\nexport const formatDictionariesOutput = (\n dictionaries: Dictionary[],\n format: Dictionary['format']\n) =>\n dictionaries.map((dictionary) => formatDictionaryOutput(dictionary, format));\n"],"mappings":";;;AAYA,MAAa,oBAAoB,eAAuC;CACtE,IAAI,WAAW,WAAW,OACxB,OAAO;EACL,GAAG;EACH,QAAQ;EACR,SAAS,uBAAuB,WAAW,OAAO;CACpD;CAGF,IAAI,WAAW,WAAW,WACxB,OAAO;EACL,GAAG;EACH,QAAQ;EACR,SAAS,2BAA2B,WAAW,OAAO;CACxD;CAGF,IAAI,WAAW,WAAW,YACxB,OAAO;EACL,GAAG;EACH,QAAQ;EACR,SAAS,2BAA2B,WAAW,OAAO;CACxD;CAGF,IAAI,WAAW,WAAW,MACxB,OAAO;EACL,GAAG;EACH,QAAQ;EACR,SAAS,kCAAkC,WAAW,OAAO;CAC/D;CAGF,OAAO;AACT;AAEA,MAAa,qBAAqB,OAChC,iBAC0B,QAAQ,IAAI,aAAa,IAAI,gBAAgB,CAAC;AAE1E,MAAa,0BACX,YACA,WACG;CACH,IAAI,WAAW,OACb,OAAO;EACL,GAAG;EACH,QAAQ;EACR,SAAS,uBAAuB,WAAW,OAAO;CACpD;CAGF,IAAI,WAAW,WACb,OAAO;EACL,GAAG;EACH,QAAQ;EACR,SAAS,2BAA2B,WAAW,OAAO;CACxD;CAGF,IAAI,WAAW,YACb,OAAO;EACL,GAAG;EACH,QAAQ;EACR,SAAS,2BAA2B,WAAW,OAAO;CACxD;CAGF,IAAI,WAAW,WAAW,MACxB,OAAO;EACL,GAAG;EACH,QAAQ;EACR,SAAS,kCAAkC,WAAW,OAAO;CAC/D;CAGF,OAAO;AACT;AAEA,MAAa,4BACX,cACA,WAEA,aAAa,KAAK,eAAe,uBAAuB,YAAY,MAAM,CAAC"}
|
package/dist/esm/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getContentDeclarationFileTemplate.mjs","names":[],"sources":["../../../src/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.ts"],"sourcesContent":["import { kebabCaseToCamelCase } from '@intlayer/config/utils';\nimport type { Format } from '../utils/getFormatFromExtension';\n\nexport const getContentDeclarationFileTemplate = async (\n key: string,\n format: Format,\n fileParams: Record<string, any> = {},\n noMetadata?: boolean\n) => {\n const camelCaseKey = kebabCaseToCamelCase(key);\n const name = camelCaseKey.charAt(0).toLowerCase() + camelCaseKey.slice(1);\n\n const fileParamsString = Object.entries(fileParams)\n .filter(([, value]) => value !== undefined)\n .map(([paramKey, value]) => {\n const formattedKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(paramKey)\n ? paramKey\n : JSON.stringify(paramKey);\n\n const formattedValue =\n typeof value === 'object' || typeof value === 'string'\n ? JSON.stringify(value)\n : value;\n\n return `\\n ${formattedKey}: ${formattedValue},`;\n })\n .join('');\n\n let content: string;\n\n if (noMetadata) {\n content = '{}';\n } else if (format === 'json' || format === 'jsonc' || format === 'json5') {\n content = [\n '{',\n ' \"$schema\": \"https://intlayer.org/schema.json\",',\n ` \"key\": \"${key}\",${fileParamsString}`,\n ' \"content\": {',\n ' }',\n '}',\n ].join('\\n');\n } else {\n content = [\n '{',\n ` key: '${key}',${fileParamsString}`,\n ' content: {',\n ' },',\n '}',\n ].join('\\n');\n }\n\n const jsdoc = `/** @type {import('intlayer').Dictionary${noMetadata ? \"['content']\" : ''}} **/`;\n const satisfiesType = noMetadata ? \"Dictionary['content']\" : 'Dictionary';\n\n switch (format) {\n case 'yaml': {\n const yamlLines = [\n `key: ${key}`,\n ...(fileParams.locale ? [`locale: ${fileParams.locale}`] : []),\n ...(fileParams.title\n ? [`title: ${JSON.stringify(fileParams.title)}`]\n : []),\n ...(fileParams.description\n ? [`description: ${JSON.stringify(fileParams.description)}`]\n : []),\n ...(fileParams.tags?.length\n ? [\n 'tags:',\n ...(fileParams.tags as string[]).map(\n (tag) => ` - ${JSON.stringify(tag)}`\n ),\n ]\n : []),\n 'content: {}',\n ];\n return `${yamlLines.join('\\n')}\\n`;\n }\n\n case 'md': {\n const mdFrontmatterLines = [\n `key: ${key}`,\n ...(fileParams.locale ? [`locale: ${fileParams.locale}`] : []),\n ...(fileParams.title\n ? [`title: ${JSON.stringify(fileParams.title)}`]\n : []),\n ...(fileParams.description\n ? [`description: ${JSON.stringify(fileParams.description)}`]\n : []),\n ...(fileParams.tags?.length\n ? [\n 'tags:',\n ...(fileParams.tags as string[]).map(\n (t) => ` - ${JSON.stringify(t)}`\n ),\n ]\n : []),\n ];\n return ['---', ...mdFrontmatterLines, '---', '', ''].join('\\n');\n }\n\n case 'ts':\n return [\n \"import { type Dictionary } from 'intlayer';\",\n '',\n `const ${name}Content = ${content} satisfies ${satisfiesType};`,\n '',\n `export default ${name}Content;`,\n '',\n ].join('\\n');\n\n case 'cjs':\n return [\n jsdoc,\n `const ${name}Content = ${content};`,\n '',\n `module.exports = ${name}Content;`,\n '',\n ].join('\\n');\n\n case 'json':\n case 'jsonc':\n case 'json5':\n return [content, ''].join('\\n');\n\n default: // esm\n return [\n jsdoc,\n `const ${name}Content = ${content};`,\n '',\n `export default ${name}Content;`,\n '',\n ].join('\\n');\n }\n};\n"],"mappings":";;;AAGA,MAAa,oCAAoC,OAC/C,KACA,QACA,aAAkC,
|
|
1
|
+
{"version":3,"file":"getContentDeclarationFileTemplate.mjs","names":[],"sources":["../../../src/getContentDeclarationFileTemplate/getContentDeclarationFileTemplate.ts"],"sourcesContent":["import { kebabCaseToCamelCase } from '@intlayer/config/utils';\nimport type { Format } from '../utils/getFormatFromExtension';\n\nexport const getContentDeclarationFileTemplate = async (\n key: string,\n format: Format,\n fileParams: Record<string, any> = {},\n noMetadata?: boolean\n) => {\n const camelCaseKey = kebabCaseToCamelCase(key);\n const name = camelCaseKey.charAt(0).toLowerCase() + camelCaseKey.slice(1);\n\n const fileParamsString = Object.entries(fileParams)\n .filter(([, value]) => value !== undefined)\n .map(([paramKey, value]) => {\n const formattedKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(paramKey)\n ? paramKey\n : JSON.stringify(paramKey);\n\n const formattedValue =\n typeof value === 'object' || typeof value === 'string'\n ? JSON.stringify(value)\n : value;\n\n return `\\n ${formattedKey}: ${formattedValue},`;\n })\n .join('');\n\n let content: string;\n\n if (noMetadata) {\n content = '{}';\n } else if (format === 'json' || format === 'jsonc' || format === 'json5') {\n content = [\n '{',\n ' \"$schema\": \"https://intlayer.org/schema.json\",',\n ` \"key\": \"${key}\",${fileParamsString}`,\n ' \"content\": {',\n ' }',\n '}',\n ].join('\\n');\n } else {\n content = [\n '{',\n ` key: '${key}',${fileParamsString}`,\n ' content: {',\n ' },',\n '}',\n ].join('\\n');\n }\n\n const jsdoc = `/** @type {import('intlayer').Dictionary${noMetadata ? \"['content']\" : ''}} **/`;\n const satisfiesType = noMetadata ? \"Dictionary['content']\" : 'Dictionary';\n\n switch (format) {\n case 'yaml': {\n const yamlLines = [\n `key: ${key}`,\n ...(fileParams.locale ? [`locale: ${fileParams.locale}`] : []),\n ...(fileParams.title\n ? [`title: ${JSON.stringify(fileParams.title)}`]\n : []),\n ...(fileParams.description\n ? [`description: ${JSON.stringify(fileParams.description)}`]\n : []),\n ...(fileParams.tags?.length\n ? [\n 'tags:',\n ...(fileParams.tags as string[]).map(\n (tag) => ` - ${JSON.stringify(tag)}`\n ),\n ]\n : []),\n 'content: {}',\n ];\n return `${yamlLines.join('\\n')}\\n`;\n }\n\n case 'md': {\n const mdFrontmatterLines = [\n `key: ${key}`,\n ...(fileParams.locale ? [`locale: ${fileParams.locale}`] : []),\n ...(fileParams.title\n ? [`title: ${JSON.stringify(fileParams.title)}`]\n : []),\n ...(fileParams.description\n ? [`description: ${JSON.stringify(fileParams.description)}`]\n : []),\n ...(fileParams.tags?.length\n ? [\n 'tags:',\n ...(fileParams.tags as string[]).map(\n (t) => ` - ${JSON.stringify(t)}`\n ),\n ]\n : []),\n ];\n return ['---', ...mdFrontmatterLines, '---', '', ''].join('\\n');\n }\n\n case 'ts':\n return [\n \"import { type Dictionary } from 'intlayer';\",\n '',\n `const ${name}Content = ${content} satisfies ${satisfiesType};`,\n '',\n `export default ${name}Content;`,\n '',\n ].join('\\n');\n\n case 'cjs':\n return [\n jsdoc,\n `const ${name}Content = ${content};`,\n '',\n `module.exports = ${name}Content;`,\n '',\n ].join('\\n');\n\n case 'json':\n case 'jsonc':\n case 'json5':\n return [content, ''].join('\\n');\n\n default: // esm\n return [\n jsdoc,\n `const ${name}Content = ${content};`,\n '',\n `export default ${name}Content;`,\n '',\n ].join('\\n');\n }\n};\n"],"mappings":";;;AAGA,MAAa,oCAAoC,OAC/C,KACA,QACA,aAAkC,CAAC,GACnC,eACG;CACH,MAAM,eAAe,qBAAqB,GAAG;CAC7C,MAAM,OAAO,aAAa,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,aAAa,MAAM,CAAC;CAExE,MAAM,mBAAmB,OAAO,QAAQ,UAAU,CAAC,CAChD,QAAQ,GAAG,WAAW,UAAU,MAAS,CAAC,CAC1C,KAAK,CAAC,UAAU,WAAW;EAU1B,OAAO,OATc,6BAA6B,KAAK,QAAQ,IAC3D,WACA,KAAK,UAAU,QAAQ,EAOA,IAJzB,OAAO,UAAU,YAAY,OAAO,UAAU,WAC1C,KAAK,UAAU,KAAK,IACpB,MAEwC;CAChD,CAAC,CAAC,CACD,KAAK,EAAE;CAEV,IAAI;CAEJ,IAAI,YACF,UAAU;MACL,IAAI,WAAW,UAAU,WAAW,WAAW,WAAW,SAC/D,UAAU;EACR;EACA;EACA,aAAa,IAAI,IAAI;EACrB;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;MAEX,UAAU;EACR;EACA,WAAW,IAAI,IAAI;EACnB;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;CAGb,MAAM,QAAQ,2CAA2C,aAAa,gBAAgB,GAAG;CACzF,MAAM,gBAAgB,aAAa,0BAA0B;CAE7D,QAAQ,QAAR;EACE,KAAK,QAoBH,OAAO,GAAG;GAlBR,QAAQ;GACR,GAAI,WAAW,SAAS,CAAC,WAAW,WAAW,QAAQ,IAAI,CAAC;GAC5D,GAAI,WAAW,QACX,CAAC,UAAU,KAAK,UAAU,WAAW,KAAK,GAAG,IAC7C,CAAC;GACL,GAAI,WAAW,cACX,CAAC,gBAAgB,KAAK,UAAU,WAAW,WAAW,GAAG,IACzD,CAAC;GACL,GAAI,WAAW,MAAM,SACjB,CACE,SACA,GAAI,WAAW,KAAkB,KAC9B,QAAQ,OAAO,KAAK,UAAU,GAAG,GACpC,CACF,IACA,CAAC;GACL;EAEgB,CAAC,CAAC,KAAK,IAAI,EAAE;EAGjC,KAAK,MAmBH,OAAO;GAAC;GAAO,GAAG;IAjBhB,QAAQ;IACR,GAAI,WAAW,SAAS,CAAC,WAAW,WAAW,QAAQ,IAAI,CAAC;IAC5D,GAAI,WAAW,QACX,CAAC,UAAU,KAAK,UAAU,WAAW,KAAK,GAAG,IAC7C,CAAC;IACL,GAAI,WAAW,cACX,CAAC,gBAAgB,KAAK,UAAU,WAAW,WAAW,GAAG,IACzD,CAAC;IACL,GAAI,WAAW,MAAM,SACjB,CACE,SACA,GAAI,WAAW,KAAkB,KAC9B,MAAM,OAAO,KAAK,UAAU,CAAC,GAChC,CACF,IACA,CAAC;GAE4B;GAAG;GAAO;GAAI;EAAE,CAAC,CAAC,KAAK,IAAI;EAGhE,KAAK,MACH,OAAO;GACL;GACA;GACA,SAAS,KAAK,YAAY,QAAQ,aAAa,cAAc;GAC7D;GACA,kBAAkB,KAAK;GACvB;EACF,CAAC,CAAC,KAAK,IAAI;EAEb,KAAK,OACH,OAAO;GACL;GACA,SAAS,KAAK,YAAY,QAAQ;GAClC;GACA,oBAAoB,KAAK;GACzB;EACF,CAAC,CAAC,KAAK,IAAI;EAEb,KAAK;EACL,KAAK;EACL,KAAK,SACH,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,KAAK,IAAI;EAEhC,SACE,OAAO;GACL;GACA,SAAS,KAAK,YAAY,QAAQ;GAClC;GACA,kBAAkB,KAAK;GACvB;EACF,CAAC,CAAC,KAAK,IAAI;CACf;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleAdditionalContentDeclarationFile.mjs","names":[],"sources":["../../src/handleAdditionalContentDeclarationFile.ts"],"sourcesContent":["import { getAppLogger } from '@intlayer/config/logger';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { buildDictionary } from './buildIntlayerDictionary/buildIntlayerDictionary';\nimport { createDictionaryEntryPoint } from './createDictionaryEntryPoint/createDictionaryEntryPoint';\nimport { createModuleAugmentation, createTypes } from './createType/index';\nimport { loadLocalDictionaries } from './loadDictionaries/loadLocalDictionaries';\nimport { formatPath } from './utils/formatter';\n\nexport const handleAdditionalContentDeclarationFile = async (\n filePath: string,\n config: IntlayerConfig\n) => {\n const appLogger = getAppLogger(config);\n\n // Process the file with the functionToRun\n appLogger(`Additional file detected: ${formatPath(filePath)}`, {\n isVerbose: true,\n });\n\n const localeDictionaries = await loadLocalDictionaries(filePath, config);\n\n const dictionariesOutput = await buildDictionary(localeDictionaries, config);\n\n const dictionariesToBuild = Object.values(\n dictionariesOutput?.mergedDictionaries ?? {}\n ).map((dictionary) => dictionary.dictionary);\n\n await createTypes(dictionariesToBuild, config);\n\n await createDictionaryEntryPoint(config);\n\n appLogger('Dictionaries built', {\n isVerbose: true,\n });\n\n await createModuleAugmentation(config);\n\n appLogger('Module augmentation built', {\n isVerbose: true,\n });\n\n // Plugin transformation\n // Allow plugins to post-process the final build output (e.g., write back ICU JSON)\n for await (const plugin of config.plugins ?? []) {\n const { unmergedDictionaries, mergedDictionaries } = dictionariesOutput;\n\n await plugin.afterBuild?.({\n dictionaries: {\n unmergedDictionaries,\n mergedDictionaries,\n },\n configuration: config,\n });\n }\n};\n"],"mappings":";;;;;;;;;AAQA,MAAa,yCAAyC,OACpD,UACA,WACG;CACH,MAAM,YAAY,aAAa,
|
|
1
|
+
{"version":3,"file":"handleAdditionalContentDeclarationFile.mjs","names":[],"sources":["../../src/handleAdditionalContentDeclarationFile.ts"],"sourcesContent":["import { getAppLogger } from '@intlayer/config/logger';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { buildDictionary } from './buildIntlayerDictionary/buildIntlayerDictionary';\nimport { createDictionaryEntryPoint } from './createDictionaryEntryPoint/createDictionaryEntryPoint';\nimport { createModuleAugmentation, createTypes } from './createType/index';\nimport { loadLocalDictionaries } from './loadDictionaries/loadLocalDictionaries';\nimport { formatPath } from './utils/formatter';\n\nexport const handleAdditionalContentDeclarationFile = async (\n filePath: string,\n config: IntlayerConfig\n) => {\n const appLogger = getAppLogger(config);\n\n // Process the file with the functionToRun\n appLogger(`Additional file detected: ${formatPath(filePath)}`, {\n isVerbose: true,\n });\n\n const localeDictionaries = await loadLocalDictionaries(filePath, config);\n\n const dictionariesOutput = await buildDictionary(localeDictionaries, config);\n\n const dictionariesToBuild = Object.values(\n dictionariesOutput?.mergedDictionaries ?? {}\n ).map((dictionary) => dictionary.dictionary);\n\n await createTypes(dictionariesToBuild, config);\n\n await createDictionaryEntryPoint(config);\n\n appLogger('Dictionaries built', {\n isVerbose: true,\n });\n\n await createModuleAugmentation(config);\n\n appLogger('Module augmentation built', {\n isVerbose: true,\n });\n\n // Plugin transformation\n // Allow plugins to post-process the final build output (e.g., write back ICU JSON)\n for await (const plugin of config.plugins ?? []) {\n const { unmergedDictionaries, mergedDictionaries } = dictionariesOutput;\n\n await plugin.afterBuild?.({\n dictionaries: {\n unmergedDictionaries,\n mergedDictionaries,\n },\n configuration: config,\n });\n }\n};\n"],"mappings":";;;;;;;;;AAQA,MAAa,yCAAyC,OACpD,UACA,WACG;CACH,MAAM,YAAY,aAAa,MAAM;CAGrC,UAAU,6BAA6B,WAAW,QAAQ,KAAK,EAC7D,WAAW,KACb,CAAC;CAID,MAAM,qBAAqB,MAAM,gBAAgB,MAFhB,sBAAsB,UAAU,MAAM,GAEF,MAAM;CAM3E,MAAM,YAJsB,OAAO,OACjC,oBAAoB,sBAAsB,CAAC,CAC7C,CAAC,CAAC,KAAK,eAAe,WAAW,UAEG,GAAG,MAAM;CAE7C,MAAM,2BAA2B,MAAM;CAEvC,UAAU,sBAAsB,EAC9B,WAAW,KACb,CAAC;CAED,MAAM,yBAAyB,MAAM;CAErC,UAAU,6BAA6B,EACrC,WAAW,KACb,CAAC;CAID,WAAW,MAAM,UAAU,OAAO,WAAW,CAAC,GAAG;EAC/C,MAAM,EAAE,sBAAsB,uBAAuB;EAErD,MAAM,OAAO,aAAa;GACxB,cAAc;IACZ;IACA;GACF;GACA,eAAe;EACjB,CAAC;CACH;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleContentDeclarationFileChange.mjs","names":[],"sources":["../../src/handleContentDeclarationFileChange.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { getAppLogger } from '@intlayer/config/logger';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { buildDictionary } from './buildIntlayerDictionary/buildIntlayerDictionary';\nimport { cleanRemovedContentDeclaration } from './cleanRemovedContentDeclaration';\nimport { createDictionaryEntryPoint } from './createDictionaryEntryPoint/createDictionaryEntryPoint';\nimport { getBuiltDictionariesPath } from './createDictionaryEntryPoint/getBuiltDictionariesPath';\nimport { createTypes } from './createType';\nimport { createModuleAugmentation } from './createType/createModuleAugmentation';\nimport { loadLocalDictionaries } from './loadDictionaries/loadLocalDictionaries';\nimport { formatPath } from './utils/formatter';\n\nexport const handleContentDeclarationFileChange = async (\n filePath: string,\n config: IntlayerConfig\n) => {\n const appLogger = getAppLogger(config);\n\n // Process the file with the functionToRun\n appLogger(`Change detected: ${formatPath(filePath)}`, {\n isVerbose: true,\n });\n\n const allDictionariesPaths: string[] = await getBuiltDictionariesPath(config);\n\n const localeDictionaries = await loadLocalDictionaries(filePath, config);\n\n const dictionariesOutput = await buildDictionary(localeDictionaries, config);\n const updatedDictionaries = Object.values(\n dictionariesOutput?.mergedDictionaries ?? {}\n );\n const updatedDictionariesPaths = updatedDictionaries.map(\n (dictionary) => dictionary.dictionaryPath\n );\n\n const { excludeKeys, hasRebuilt } = await cleanRemovedContentDeclaration(\n filePath,\n localeDictionaries.map((dictionary) => dictionary.key),\n config\n );\n\n const hasNewDictionaries = updatedDictionariesPaths.some(\n (updatedDictionaryPath) =>\n !allDictionariesPaths.includes(updatedDictionaryPath)\n );\n\n // Rebuild Types first — types must be ready before anything triggers a bundler rebuild.\n // esbuild (used by Angular, Vite, etc.) only watches files in its JS bundle graph; it does\n // NOT watch .intlayer/types/*.ts (TypeScript-only files). Generating types here, before\n // updating the entry point, guarantees that when the entry point write below fires esbuild's\n // file watcher the types are already up-to-date.\n const dictionariesToBuild = updatedDictionaries.map(\n (dictionary) => dictionary.dictionary\n );\n\n await createTypes(dictionariesToBuild, config);\n appLogger('TypeScript types built', {\n isVerbose: true,\n });\n\n // Always regenerate the module augmentation so that structural changes to existing\n // dictionaries (new content keys, type changes) are reflected in intlayer.d.ts.\n await createModuleAugmentation(config);\n appLogger('Module augmentation built', {\n isVerbose: true,\n });\n\n // Rebuild Entry Point\n // Only needed when the *list* of dictionaries changed (Add/Remove/Rename).\n if (hasRebuilt || hasNewDictionaries) {\n // If hasRebuilt is true, cleanRemovedContentDeclaration has already updated the entry point\n // to remove the old keys (and it likely included the new ones if they were already on disk).\n // If NOT hasRebuilt, we explicitly need to update the entry point to include the new dictionaries.\n if (!hasRebuilt) {\n await createDictionaryEntryPoint(config, { excludeKeys });\n appLogger('Dictionary list built', {\n isVerbose: true,\n });\n }\n }\n\n // Force-write the entry point files so esbuild detects a change and triggers a fresh rebuild\n // now that all types are ready. Without this, the only rebuild esbuild sees is the one\n // triggered by buildDictionary's JSON writes above — which races against type generation\n // and often runs before the new .intlayer/types/*.ts files are on disk.\n const { mainDir } = config.system;\n\n for (const extension of config.build.outputFormat) {\n const entryPointPath = join(mainDir, `dictionaries.${extension}`);\n\n if (existsSync(entryPointPath)) {\n const content = await readFile(entryPointPath, 'utf-8');\n await writeFile(entryPointPath, content);\n }\n }\n\n // Plugin transformation\n // Allow plugins to post-process the final build output (e.g., write back ICU JSON)\n for await (const plugin of config.plugins ?? []) {\n const { unmergedDictionaries, mergedDictionaries } = dictionariesOutput;\n\n await plugin.afterBuild?.({\n dictionaries: {\n unmergedDictionaries,\n mergedDictionaries,\n },\n configuration: config,\n });\n }\n};\n"],"mappings":";;;;;;;;;;;;;;AAcA,MAAa,qCAAqC,OAChD,UACA,WACG;CACH,MAAM,YAAY,aAAa,
|
|
1
|
+
{"version":3,"file":"handleContentDeclarationFileChange.mjs","names":[],"sources":["../../src/handleContentDeclarationFileChange.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { getAppLogger } from '@intlayer/config/logger';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { buildDictionary } from './buildIntlayerDictionary/buildIntlayerDictionary';\nimport { cleanRemovedContentDeclaration } from './cleanRemovedContentDeclaration';\nimport { createDictionaryEntryPoint } from './createDictionaryEntryPoint/createDictionaryEntryPoint';\nimport { getBuiltDictionariesPath } from './createDictionaryEntryPoint/getBuiltDictionariesPath';\nimport { createTypes } from './createType';\nimport { createModuleAugmentation } from './createType/createModuleAugmentation';\nimport { loadLocalDictionaries } from './loadDictionaries/loadLocalDictionaries';\nimport { formatPath } from './utils/formatter';\n\nexport const handleContentDeclarationFileChange = async (\n filePath: string,\n config: IntlayerConfig\n) => {\n const appLogger = getAppLogger(config);\n\n // Process the file with the functionToRun\n appLogger(`Change detected: ${formatPath(filePath)}`, {\n isVerbose: true,\n });\n\n const allDictionariesPaths: string[] = await getBuiltDictionariesPath(config);\n\n const localeDictionaries = await loadLocalDictionaries(filePath, config);\n\n const dictionariesOutput = await buildDictionary(localeDictionaries, config);\n const updatedDictionaries = Object.values(\n dictionariesOutput?.mergedDictionaries ?? {}\n );\n const updatedDictionariesPaths = updatedDictionaries.map(\n (dictionary) => dictionary.dictionaryPath\n );\n\n const { excludeKeys, hasRebuilt } = await cleanRemovedContentDeclaration(\n filePath,\n localeDictionaries.map((dictionary) => dictionary.key),\n config\n );\n\n const hasNewDictionaries = updatedDictionariesPaths.some(\n (updatedDictionaryPath) =>\n !allDictionariesPaths.includes(updatedDictionaryPath)\n );\n\n // Rebuild Types first — types must be ready before anything triggers a bundler rebuild.\n // esbuild (used by Angular, Vite, etc.) only watches files in its JS bundle graph; it does\n // NOT watch .intlayer/types/*.ts (TypeScript-only files). Generating types here, before\n // updating the entry point, guarantees that when the entry point write below fires esbuild's\n // file watcher the types are already up-to-date.\n const dictionariesToBuild = updatedDictionaries.map(\n (dictionary) => dictionary.dictionary\n );\n\n await createTypes(dictionariesToBuild, config);\n appLogger('TypeScript types built', {\n isVerbose: true,\n });\n\n // Always regenerate the module augmentation so that structural changes to existing\n // dictionaries (new content keys, type changes) are reflected in intlayer.d.ts.\n await createModuleAugmentation(config);\n appLogger('Module augmentation built', {\n isVerbose: true,\n });\n\n // Rebuild Entry Point\n // Only needed when the *list* of dictionaries changed (Add/Remove/Rename).\n if (hasRebuilt || hasNewDictionaries) {\n // If hasRebuilt is true, cleanRemovedContentDeclaration has already updated the entry point\n // to remove the old keys (and it likely included the new ones if they were already on disk).\n // If NOT hasRebuilt, we explicitly need to update the entry point to include the new dictionaries.\n if (!hasRebuilt) {\n await createDictionaryEntryPoint(config, { excludeKeys });\n appLogger('Dictionary list built', {\n isVerbose: true,\n });\n }\n }\n\n // Force-write the entry point files so esbuild detects a change and triggers a fresh rebuild\n // now that all types are ready. Without this, the only rebuild esbuild sees is the one\n // triggered by buildDictionary's JSON writes above — which races against type generation\n // and often runs before the new .intlayer/types/*.ts files are on disk.\n const { mainDir } = config.system;\n\n for (const extension of config.build.outputFormat) {\n const entryPointPath = join(mainDir, `dictionaries.${extension}`);\n\n if (existsSync(entryPointPath)) {\n const content = await readFile(entryPointPath, 'utf-8');\n await writeFile(entryPointPath, content);\n }\n }\n\n // Plugin transformation\n // Allow plugins to post-process the final build output (e.g., write back ICU JSON)\n for await (const plugin of config.plugins ?? []) {\n const { unmergedDictionaries, mergedDictionaries } = dictionariesOutput;\n\n await plugin.afterBuild?.({\n dictionaries: {\n unmergedDictionaries,\n mergedDictionaries,\n },\n configuration: config,\n });\n }\n};\n"],"mappings":";;;;;;;;;;;;;;AAcA,MAAa,qCAAqC,OAChD,UACA,WACG;CACH,MAAM,YAAY,aAAa,MAAM;CAGrC,UAAU,oBAAoB,WAAW,QAAQ,KAAK,EACpD,WAAW,KACb,CAAC;CAED,MAAM,uBAAiC,MAAM,yBAAyB,MAAM;CAE5E,MAAM,qBAAqB,MAAM,sBAAsB,UAAU,MAAM;CAEvE,MAAM,qBAAqB,MAAM,gBAAgB,oBAAoB,MAAM;CAC3E,MAAM,sBAAsB,OAAO,OACjC,oBAAoB,sBAAsB,CAAC,CAC7C;CACA,MAAM,2BAA2B,oBAAoB,KAClD,eAAe,WAAW,cAC7B;CAEA,MAAM,EAAE,aAAa,eAAe,MAAM,+BACxC,UACA,mBAAmB,KAAK,eAAe,WAAW,GAAG,GACrD,MACF;CAEA,MAAM,qBAAqB,yBAAyB,MACjD,0BACC,CAAC,qBAAqB,SAAS,qBAAqB,CACxD;CAWA,MAAM,YAJsB,oBAAoB,KAC7C,eAAe,WAAW,UAGO,GAAG,MAAM;CAC7C,UAAU,0BAA0B,EAClC,WAAW,KACb,CAAC;CAID,MAAM,yBAAyB,MAAM;CACrC,UAAU,6BAA6B,EACrC,WAAW,KACb,CAAC;CAID,IAAI,cAAc,oBAIhB;MAAI,CAAC,YAAY;GACf,MAAM,2BAA2B,QAAQ,EAAE,YAAY,CAAC;GACxD,UAAU,yBAAyB,EACjC,WAAW,KACb,CAAC;EACH;;CAOF,MAAM,EAAE,YAAY,OAAO;CAE3B,KAAK,MAAM,aAAa,OAAO,MAAM,cAAc;EACjD,MAAM,iBAAiB,KAAK,SAAS,gBAAgB,WAAW;EAEhE,IAAI,WAAW,cAAc,GAE3B,MAAM,UAAU,gBAAgB,MADV,SAAS,gBAAgB,OAAO,CACf;CAE3C;CAIA,WAAW,MAAM,UAAU,OAAO,WAAW,CAAC,GAAG;EAC/C,MAAM,EAAE,sBAAsB,uBAAuB;EAErD,MAAM,OAAO,aAAa;GACxB,cAAc;IACZ;IACA;GACF;GACA,eAAe;EACjB,CAAC;CACH;AACF"}
|