@intlayer/cli 9.6.0 → 9.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/IntlayerEventListener.cjs +1 -2
- package/dist/cjs/IntlayerEventListener.cjs.map +1 -1
- package/dist/cjs/_virtual/_rolldown/runtime.cjs +1 -2
- package/dist/cjs/_virtual/_utils_asset.cjs +2 -3
- package/dist/cjs/auth/login.cjs +19 -9
- package/dist/cjs/auth/login.cjs.map +1 -1
- package/dist/cjs/auth/sessionToken.cjs +1 -2
- package/dist/cjs/auth/setupRepository.cjs +94 -0
- package/dist/cjs/auth/setupRepository.cjs.map +1 -0
- package/dist/cjs/build.cjs +2 -3
- package/dist/cjs/bundle.cjs +1 -2
- package/dist/cjs/ci.cjs +2 -3
- package/dist/cjs/cli.cjs +17 -12
- package/dist/cjs/cli.cjs.map +1 -1
- package/dist/cjs/config.cjs +2 -3
- package/dist/cjs/editor.cjs +62 -34
- package/dist/cjs/editor.cjs.map +1 -1
- package/dist/cjs/extract.cjs +7 -8
- package/dist/cjs/fill/deepMergeContent.cjs +1 -2
- package/dist/cjs/fill/extractTranslatableContent.cjs +1 -2
- package/dist/cjs/fill/fill.cjs +9 -10
- package/dist/cjs/fill/fill.cjs.map +1 -1
- package/dist/cjs/fill/formatAutoFilledFilePath.cjs +2 -3
- package/dist/cjs/fill/formatFillData.cjs +2 -3
- package/dist/cjs/fill/getAvailableLocalesInDictionary.cjs +1 -2
- package/dist/cjs/fill/getFilterMissingContentPerLocale.cjs +1 -2
- package/dist/cjs/fill/index.cjs +2 -2
- package/dist/cjs/fill/listTranslationsTasks.cjs +4 -5
- package/dist/cjs/fill/translateDictionary.cjs +6 -7
- package/dist/cjs/fill/translateDictionary.cjs.map +1 -1
- package/dist/cjs/fill/writeFill.cjs +4 -5
- package/dist/cjs/getTargetDictionary.cjs +2 -3
- package/dist/cjs/index.cjs +37 -23
- package/dist/cjs/init.cjs +175 -22
- package/dist/cjs/init.cjs.map +1 -1
- package/dist/cjs/initChromeExtension.cjs +5 -6
- package/dist/cjs/initInfra.cjs +3 -4
- package/dist/cjs/initMCP.cjs +6 -7
- package/dist/cjs/initSkills.cjs +6 -7
- package/dist/cjs/listContentDeclaration.cjs +3 -4
- package/dist/cjs/listProjects.cjs +1 -2
- package/dist/cjs/liveSync.cjs +4 -5
- package/dist/cjs/liveSync.cjs.map +1 -1
- package/dist/cjs/loadPrompts.cjs +1 -2
- package/dist/cjs/pull.cjs +9 -11
- package/dist/cjs/pull.cjs.map +1 -1
- package/dist/cjs/push/pullLog.cjs +2 -3
- package/dist/cjs/push/push.cjs +10 -10
- package/dist/cjs/push/push.cjs.map +1 -1
- package/dist/cjs/pushConfig.cjs +4 -5
- package/dist/cjs/pushLog.cjs +2 -3
- package/dist/cjs/reviewDoc/reviewDoc.cjs +15 -15
- package/dist/cjs/reviewDoc/reviewDoc.cjs.map +1 -1
- package/dist/cjs/reviewDoc/reviewDocBlockAware.cjs +8 -9
- package/dist/cjs/reviewDoc/reviewDocBlockAware.cjs.map +1 -1
- package/dist/cjs/reviewDoc/reviewDocLog.cjs +2 -3
- package/dist/cjs/reviewDoc/reviewDocProgress.cjs +2 -3
- package/dist/cjs/reviewDoc/reviewDocSynthesis.cjs +2 -3
- package/dist/cjs/scan.cjs +2 -3
- package/dist/cjs/searchDoc.cjs +2 -3
- package/dist/cjs/test/index.cjs +2 -2
- package/dist/cjs/test/listMissingTranslations.cjs +2 -3
- package/dist/cjs/test/test.cjs +3 -4
- package/dist/cjs/translateDoc/index.cjs +3 -3
- package/dist/cjs/translateDoc/translateDoc.cjs +12 -13
- package/dist/cjs/translateDoc/translateDoc.cjs.map +1 -1
- package/dist/cjs/translateDoc/translateFile.cjs +8 -9
- package/dist/cjs/translateDoc/validation.cjs +1 -2
- package/dist/cjs/upgrade.cjs +2 -3
- package/dist/cjs/utils/calculateChunks.cjs +1 -2
- package/dist/cjs/utils/checkAccess.cjs +5 -6
- package/dist/cjs/utils/checkAccess.cjs.map +1 -1
- package/dist/cjs/utils/checkConfigConsistency.cjs +1 -2
- package/dist/cjs/utils/checkFileModifiedRange.cjs +3 -4
- package/dist/cjs/utils/checkLastUpdateTime.cjs +1 -2
- package/dist/cjs/utils/chunkInference.cjs +2 -3
- package/dist/cjs/utils/detectGitRepository.cjs +86 -0
- package/dist/cjs/utils/detectGitRepository.cjs.map +1 -0
- package/dist/cjs/utils/fixChunkStartEndChars.cjs +1 -2
- package/dist/cjs/utils/formatLineRanges.cjs +1 -2
- package/dist/cjs/utils/formatTimeDiff.cjs +1 -2
- package/dist/cjs/utils/getIsFileUpdatedRecently.cjs +1 -2
- package/dist/cjs/utils/getOutputFilePath.cjs +1 -2
- package/dist/cjs/utils/getParentPackageJSON.cjs +2 -3
- package/dist/cjs/utils/isInteractiveTerminal.cjs +1 -2
- package/dist/cjs/utils/listSpecialChars.cjs +1 -2
- package/dist/cjs/utils/mapChunksBetweenFiles.cjs +2 -3
- package/dist/cjs/utils/openBrowser.cjs +1 -2
- package/dist/cjs/utils/parseChoice.cjs +1 -2
- package/dist/cjs/utils/reorderParagraphs.cjs +2 -3
- package/dist/cjs/utils/selectCmsEnvironment.cjs +2 -3
- package/dist/cjs/utils/setupAI.cjs +3 -4
- package/dist/cjs/watch.cjs +2 -3
- package/dist/esm/IntlayerEventListener.mjs +1 -2
- package/dist/esm/IntlayerEventListener.mjs.map +1 -1
- package/dist/esm/_virtual/_rolldown/runtime.mjs +1 -2
- package/dist/esm/_virtual/_utils_asset.mjs +2 -3
- package/dist/esm/auth/login.mjs +15 -5
- package/dist/esm/auth/login.mjs.map +1 -1
- package/dist/esm/auth/sessionToken.mjs +1 -2
- package/dist/esm/auth/setupRepository.mjs +89 -0
- package/dist/esm/auth/setupRepository.mjs.map +1 -0
- package/dist/esm/build.mjs +2 -3
- package/dist/esm/bundle.mjs +1 -2
- package/dist/esm/ci.mjs +2 -3
- package/dist/esm/cli.mjs +16 -11
- package/dist/esm/cli.mjs.map +1 -1
- package/dist/esm/config.mjs +2 -3
- package/dist/esm/editor.mjs +63 -36
- package/dist/esm/editor.mjs.map +1 -1
- package/dist/esm/extract.mjs +5 -6
- package/dist/esm/fill/deepMergeContent.mjs +1 -2
- package/dist/esm/fill/extractTranslatableContent.mjs +1 -2
- package/dist/esm/fill/fill.mjs +3 -4
- package/dist/esm/fill/fill.mjs.map +1 -1
- package/dist/esm/fill/formatAutoFilledFilePath.mjs +2 -3
- package/dist/esm/fill/formatFillData.mjs +1 -2
- package/dist/esm/fill/getAvailableLocalesInDictionary.mjs +1 -2
- package/dist/esm/fill/getFilterMissingContentPerLocale.mjs +1 -2
- package/dist/esm/fill/index.mjs +1 -1
- package/dist/esm/fill/listTranslationsTasks.mjs +2 -3
- package/dist/esm/fill/translateDictionary.mjs +2 -3
- package/dist/esm/fill/translateDictionary.mjs.map +1 -1
- package/dist/esm/fill/writeFill.mjs +2 -3
- package/dist/esm/getTargetDictionary.mjs +2 -3
- package/dist/esm/index.mjs +15 -11
- package/dist/esm/init.mjs +169 -20
- package/dist/esm/init.mjs.map +1 -1
- package/dist/esm/initChromeExtension.mjs +2 -3
- package/dist/esm/initInfra.mjs +1 -2
- package/dist/esm/initMCP.mjs +3 -4
- package/dist/esm/initSkills.mjs +2 -3
- package/dist/esm/listContentDeclaration.mjs +3 -4
- package/dist/esm/listProjects.mjs +1 -2
- package/dist/esm/liveSync.mjs +2 -3
- package/dist/esm/liveSync.mjs.map +1 -1
- package/dist/esm/loadPrompts.mjs +1 -2
- package/dist/esm/pull.mjs +6 -8
- package/dist/esm/pull.mjs.map +1 -1
- package/dist/esm/push/pullLog.mjs +1 -2
- package/dist/esm/push/push.mjs +6 -6
- package/dist/esm/push/push.mjs.map +1 -1
- package/dist/esm/pushConfig.mjs +2 -3
- package/dist/esm/pushLog.mjs +1 -2
- package/dist/esm/reviewDoc/reviewDoc.mjs +8 -8
- package/dist/esm/reviewDoc/reviewDoc.mjs.map +1 -1
- package/dist/esm/reviewDoc/reviewDocBlockAware.mjs +3 -4
- package/dist/esm/reviewDoc/reviewDocBlockAware.mjs.map +1 -1
- package/dist/esm/reviewDoc/reviewDocLog.mjs +2 -3
- package/dist/esm/reviewDoc/reviewDocProgress.mjs +1 -2
- package/dist/esm/reviewDoc/reviewDocSynthesis.mjs +1 -2
- package/dist/esm/scan.mjs +1 -2
- package/dist/esm/searchDoc.mjs +2 -3
- package/dist/esm/test/listMissingTranslations.mjs +2 -3
- package/dist/esm/test/test.mjs +1 -2
- package/dist/esm/translateDoc/index.mjs +2 -2
- package/dist/esm/translateDoc/translateDoc.mjs +7 -8
- package/dist/esm/translateDoc/translateDoc.mjs.map +1 -1
- package/dist/esm/translateDoc/translateFile.mjs +4 -5
- package/dist/esm/translateDoc/validation.mjs +1 -2
- package/dist/esm/upgrade.mjs +1 -2
- package/dist/esm/utils/calculateChunks.mjs +1 -2
- package/dist/esm/utils/checkAccess.mjs +2 -3
- package/dist/esm/utils/checkAccess.mjs.map +1 -1
- package/dist/esm/utils/checkConfigConsistency.mjs +1 -2
- package/dist/esm/utils/checkFileModifiedRange.mjs +1 -2
- package/dist/esm/utils/checkLastUpdateTime.mjs +1 -2
- package/dist/esm/utils/chunkInference.mjs +1 -2
- package/dist/esm/utils/detectGitRepository.mjs +84 -0
- package/dist/esm/utils/detectGitRepository.mjs.map +1 -0
- package/dist/esm/utils/fixChunkStartEndChars.mjs +1 -2
- package/dist/esm/utils/formatLineRanges.mjs +1 -2
- package/dist/esm/utils/formatTimeDiff.mjs +1 -2
- package/dist/esm/utils/getIsFileUpdatedRecently.mjs +1 -2
- package/dist/esm/utils/getOutputFilePath.mjs +1 -2
- package/dist/esm/utils/getParentPackageJSON.mjs +2 -3
- package/dist/esm/utils/isInteractiveTerminal.mjs +1 -2
- package/dist/esm/utils/listSpecialChars.mjs +1 -2
- package/dist/esm/utils/mapChunksBetweenFiles.mjs +1 -2
- package/dist/esm/utils/openBrowser.mjs +1 -2
- package/dist/esm/utils/parseChoice.mjs +1 -2
- package/dist/esm/utils/reorderParagraphs.mjs +1 -2
- package/dist/esm/utils/selectCmsEnvironment.mjs +1 -2
- package/dist/esm/utils/setupAI.mjs +1 -2
- package/dist/esm/watch.mjs +2 -3
- package/dist/types/IntlayerEventListener.d.ts +1 -3
- package/dist/types/IntlayerEventListener.d.ts.map +1 -1
- package/dist/types/auth/login.d.ts +6 -2
- package/dist/types/auth/login.d.ts.map +1 -1
- package/dist/types/auth/sessionToken.d.ts +0 -2
- package/dist/types/auth/sessionToken.d.ts.map +1 -1
- package/dist/types/auth/setupRepository.d.ts +24 -0
- package/dist/types/auth/setupRepository.d.ts.map +1 -0
- package/dist/types/build.d.ts +1 -2
- package/dist/types/build.d.ts.map +1 -1
- package/dist/types/bundle.d.ts +0 -2
- package/dist/types/bundle.d.ts.map +1 -1
- package/dist/types/ci.d.ts +1 -2
- package/dist/types/ci.d.ts.map +1 -1
- package/dist/types/cli.d.ts +1 -2
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/config.d.ts +1 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/editor.d.ts +11 -2
- package/dist/types/editor.d.ts.map +1 -1
- package/dist/types/extract.d.ts +1 -2
- package/dist/types/extract.d.ts.map +1 -1
- package/dist/types/fill/deepMergeContent.d.ts +0 -2
- package/dist/types/fill/deepMergeContent.d.ts.map +1 -1
- package/dist/types/fill/extractTranslatableContent.d.ts +0 -2
- package/dist/types/fill/extractTranslatableContent.d.ts.map +1 -1
- package/dist/types/fill/fill.d.ts +1 -3
- package/dist/types/fill/fill.d.ts.map +1 -1
- package/dist/types/fill/formatAutoFilledFilePath.d.ts +0 -2
- package/dist/types/fill/formatAutoFilledFilePath.d.ts.map +1 -1
- package/dist/types/fill/formatFillData.d.ts +0 -2
- package/dist/types/fill/formatFillData.d.ts.map +1 -1
- package/dist/types/fill/getAvailableLocalesInDictionary.d.ts +0 -2
- package/dist/types/fill/getAvailableLocalesInDictionary.d.ts.map +1 -1
- package/dist/types/fill/getFilterMissingContentPerLocale.d.ts +0 -2
- package/dist/types/fill/getFilterMissingContentPerLocale.d.ts.map +1 -1
- package/dist/types/fill/listTranslationsTasks.d.ts +0 -2
- package/dist/types/fill/listTranslationsTasks.d.ts.map +1 -1
- package/dist/types/fill/translateDictionary.d.ts +3 -5
- package/dist/types/fill/translateDictionary.d.ts.map +1 -1
- package/dist/types/fill/writeFill.d.ts +0 -2
- package/dist/types/fill/writeFill.d.ts.map +1 -1
- package/dist/types/getTargetDictionary.d.ts +0 -2
- package/dist/types/getTargetDictionary.d.ts.map +1 -1
- package/dist/types/index.d.ts +7 -3
- package/dist/types/init.d.ts +20 -4
- package/dist/types/init.d.ts.map +1 -1
- package/dist/types/initChromeExtension.d.ts +0 -2
- package/dist/types/initChromeExtension.d.ts.map +1 -1
- package/dist/types/initInfra.d.ts +0 -2
- package/dist/types/initInfra.d.ts.map +1 -1
- package/dist/types/initMCP.d.ts +0 -2
- package/dist/types/initMCP.d.ts.map +1 -1
- package/dist/types/initSkills.d.ts +0 -2
- package/dist/types/initSkills.d.ts.map +1 -1
- package/dist/types/listContentDeclaration.d.ts +1 -2
- package/dist/types/listContentDeclaration.d.ts.map +1 -1
- package/dist/types/listProjects.d.ts +0 -2
- package/dist/types/listProjects.d.ts.map +1 -1
- package/dist/types/liveSync.d.ts +1 -2
- package/dist/types/liveSync.d.ts.map +1 -1
- package/dist/types/loadPrompts.d.ts +0 -2
- package/dist/types/loadPrompts.d.ts.map +1 -1
- package/dist/types/pull.d.ts +1 -2
- package/dist/types/pull.d.ts.map +1 -1
- package/dist/types/push/pullLog.d.ts +0 -2
- package/dist/types/push/pullLog.d.ts.map +1 -1
- package/dist/types/push/push.d.ts +1 -2
- package/dist/types/push/push.d.ts.map +1 -1
- package/dist/types/pushConfig.d.ts +1 -2
- package/dist/types/pushConfig.d.ts.map +1 -1
- package/dist/types/pushLog.d.ts +0 -2
- package/dist/types/pushLog.d.ts.map +1 -1
- package/dist/types/reviewDoc/reviewDoc.d.ts +2 -3
- package/dist/types/reviewDoc/reviewDoc.d.ts.map +1 -1
- package/dist/types/reviewDoc/reviewDocBlockAware.d.ts +1 -4
- package/dist/types/reviewDoc/reviewDocBlockAware.d.ts.map +1 -1
- package/dist/types/reviewDoc/reviewDocLog.d.ts +0 -2
- package/dist/types/reviewDoc/reviewDocLog.d.ts.map +1 -1
- package/dist/types/reviewDoc/reviewDocProgress.d.ts +0 -2
- package/dist/types/reviewDoc/reviewDocProgress.d.ts.map +1 -1
- package/dist/types/reviewDoc/reviewDocSynthesis.d.ts +0 -2
- package/dist/types/reviewDoc/reviewDocSynthesis.d.ts.map +1 -1
- package/dist/types/scan.d.ts +0 -2
- package/dist/types/scan.d.ts.map +1 -1
- package/dist/types/searchDoc.d.ts +1 -2
- package/dist/types/searchDoc.d.ts.map +1 -1
- package/dist/types/test/listMissingTranslations.d.ts +0 -2
- package/dist/types/test/listMissingTranslations.d.ts.map +1 -1
- package/dist/types/test/test.d.ts +1 -2
- package/dist/types/test/test.d.ts.map +1 -1
- package/dist/types/translateDoc/index.d.ts +1 -1
- package/dist/types/translateDoc/translateDoc.d.ts +0 -2
- package/dist/types/translateDoc/translateDoc.d.ts.map +1 -1
- package/dist/types/translateDoc/translateFile.d.ts +0 -2
- package/dist/types/translateDoc/translateFile.d.ts.map +1 -1
- package/dist/types/translateDoc/types.d.ts +1 -3
- package/dist/types/translateDoc/types.d.ts.map +1 -1
- package/dist/types/translateDoc/validation.d.ts +0 -2
- package/dist/types/translateDoc/validation.d.ts.map +1 -1
- package/dist/types/upgrade.d.ts +0 -2
- package/dist/types/upgrade.d.ts.map +1 -1
- package/dist/types/utils/calculateChunks.d.ts +0 -2
- package/dist/types/utils/calculateChunks.d.ts.map +1 -1
- package/dist/types/utils/checkAccess.d.ts +2 -3
- package/dist/types/utils/checkAccess.d.ts.map +1 -1
- package/dist/types/utils/checkConfigConsistency.d.ts +0 -2
- package/dist/types/utils/checkConfigConsistency.d.ts.map +1 -1
- package/dist/types/utils/checkFileModifiedRange.d.ts +1 -2
- package/dist/types/utils/checkFileModifiedRange.d.ts.map +1 -1
- package/dist/types/utils/checkLastUpdateTime.d.ts +0 -2
- package/dist/types/utils/checkLastUpdateTime.d.ts.map +1 -1
- package/dist/types/utils/chunkInference.d.ts +1 -2
- package/dist/types/utils/chunkInference.d.ts.map +1 -1
- package/dist/types/utils/detectGitRepository.d.ts +32 -0
- package/dist/types/utils/detectGitRepository.d.ts.map +1 -0
- package/dist/types/utils/fixChunkStartEndChars.d.ts +0 -2
- package/dist/types/utils/fixChunkStartEndChars.d.ts.map +1 -1
- package/dist/types/utils/formatLineRanges.d.ts +0 -2
- package/dist/types/utils/formatLineRanges.d.ts.map +1 -1
- package/dist/types/utils/formatTimeDiff.d.ts +0 -2
- package/dist/types/utils/formatTimeDiff.d.ts.map +1 -1
- package/dist/types/utils/getIsFileUpdatedRecently.d.ts +0 -2
- package/dist/types/utils/getIsFileUpdatedRecently.d.ts.map +1 -1
- package/dist/types/utils/getOutputFilePath.d.ts +0 -2
- package/dist/types/utils/getOutputFilePath.d.ts.map +1 -1
- package/dist/types/utils/getParentPackageJSON.d.ts +1 -2
- package/dist/types/utils/getParentPackageJSON.d.ts.map +1 -1
- package/dist/types/utils/isInteractiveTerminal.d.ts +0 -2
- package/dist/types/utils/isInteractiveTerminal.d.ts.map +1 -1
- package/dist/types/utils/listSpecialChars.d.ts +1 -2
- package/dist/types/utils/listSpecialChars.d.ts.map +1 -1
- package/dist/types/utils/mapChunksBetweenFiles.d.ts +0 -2
- package/dist/types/utils/mapChunksBetweenFiles.d.ts.map +1 -1
- package/dist/types/utils/openBrowser.d.ts +0 -2
- package/dist/types/utils/openBrowser.d.ts.map +1 -1
- package/dist/types/utils/parseChoice.d.ts +0 -2
- package/dist/types/utils/parseChoice.d.ts.map +1 -1
- package/dist/types/utils/reorderParagraphs.d.ts +0 -2
- package/dist/types/utils/reorderParagraphs.d.ts.map +1 -1
- package/dist/types/utils/selectCmsEnvironment.d.ts +1 -3
- package/dist/types/utils/selectCmsEnvironment.d.ts.map +1 -1
- package/dist/types/utils/setupAI.d.ts +1 -2
- package/dist/types/utils/setupAI.d.ts.map +1 -1
- package/dist/types/watch.d.ts +1 -2
- package/dist/types/watch.d.ts.map +1 -1
- package/package.json +14 -14
|
@@ -4,7 +4,7 @@ let _intlayer_api = require("@intlayer/api");
|
|
|
4
4
|
let _intlayer_config_built = require("@intlayer/config/built");
|
|
5
5
|
let eventsource = require("eventsource");
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
// src/IntlayerEventListener.ts
|
|
8
8
|
/**
|
|
9
9
|
* IntlayerEventListener class to listen for dictionary changes via SSE (Server-Sent Events).
|
|
10
10
|
*
|
|
@@ -180,6 +180,5 @@ var IntlayerEventListener = class {
|
|
|
180
180
|
}
|
|
181
181
|
};
|
|
182
182
|
|
|
183
|
-
//#endregion
|
|
184
183
|
exports.IntlayerEventListener = IntlayerEventListener;
|
|
185
184
|
//# sourceMappingURL=IntlayerEventListener.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntlayerEventListener.cjs","names":["getAppLogger","getIntlayerAPIProxy","EventSource"],"sources":["../../src/IntlayerEventListener.ts"],"sourcesContent":["import { getIntlayerAPIProxy } from '@intlayer/api';\n// @ts-ignore: @intlayer/backend is not built yet\nimport type { DictionaryAPI, MessageEventData } from '@intlayer/backend';\nimport { editor, log } from '@intlayer/config/built';\nimport { getAppLogger } from '@intlayer/config/logger';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { EventSource } from 'eventsource';\n\nexport type IntlayerMessageEvent = MessageEvent;\n\n/**\n * IntlayerEventListener class to listen for dictionary changes via SSE (Server-Sent Events).\n *\n * Usage example:\n *\n * import { buildIntlayerDictionary } from './transpiler/declaration_file_to_dictionary/intlayer_dictionary';\n * import { IntlayerEventListener } from '@intlayer/api';\n *\n * export const checkDictionaryChanges = async () => {\n * // Instantiate the listener\n * const eventListener = new IntlayerEventListener();\n *\n * // Set up your callbacks\n * eventListener.onDictionaryChange = async (dictionary) => {\n * await buildIntlayerDictionary(dictionary);\n * };\n *\n * // Initialize the listener\n * await eventListener.initialize();\n *\n * // Optionally, clean up later when you’re done\n * // eventListener.cleanup();\n * };\n */\nexport class IntlayerEventListener {\n private appLogger = getAppLogger({ log });\n\n private eventSource: EventSource | null = null;\n private reconnectAttempts = 0;\n private maxReconnectAttempts = 5;\n private reconnectDelay = 1000; // Start with 1 second\n private isManuallyDisconnected = false;\n private reconnectTimeout: NodeJS.Timeout | null = null;\n\n /**\n * Callback triggered when a Dictionary is ADDED.\n */\n public onDictionaryAdded?: (dictionary: DictionaryAPI) => any;\n\n /**\n * Callback triggered when a Dictionary is UPDATED.\n */\n public onDictionaryChange?: (dictionary: DictionaryAPI) => any;\n\n /**\n * Callback triggered when a Dictionary is DELETED.\n */\n public onDictionaryDeleted?: (dictionary: DictionaryAPI) => any;\n\n /**\n * Callback triggered when connection is established or re-established.\n */\n public onConnectionOpen?: () => any;\n\n /**\n * Callback triggered when connection encounters an error.\n */\n public onConnectionError?: (error: Event) => any;\n\n constructor(\n private intlayerConfig: Pick<IntlayerConfig, 'log' | 'editor'> = {\n log,\n editor,\n }\n ) {\n this.appLogger = getAppLogger(this.intlayerConfig);\n }\n\n /**\n * Initializes the EventSource connection using the given intlayerConfig\n * (or the default config if none was provided).\n */\n public async initialize(): Promise<void> {\n this.isManuallyDisconnected = false;\n await this.connect();\n }\n\n /**\n * Establishes the EventSource connection with automatic reconnection support.\n */\n private async connect(): Promise<void> {\n try {\n const backendURL = this.intlayerConfig.editor.backendURL;\n\n // Retrieve the access token via proxy\n const accessToken = await getIntlayerAPIProxy(\n undefined,\n this.intlayerConfig\n ).oAuth.getOAuth2AccessToken();\n\n if (!accessToken) {\n throw new Error('Failed to retrieve access token');\n }\n\n const API_ROUTE = `${backendURL}/api/event-listener`;\n\n // Close existing connection if any\n if (this.eventSource) {\n this.eventSource.close();\n }\n\n this.eventSource = new EventSource(API_ROUTE, {\n fetch: (input, init) =>\n fetch(input, {\n ...init,\n headers: {\n ...(init?.headers ?? {}),\n Authorization: `Bearer ${accessToken.data?.accessToken}`,\n },\n }),\n });\n\n this.eventSource.onopen = () => {\n this.reconnectAttempts = 0;\n this.reconnectDelay = 1000; // Reset delay\n this.onConnectionOpen?.();\n };\n\n this.eventSource.onmessage = (event) => this.handleMessage(event);\n this.eventSource.onerror = (event) => this.handleError(event);\n } catch (_error) {\n this.appLogger('Failed to establish EventSource connection:', {\n level: 'error',\n });\n this.scheduleReconnect();\n }\n }\n\n /**\n * Cleans up (closes) the EventSource connection.\n */\n public cleanup(): void {\n this.isManuallyDisconnected = true;\n\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n }\n\n /**\n * Schedules a reconnection attempt with exponential backoff.\n */\n private scheduleReconnect(): void {\n if (\n this.isManuallyDisconnected ||\n this.reconnectAttempts >= this.maxReconnectAttempts\n ) {\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n this.appLogger(\n [\n `Max reconnection attempts (${this.maxReconnectAttempts}) reached. Giving up.`,\n ],\n {\n level: 'error',\n }\n );\n }\n return;\n }\n\n this.reconnectAttempts++;\n const delay = this.reconnectDelay * 2 ** (this.reconnectAttempts - 1); // Exponential backoff\n\n this.appLogger(\n `Scheduling reconnection attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms`\n );\n\n this.reconnectTimeout = setTimeout(async () => {\n if (!this.isManuallyDisconnected) {\n await this.connect();\n }\n }, delay);\n }\n\n /**\n * Handles incoming SSE messages, parses the event data,\n * and invokes the appropriate callback.\n */\n private async handleMessage(event: IntlayerMessageEvent): Promise<void> {\n try {\n const { data } = event;\n\n const dataJSON: MessageEventData[] = JSON.parse(data);\n\n for (const dataEl of dataJSON) {\n switch (dataEl.object) {\n case 'DICTIONARY':\n switch (dataEl.status) {\n case 'ADDED':\n await this.onDictionaryAdded?.(dataEl.data);\n break;\n case 'UPDATED':\n await this.onDictionaryChange?.(dataEl.data);\n break;\n case 'DELETED':\n await this.onDictionaryDeleted?.(dataEl.data);\n break;\n default:\n this.appLogger(\n ['Unhandled dictionary status:', dataEl.status],\n {\n level: 'error',\n }\n );\n break;\n }\n break;\n default:\n this.appLogger(['Unknown object type:', dataEl.object], {\n level: 'error',\n });\n break;\n }\n }\n } catch (error) {\n this.appLogger(['Error processing dictionary update:', error], {\n level: 'error',\n });\n }\n }\n\n /**\n * Handles any SSE errors and attempts reconnection if appropriate.\n */\n private handleError(event: Event): void {\n const errorEvent = event as any;\n\n // Log detailed error information\n this.appLogger(\n [\n 'EventSource error:',\n {\n type: errorEvent.type,\n message: errorEvent.message,\n code: errorEvent.code,\n readyState: this.eventSource?.readyState,\n url: this.eventSource?.url,\n },\n ],\n {\n level: 'error',\n }\n );\n\n // Notify error callback\n this.onConnectionError?.(event);\n\n // Check if this is a connection close error\n const isConnectionClosed =\n errorEvent.type === 'error' &&\n (errorEvent.message?.includes('terminated') ||\n errorEvent.message?.includes('closed') ||\n this.eventSource?.readyState === EventSource.CLOSED);\n\n if (isConnectionClosed && !this.isManuallyDisconnected) {\n this.appLogger(\n 'Connection was terminated by server, attempting to reconnect...'\n );\n this.scheduleReconnect();\n } else {\n // For other types of errors, close the connection\n this.cleanup();\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IntlayerEventListener.cjs","names":["getAppLogger","getIntlayerAPIProxy","EventSource"],"sources":["../../src/IntlayerEventListener.ts"],"sourcesContent":["import type { DictionaryAPI, MessageEventData } from '@intlayer/api';\nimport { getIntlayerAPIProxy } from '@intlayer/api';\nimport { editor, log } from '@intlayer/config/built';\nimport { getAppLogger } from '@intlayer/config/logger';\nimport type { IntlayerConfig } from '@intlayer/types/config';\nimport { EventSource } from 'eventsource';\n\nexport type IntlayerMessageEvent = MessageEvent;\n\n/**\n * IntlayerEventListener class to listen for dictionary changes via SSE (Server-Sent Events).\n *\n * Usage example:\n *\n * import { buildIntlayerDictionary } from './transpiler/declaration_file_to_dictionary/intlayer_dictionary';\n * import { IntlayerEventListener } from '@intlayer/api';\n *\n * export const checkDictionaryChanges = async () => {\n * // Instantiate the listener\n * const eventListener = new IntlayerEventListener();\n *\n * // Set up your callbacks\n * eventListener.onDictionaryChange = async (dictionary) => {\n * await buildIntlayerDictionary(dictionary);\n * };\n *\n * // Initialize the listener\n * await eventListener.initialize();\n *\n * // Optionally, clean up later when you’re done\n * // eventListener.cleanup();\n * };\n */\nexport class IntlayerEventListener {\n private appLogger = getAppLogger({ log });\n\n private eventSource: EventSource | null = null;\n private reconnectAttempts = 0;\n private maxReconnectAttempts = 5;\n private reconnectDelay = 1000; // Start with 1 second\n private isManuallyDisconnected = false;\n private reconnectTimeout: NodeJS.Timeout | null = null;\n\n /**\n * Callback triggered when a Dictionary is ADDED.\n */\n public onDictionaryAdded?: (dictionary: DictionaryAPI) => any;\n\n /**\n * Callback triggered when a Dictionary is UPDATED.\n */\n public onDictionaryChange?: (dictionary: DictionaryAPI) => any;\n\n /**\n * Callback triggered when a Dictionary is DELETED.\n */\n public onDictionaryDeleted?: (dictionary: DictionaryAPI) => any;\n\n /**\n * Callback triggered when connection is established or re-established.\n */\n public onConnectionOpen?: () => any;\n\n /**\n * Callback triggered when connection encounters an error.\n */\n public onConnectionError?: (error: Event) => any;\n\n constructor(\n private intlayerConfig: Pick<IntlayerConfig, 'log' | 'editor'> = {\n log,\n editor,\n }\n ) {\n this.appLogger = getAppLogger(this.intlayerConfig);\n }\n\n /**\n * Initializes the EventSource connection using the given intlayerConfig\n * (or the default config if none was provided).\n */\n public async initialize(): Promise<void> {\n this.isManuallyDisconnected = false;\n await this.connect();\n }\n\n /**\n * Establishes the EventSource connection with automatic reconnection support.\n */\n private async connect(): Promise<void> {\n try {\n const backendURL = this.intlayerConfig.editor.backendURL;\n\n // Retrieve the access token via proxy\n const accessToken = await getIntlayerAPIProxy(\n undefined,\n this.intlayerConfig\n ).oAuth.getOAuth2AccessToken();\n\n if (!accessToken) {\n throw new Error('Failed to retrieve access token');\n }\n\n const API_ROUTE = `${backendURL}/api/event-listener`;\n\n // Close existing connection if any\n if (this.eventSource) {\n this.eventSource.close();\n }\n\n this.eventSource = new EventSource(API_ROUTE, {\n fetch: (input, init) =>\n fetch(input, {\n ...init,\n headers: {\n ...(init?.headers ?? {}),\n Authorization: `Bearer ${accessToken.data?.accessToken}`,\n },\n }),\n });\n\n this.eventSource.onopen = () => {\n this.reconnectAttempts = 0;\n this.reconnectDelay = 1000; // Reset delay\n this.onConnectionOpen?.();\n };\n\n this.eventSource.onmessage = (event) => this.handleMessage(event);\n this.eventSource.onerror = (event) => this.handleError(event);\n } catch (_error) {\n this.appLogger('Failed to establish EventSource connection:', {\n level: 'error',\n });\n this.scheduleReconnect();\n }\n }\n\n /**\n * Cleans up (closes) the EventSource connection.\n */\n public cleanup(): void {\n this.isManuallyDisconnected = true;\n\n if (this.reconnectTimeout) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n }\n }\n\n /**\n * Schedules a reconnection attempt with exponential backoff.\n */\n private scheduleReconnect(): void {\n if (\n this.isManuallyDisconnected ||\n this.reconnectAttempts >= this.maxReconnectAttempts\n ) {\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n this.appLogger(\n [\n `Max reconnection attempts (${this.maxReconnectAttempts}) reached. Giving up.`,\n ],\n {\n level: 'error',\n }\n );\n }\n return;\n }\n\n this.reconnectAttempts++;\n const delay = this.reconnectDelay * 2 ** (this.reconnectAttempts - 1); // Exponential backoff\n\n this.appLogger(\n `Scheduling reconnection attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts} in ${delay}ms`\n );\n\n this.reconnectTimeout = setTimeout(async () => {\n if (!this.isManuallyDisconnected) {\n await this.connect();\n }\n }, delay);\n }\n\n /**\n * Handles incoming SSE messages, parses the event data,\n * and invokes the appropriate callback.\n */\n private async handleMessage(event: IntlayerMessageEvent): Promise<void> {\n try {\n const { data } = event;\n\n const dataJSON: MessageEventData[] = JSON.parse(data);\n\n for (const dataEl of dataJSON) {\n switch (dataEl.object) {\n case 'DICTIONARY':\n switch (dataEl.status) {\n case 'ADDED':\n await this.onDictionaryAdded?.(dataEl.data);\n break;\n case 'UPDATED':\n await this.onDictionaryChange?.(dataEl.data);\n break;\n case 'DELETED':\n await this.onDictionaryDeleted?.(dataEl.data);\n break;\n default:\n this.appLogger(\n ['Unhandled dictionary status:', dataEl.status],\n {\n level: 'error',\n }\n );\n break;\n }\n break;\n default:\n this.appLogger(['Unknown object type:', dataEl.object], {\n level: 'error',\n });\n break;\n }\n }\n } catch (error) {\n this.appLogger(['Error processing dictionary update:', error], {\n level: 'error',\n });\n }\n }\n\n /**\n * Handles any SSE errors and attempts reconnection if appropriate.\n */\n private handleError(event: Event): void {\n const errorEvent = event as any;\n\n // Log detailed error information\n this.appLogger(\n [\n 'EventSource error:',\n {\n type: errorEvent.type,\n message: errorEvent.message,\n code: errorEvent.code,\n readyState: this.eventSource?.readyState,\n url: this.eventSource?.url,\n },\n ],\n {\n level: 'error',\n }\n );\n\n // Notify error callback\n this.onConnectionError?.(event);\n\n // Check if this is a connection close error\n const isConnectionClosed =\n errorEvent.type === 'error' &&\n (errorEvent.message?.includes('terminated') ||\n errorEvent.message?.includes('closed') ||\n this.eventSource?.readyState === EventSource.CLOSED);\n\n if (isConnectionClosed && !this.isManuallyDisconnected) {\n this.appLogger(\n 'Connection was terminated by server, attempting to reconnect...'\n );\n this.scheduleReconnect();\n } else {\n // For other types of errors, close the connection\n this.cleanup();\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
// \0rolldown/runtime.js
|
|
2
2
|
var __create = Object.create;
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -24,5 +24,4 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
enumerable: true
|
|
25
25
|
}) : target, mod));
|
|
26
26
|
|
|
27
|
-
//#endregion
|
|
28
27
|
exports.__toESM = __toESM;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
let node_fs = require("node:fs");
|
|
2
1
|
let node_path = require("node:path");
|
|
3
2
|
let node_url = require("node:url");
|
|
3
|
+
let node_fs = require("node:fs");
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// \0utils:asset
|
|
6
6
|
const hereDirname = () => {
|
|
7
7
|
try {
|
|
8
8
|
return (0, node_path.dirname)((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
|
|
@@ -96,5 +96,4 @@ const readAsset = (relPath, encoding = "utf8") => {
|
|
|
96
96
|
throw new Error(msg);
|
|
97
97
|
};
|
|
98
98
|
|
|
99
|
-
//#endregion
|
|
100
99
|
exports.readAsset = readAsset;
|
package/dist/cjs/auth/login.cjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_runtime = require(
|
|
3
|
-
const require_utils_openBrowser = require(
|
|
4
|
-
const require_auth_sessionToken = require(
|
|
5
|
-
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
6
|
-
let node_http = require("node:http");
|
|
7
|
-
node_http = require_runtime.__toESM(node_http);
|
|
8
|
-
let node_url = require("node:url");
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_utils_openBrowser = require("../utils/openBrowser.cjs");
|
|
4
|
+
const require_auth_sessionToken = require("./sessionToken.cjs");
|
|
9
5
|
let _intlayer_config_colors = require("@intlayer/config/colors");
|
|
10
6
|
_intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
|
|
11
7
|
let _intlayer_config_logger = require("@intlayer/config/logger");
|
|
12
8
|
let _intlayer_config_node = require("@intlayer/config/node");
|
|
9
|
+
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
10
|
+
let node_url = require("node:url");
|
|
11
|
+
let node_http = require("node:http");
|
|
12
|
+
node_http = require_runtime.__toESM(node_http);
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
// src/auth/login.ts
|
|
15
15
|
const buildSuccessHtml = (message) => `
|
|
16
16
|
<!DOCTYPE html>
|
|
17
17
|
<html lang="en" data-theme="dark">
|
|
@@ -164,6 +164,17 @@ const login = async (options = {}) => {
|
|
|
164
164
|
res.end("Not found");
|
|
165
165
|
}
|
|
166
166
|
});
|
|
167
|
+
const abortLogin = () => {
|
|
168
|
+
server.close();
|
|
169
|
+
server.closeAllConnections();
|
|
170
|
+
resolve();
|
|
171
|
+
};
|
|
172
|
+
if (options.signal?.aborted) {
|
|
173
|
+
resolve();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
options.signal?.addEventListener("abort", abortLogin, { once: true });
|
|
177
|
+
server.on("close", () => options.signal?.removeEventListener("abort", abortLogin));
|
|
167
178
|
server.listen(0, () => {
|
|
168
179
|
const address = server.address();
|
|
169
180
|
const port = typeof address === "object" && address ? address.port : 0;
|
|
@@ -178,6 +189,5 @@ const login = async (options = {}) => {
|
|
|
178
189
|
});
|
|
179
190
|
};
|
|
180
191
|
|
|
181
|
-
//#endregion
|
|
182
192
|
exports.login = login;
|
|
183
193
|
//# sourceMappingURL=login.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.cjs","names":["getConfiguration","getAppLogger","http","URL","colorize","ANSIColors","writeCliSessionToken","colorizePath"],"sources":["../../../src/auth/login.ts"],"sourcesContent":["import http from 'node:http';\nimport { URL } from 'node:url';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizePath, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { logConfigDetails } from '@intlayer/engine/cli';\nimport { openBrowser } from '../utils/openBrowser';\nimport { writeCliSessionToken } from './sessionToken';\n\nconst buildSuccessHtml = (message: string): string => `\n <!DOCTYPE html>\n <html lang=\"en\" data-theme=\"dark\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Intlayer CLI Login</title>\n <style>\n :root {\n --color-background: rgba(23, 23, 23);\n --color-card: rgba(39, 39, 39);\n --color-text: rgba(255, 245, 237);\n --color-neutral: rgba(93, 93, 93);\n --font-sans: \"Inter\", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;\n }\n * { box-sizing: border-box; }\n body {\n font-family: var(--font-sans);\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n padding: 1rem;\n background-color: var(--color-background);\n color: var(--color-text);\n }\n .container {\n text-align: center;\n padding: 2rem;\n border-radius: 1rem;\n background-color: var(--color-card);\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 400px;\n width: 100%;\n }\n h1 { margin: 0 0 1rem 0; font-size: 1.5rem; font-weight: 700; color: var(--color-text); }\n p { color: var(--color-neutral); font-size: 0.8rem; margin: 0 0 1.5rem 0; line-height: 1.5; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Login Successful</h1>\n <p>${message}</p>\n </div>\n <script>\n window.close();\n setTimeout(() => { window.close(); }, 1000);\n </script>\n </body>\n </html>\n`;\n\ntype LoginOptions = {\n cmsUrl?: string;\n configOptions?: GetConfigurationOptions;\n /**\n * When false, do not call process.exit(0) after a successful login so the\n * caller can continue (e.g. retry a command inline, or finish an interactive\n * setup). Defaults to true to preserve existing standalone-login behaviour.\n */\n exitAfter?: boolean;\n /**\n * Invoked with the access-key credentials when the login flow returns a\n * `clientId` / `clientSecret` pair. When provided, the caller takes ownership\n * of persisting the credentials (e.g. writing them to `.env` and enabling the\n * editor in the config), so the default manual-setup instructions are skipped.\n */\n onCredentials?: (credentials: {\n clientId: string;\n clientSecret: string;\n }) => void | Promise<void>;\n};\n\nexport const login = async (options: LoginOptions = {}) => {\n const configuration = getConfiguration(options.configOptions);\n logConfigDetails(options?.configOptions);\n\n const logger = getAppLogger(configuration);\n\n const cmsUrl = options.cmsUrl ?? configuration.editor.cmsURL;\n\n return new Promise<void>((resolve) => {\n /**\n * Sends the success page, then shuts the callback server down. Open\n * keep-alive sockets are dropped: `server.close` alone waits for the\n * browser to release them, which would leave the login pending forever.\n */\n const completeLogin = (\n response: http.ServerResponse,\n message: string\n ): void => {\n response.writeHead(200, {\n 'Content-Type': 'text/html',\n Connection: 'close',\n });\n response.end(buildSuccessHtml(message), () => {\n server.close();\n server.closeAllConnections();\n resolve();\n\n if (options.exitAfter !== false) {\n process.exit(0);\n }\n });\n };\n\n const server = http.createServer(async (req, res) => {\n const url = new URL(req.url ?? '', `http://${req.headers.host}`);\n\n // Set CORS headers\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n if (url.pathname === '/callback') {\n const sessionToken = url.searchParams.get('sessionToken');\n const sessionExpiresAt = url.searchParams.get('expiresAt');\n const clientId = url.searchParams.get('clientId');\n const clientSecret = url.searchParams.get('clientSecret');\n\n if (sessionToken && sessionExpiresAt) {\n logger('');\n logger(\n `Log in successful. ${colorize('2h', ANSIColors.BLUE)} session token received.`\n );\n logger('');\n\n logger(\n colorize(\n `Token expires at: ${new Date(sessionExpiresAt).toLocaleString()}`,\n ANSIColors.GREY\n )\n );\n\n await writeCliSessionToken(\n configuration,\n sessionToken,\n new Date(sessionExpiresAt)\n );\n\n if (options.onCredentials) {\n logger(\n 'A session token does not configure the CMS: run `intlayer login` again and pick an access key to store the credentials in your .env.',\n { level: 'warn' }\n );\n }\n\n completeLogin(\n res,\n 'Your 2h session token has been stored. You can now close this tab and return to your terminal.'\n );\n return;\n }\n\n if (clientId && clientSecret) {\n if (options.onCredentials) {\n // The caller persists the credentials itself (e.g. interactive\n // init writing `.env` and enabling the editor in the config).\n logger('');\n logger('Log in successful. Configuring Intlayer CMS...');\n\n try {\n await options.onCredentials({ clientId, clientSecret });\n } catch (error) {\n logger(\n `Failed to persist the CMS credentials automatically: ${\n error instanceof Error ? error.message : String(error)\n }`,\n { level: 'error' }\n );\n }\n } else {\n logger('');\n logger('Log in successful. Client ID and Client Secret received.');\n\n logger('');\n logger([\n '1. Insert the Client ID and Client Secret in your',\n colorizePath('.env'),\n 'file:',\n ]);\n logger(\n colorize('--------------------------------', ANSIColors.GREY_DARK)\n );\n logger(\n [\n colorize('INTLAYER_CLIENT_ID=', ANSIColors.GREY_LIGHT),\n colorize(clientId, ANSIColors.BLUE),\n ].join('')\n );\n logger(\n [\n colorize('INTLAYER_CLIENT_SECRET=', ANSIColors.GREY_LIGHT),\n colorize(clientSecret, ANSIColors.BLUE),\n ].join('')\n );\n logger(\n colorize('--------------------------------', ANSIColors.GREY_DARK)\n );\n logger('');\n logger('2. Insert in your Intlayer configuration file:');\n logger(\n colorize('--------------------------------', ANSIColors.GREY_DARK)\n );\n [\n `${ANSIColors.GREY_LIGHT}{`,\n ` editor: {`,\n ` enabled: true,`,\n ` cmsURL: '${colorizePath(cmsUrl!, undefined, ANSIColors.GREY_LIGHT)}',`,\n ` clientId: '${colorize('process.env.INTLAYER_CLIENT_ID', ANSIColors.BLUE, ANSIColors.GREY_LIGHT)}',`,\n ` clientSecret: '${colorize('process.env.INTLAYER_CLIENT_SECRET', ANSIColors.BLUE, ANSIColors.GREY_LIGHT)}',`,\n ` },`,\n `}`,\n ].forEach((line) => {\n logger(line);\n });\n logger(\n colorize('--------------------------------', ANSIColors.GREY_DARK)\n );\n }\n\n completeLogin(\n res,\n 'You have successfully logged in to Intlayer CLI. You can now close this tab and return to your terminal.'\n );\n } else {\n res.writeHead(400, { 'Content-Type': 'text/plain' });\n res.end('Missing parameters');\n }\n } else {\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not found');\n }\n });\n\n server.listen(0, () => {\n const address = server.address();\n const port = typeof address === 'object' && address ? address.port : 0;\n const state = Math.random().toString(36).substring(7);\n\n const websiteUrl =\n cmsUrl ?? process.env.INTLAYER_SITE_URL ?? 'http://localhost:3000';\n const backendUrl = configuration.editor.backendURL ?? '';\n const loginUrl = `${websiteUrl}/auth/cli-login?port=${port}&state=${state}&backendUrl=${encodeURIComponent(backendUrl)}`;\n\n logger('Opening browser for login...');\n logger(`If browser does not open, visit: ${colorizePath(loginUrl)}`);\n\n openBrowser(loginUrl);\n });\n });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"login.cjs","names":["getConfiguration","getAppLogger","http","URL","colorize","ANSIColors","writeCliSessionToken","colorizePath"],"sources":["../../../src/auth/login.ts"],"sourcesContent":["import http from 'node:http';\nimport { URL } from 'node:url';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizePath, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport { logConfigDetails } from '@intlayer/engine/cli';\nimport { openBrowser } from '../utils/openBrowser';\nimport { writeCliSessionToken } from './sessionToken';\n\nconst buildSuccessHtml = (message: string): string => `\n <!DOCTYPE html>\n <html lang=\"en\" data-theme=\"dark\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Intlayer CLI Login</title>\n <style>\n :root {\n --color-background: rgba(23, 23, 23);\n --color-card: rgba(39, 39, 39);\n --color-text: rgba(255, 245, 237);\n --color-neutral: rgba(93, 93, 93);\n --font-sans: \"Inter\", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;\n }\n * { box-sizing: border-box; }\n body {\n font-family: var(--font-sans);\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n margin: 0;\n padding: 1rem;\n background-color: var(--color-background);\n color: var(--color-text);\n }\n .container {\n text-align: center;\n padding: 2rem;\n border-radius: 1rem;\n background-color: var(--color-card);\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n max-width: 400px;\n width: 100%;\n }\n h1 { margin: 0 0 1rem 0; font-size: 1.5rem; font-weight: 700; color: var(--color-text); }\n p { color: var(--color-neutral); font-size: 0.8rem; margin: 0 0 1.5rem 0; line-height: 1.5; }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>Login Successful</h1>\n <p>${message}</p>\n </div>\n <script>\n window.close();\n setTimeout(() => { window.close(); }, 1000);\n </script>\n </body>\n </html>\n`;\n\ntype LoginOptions = {\n cmsUrl?: string;\n configOptions?: GetConfigurationOptions;\n /**\n * When false, do not call process.exit(0) after a successful login so the\n * caller can continue (e.g. retry a command inline, or finish an interactive\n * setup). Defaults to true to preserve existing standalone-login behaviour.\n */\n exitAfter?: boolean;\n /**\n * Invoked with the access-key credentials when the login flow returns a\n * `clientId` / `clientSecret` pair. When provided, the caller takes ownership\n * of persisting the credentials (e.g. writing them to `.env` and enabling the\n * editor in the config), so the default manual-setup instructions are skipped.\n */\n onCredentials?: (credentials: {\n clientId: string;\n clientSecret: string;\n }) => void | Promise<void>;\n /**\n * Aborts a login still waiting for the browser callback: the callback\n * server is shut down and the returned promise resolves.\n */\n signal?: AbortSignal;\n};\n\nexport const login = async (options: LoginOptions = {}) => {\n const configuration = getConfiguration(options.configOptions);\n logConfigDetails(options?.configOptions);\n\n const logger = getAppLogger(configuration);\n\n const cmsUrl = options.cmsUrl ?? configuration.editor.cmsURL;\n\n return new Promise<void>((resolve) => {\n /**\n * Sends the success page, then shuts the callback server down. Open\n * keep-alive sockets are dropped: `server.close` alone waits for the\n * browser to release them, which would leave the login pending forever.\n */\n const completeLogin = (\n response: http.ServerResponse,\n message: string\n ): void => {\n response.writeHead(200, {\n 'Content-Type': 'text/html',\n Connection: 'close',\n });\n response.end(buildSuccessHtml(message), () => {\n server.close();\n server.closeAllConnections();\n resolve();\n\n if (options.exitAfter !== false) {\n process.exit(0);\n }\n });\n };\n\n const server = http.createServer(async (req, res) => {\n const url = new URL(req.url ?? '', `http://${req.headers.host}`);\n\n // Set CORS headers\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n if (url.pathname === '/callback') {\n const sessionToken = url.searchParams.get('sessionToken');\n const sessionExpiresAt = url.searchParams.get('expiresAt');\n const clientId = url.searchParams.get('clientId');\n const clientSecret = url.searchParams.get('clientSecret');\n\n if (sessionToken && sessionExpiresAt) {\n logger('');\n logger(\n `Log in successful. ${colorize('2h', ANSIColors.BLUE)} session token received.`\n );\n logger('');\n\n logger(\n colorize(\n `Token expires at: ${new Date(sessionExpiresAt).toLocaleString()}`,\n ANSIColors.GREY\n )\n );\n\n await writeCliSessionToken(\n configuration,\n sessionToken,\n new Date(sessionExpiresAt)\n );\n\n if (options.onCredentials) {\n logger(\n 'A session token does not configure the CMS: run `intlayer login` again and pick an access key to store the credentials in your .env.',\n { level: 'warn' }\n );\n }\n\n completeLogin(\n res,\n 'Your 2h session token has been stored. You can now close this tab and return to your terminal.'\n );\n return;\n }\n\n if (clientId && clientSecret) {\n if (options.onCredentials) {\n // The caller persists the credentials itself (e.g. interactive\n // init writing `.env` and enabling the editor in the config).\n logger('');\n logger('Log in successful. Configuring Intlayer CMS...');\n\n try {\n await options.onCredentials({ clientId, clientSecret });\n } catch (error) {\n logger(\n `Failed to persist the CMS credentials automatically: ${\n error instanceof Error ? error.message : String(error)\n }`,\n { level: 'error' }\n );\n }\n } else {\n logger('');\n logger('Log in successful. Client ID and Client Secret received.');\n\n logger('');\n logger([\n '1. Insert the Client ID and Client Secret in your',\n colorizePath('.env'),\n 'file:',\n ]);\n logger(\n colorize('--------------------------------', ANSIColors.GREY_DARK)\n );\n logger(\n [\n colorize('INTLAYER_CLIENT_ID=', ANSIColors.GREY_LIGHT),\n colorize(clientId, ANSIColors.BLUE),\n ].join('')\n );\n logger(\n [\n colorize('INTLAYER_CLIENT_SECRET=', ANSIColors.GREY_LIGHT),\n colorize(clientSecret, ANSIColors.BLUE),\n ].join('')\n );\n logger(\n colorize('--------------------------------', ANSIColors.GREY_DARK)\n );\n logger('');\n logger('2. Insert in your Intlayer configuration file:');\n logger(\n colorize('--------------------------------', ANSIColors.GREY_DARK)\n );\n [\n `${ANSIColors.GREY_LIGHT}{`,\n ` editor: {`,\n ` enabled: true,`,\n ` cmsURL: '${colorizePath(cmsUrl!, undefined, ANSIColors.GREY_LIGHT)}',`,\n ` clientId: '${colorize('process.env.INTLAYER_CLIENT_ID', ANSIColors.BLUE, ANSIColors.GREY_LIGHT)}',`,\n ` clientSecret: '${colorize('process.env.INTLAYER_CLIENT_SECRET', ANSIColors.BLUE, ANSIColors.GREY_LIGHT)}',`,\n ` },`,\n `}`,\n ].forEach((line) => {\n logger(line);\n });\n logger(\n colorize('--------------------------------', ANSIColors.GREY_DARK)\n );\n }\n\n completeLogin(\n res,\n 'You have successfully logged in to Intlayer CLI. You can now close this tab and return to your terminal.'\n );\n } else {\n res.writeHead(400, { 'Content-Type': 'text/plain' });\n res.end('Missing parameters');\n }\n } else {\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not found');\n }\n });\n\n const abortLogin = (): void => {\n server.close();\n server.closeAllConnections();\n resolve();\n };\n\n if (options.signal?.aborted) {\n resolve();\n return;\n }\n\n options.signal?.addEventListener('abort', abortLogin, { once: true });\n server.on('close', () =>\n options.signal?.removeEventListener('abort', abortLogin)\n );\n\n server.listen(0, () => {\n const address = server.address();\n const port = typeof address === 'object' && address ? address.port : 0;\n const state = Math.random().toString(36).substring(7);\n\n const websiteUrl =\n cmsUrl ?? process.env.INTLAYER_SITE_URL ?? 'http://localhost:3000';\n const backendUrl = configuration.editor.backendURL ?? '';\n const loginUrl = `${websiteUrl}/auth/cli-login?port=${port}&state=${state}&backendUrl=${encodeURIComponent(backendUrl)}`;\n\n logger('Opening browser for login...');\n logger(`If browser does not open, visit: ${colorizePath(loginUrl)}`);\n\n openBrowser(loginUrl);\n });\n });\n};\n"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
let node_path = require("node:path");
|
|
3
3
|
let node_fs_promises = require("node:fs/promises");
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
// src/auth/sessionToken.ts
|
|
6
6
|
const SESSION_FILE_NAME = "cli-session.json";
|
|
7
7
|
const getSessionFilePath = (config) => (0, node_path.join)(config.system.tempDir, SESSION_FILE_NAME);
|
|
8
8
|
const writeCliSessionToken = async (config, token, expiresAt) => {
|
|
@@ -35,7 +35,6 @@ const clearCliSessionToken = async (config) => {
|
|
|
35
35
|
} catch {}
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
-
//#endregion
|
|
39
38
|
exports.clearCliSessionToken = clearCliSessionToken;
|
|
40
39
|
exports.readCliSessionToken = readCliSessionToken;
|
|
41
40
|
exports.writeCliSessionToken = writeCliSessionToken;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
|
|
3
|
+
const require_utils_openBrowser = require("../utils/openBrowser.cjs");
|
|
4
|
+
let _intlayer_config_colors = require("@intlayer/config/colors");
|
|
5
|
+
_intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
|
|
6
|
+
let _intlayer_config_logger = require("@intlayer/config/logger");
|
|
7
|
+
let _intlayer_config_node = require("@intlayer/config/node");
|
|
8
|
+
let node_url = require("node:url");
|
|
9
|
+
let node_http = require("node:http");
|
|
10
|
+
node_http = require_runtime.__toESM(node_http);
|
|
11
|
+
let node_crypto = require("node:crypto");
|
|
12
|
+
|
|
13
|
+
// src/auth/setupRepository.ts
|
|
14
|
+
/** Page shown once the browser handed the result back to the CLI. */
|
|
15
|
+
const DONE_HTML = `<!DOCTYPE html>
|
|
16
|
+
<html lang="en">
|
|
17
|
+
<head>
|
|
18
|
+
<meta charset="UTF-8">
|
|
19
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
20
|
+
<title>Intlayer CLI</title>
|
|
21
|
+
<style>
|
|
22
|
+
body { font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: rgb(23, 23, 23); color: rgb(255, 245, 237); }
|
|
23
|
+
p { color: rgb(160, 160, 160); font-size: 0.9rem; }
|
|
24
|
+
</style>
|
|
25
|
+
</head>
|
|
26
|
+
<body>
|
|
27
|
+
<div>
|
|
28
|
+
<h1>Repository setup complete</h1>
|
|
29
|
+
<p>You can now close this tab and return to your terminal.</p>
|
|
30
|
+
</div>
|
|
31
|
+
<script>window.close();<\/script>
|
|
32
|
+
</body>
|
|
33
|
+
</html>`;
|
|
34
|
+
/**
|
|
35
|
+
* Search params pre-filling the repository page with the local repository.
|
|
36
|
+
* Empty when none was detected: the user then picks it in the browser.
|
|
37
|
+
*/
|
|
38
|
+
const getRepositorySearchParams = (detectedRepository) => {
|
|
39
|
+
const searchParams = new URLSearchParams();
|
|
40
|
+
if (!detectedRepository) return searchParams;
|
|
41
|
+
const { provider, owner, repository, branch, configFilePath, instanceUrl } = detectedRepository;
|
|
42
|
+
searchParams.set("repositoryProvider", provider);
|
|
43
|
+
searchParams.set("repositoryOwner", owner);
|
|
44
|
+
searchParams.set("repositoryName", repository);
|
|
45
|
+
if (branch) searchParams.set("repositoryBranch", branch);
|
|
46
|
+
if (configFilePath) searchParams.set("repositoryConfigPath", configFilePath);
|
|
47
|
+
if (instanceUrl) searchParams.set("repositoryInstanceUrl", instanceUrl);
|
|
48
|
+
return searchParams;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Opens the CMS repository page (`/auth/cli-repository`) and waits for it to
|
|
52
|
+
* call back the local server once the repository and build settings are set.
|
|
53
|
+
*/
|
|
54
|
+
const setupRepository = async (options = {}) => {
|
|
55
|
+
const configuration = (0, _intlayer_config_node.getConfiguration)(options.configOptions);
|
|
56
|
+
const logger = (0, _intlayer_config_logger.getAppLogger)(configuration);
|
|
57
|
+
const cmsUrl = options.cmsUrl ?? configuration.editor.cmsURL ?? process.env.INTLAYER_SITE_URL ?? "http://localhost:3000";
|
|
58
|
+
const state = (0, node_crypto.randomBytes)(16).toString("hex");
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
const server = node_http.default.createServer((request, response) => {
|
|
61
|
+
const url = new node_url.URL(request.url ?? "", `http://${request.headers.host}`);
|
|
62
|
+
if (url.pathname !== "/callback" || url.searchParams.get("state") !== state) {
|
|
63
|
+
response.writeHead(404, { "Content-Type": "text/plain" });
|
|
64
|
+
response.end("Not found");
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const linkedRepository = url.searchParams.get("linkedRepository");
|
|
68
|
+
logger(linkedRepository ? `Repository ${(0, _intlayer_config_logger.colorize)(linkedRepository, _intlayer_config_colors.BLUE)} connected to the CMS project.` : "Repository setup skipped.");
|
|
69
|
+
response.writeHead(200, {
|
|
70
|
+
"Content-Type": "text/html",
|
|
71
|
+
Connection: "close"
|
|
72
|
+
});
|
|
73
|
+
response.end(DONE_HTML, () => {
|
|
74
|
+
server.close();
|
|
75
|
+
server.closeAllConnections();
|
|
76
|
+
resolve({ linkedRepository });
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
server.listen(0, () => {
|
|
80
|
+
const address = server.address();
|
|
81
|
+
const port = typeof address === "object" && address ? address.port : 0;
|
|
82
|
+
const searchParams = getRepositorySearchParams(options.detectedRepository);
|
|
83
|
+
searchParams.set("port", String(port));
|
|
84
|
+
searchParams.set("state", state);
|
|
85
|
+
const pageUrl = `${cmsUrl}/auth/cli-repository?${searchParams.toString()}`;
|
|
86
|
+
logger(`If the browser does not open, visit: ${(0, _intlayer_config_logger.colorizePath)(pageUrl)}`);
|
|
87
|
+
require_utils_openBrowser.openBrowser(pageUrl);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
exports.getRepositorySearchParams = getRepositorySearchParams;
|
|
93
|
+
exports.setupRepository = setupRepository;
|
|
94
|
+
//# sourceMappingURL=setupRepository.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupRepository.cjs","names":["getConfiguration","getAppLogger","randomBytes","http","URL","colorize","ANSIColors","colorizePath"],"sources":["../../../src/auth/setupRepository.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto';\nimport http from 'node:http';\nimport { URL } from 'node:url';\nimport * as ANSIColors from '@intlayer/config/colors';\nimport { colorize, colorizePath, getAppLogger } from '@intlayer/config/logger';\nimport {\n type GetConfigurationOptions,\n getConfiguration,\n} from '@intlayer/config/node';\nimport type { DetectedGitRepository } from '../utils/detectGitRepository';\nimport { openBrowser } from '../utils/openBrowser';\n\n/** Page shown once the browser handed the result back to the CLI. */\nconst DONE_HTML = `<!DOCTYPE html>\n<html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Intlayer CLI</title>\n <style>\n body { font-family: system-ui, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; background: rgb(23, 23, 23); color: rgb(255, 245, 237); }\n p { color: rgb(160, 160, 160); font-size: 0.9rem; }\n </style>\n </head>\n <body>\n <div>\n <h1>Repository setup complete</h1>\n <p>You can now close this tab and return to your terminal.</p>\n </div>\n <script>window.close();</script>\n </body>\n</html>`;\n\n/**\n * Search params pre-filling the repository page with the local repository.\n * Empty when none was detected: the user then picks it in the browser.\n */\nexport const getRepositorySearchParams = (\n detectedRepository: DetectedGitRepository | null | undefined\n): URLSearchParams => {\n const searchParams = new URLSearchParams();\n\n if (!detectedRepository) return searchParams;\n\n const { provider, owner, repository, branch, configFilePath, instanceUrl } =\n detectedRepository;\n\n searchParams.set('repositoryProvider', provider);\n searchParams.set('repositoryOwner', owner);\n searchParams.set('repositoryName', repository);\n if (branch) searchParams.set('repositoryBranch', branch);\n if (configFilePath) searchParams.set('repositoryConfigPath', configFilePath);\n if (instanceUrl) searchParams.set('repositoryInstanceUrl', instanceUrl);\n\n return searchParams;\n};\n\ntype SetupRepositoryOptions = {\n cmsUrl?: string;\n configOptions?: GetConfigurationOptions;\n /** Local repository pre-filling the page */\n detectedRepository?: DetectedGitRepository | null;\n};\n\n/** Outcome of the browser step: `provider:owner/repository`, or skipped. */\nexport type SetupRepositoryResult = {\n linkedRepository: string | null;\n};\n\n/**\n * Opens the CMS repository page (`/auth/cli-repository`) and waits for it to\n * call back the local server once the repository and build settings are set.\n */\nexport const setupRepository = async (\n options: SetupRepositoryOptions = {}\n): Promise<SetupRepositoryResult> => {\n const configuration = getConfiguration(options.configOptions);\n const logger = getAppLogger(configuration);\n const cmsUrl =\n options.cmsUrl ??\n configuration.editor.cmsURL ??\n process.env.INTLAYER_SITE_URL ??\n 'http://localhost:3000';\n const state = randomBytes(16).toString('hex');\n\n return new Promise<SetupRepositoryResult>((resolve) => {\n const server = http.createServer((request, response) => {\n const url = new URL(request.url ?? '', `http://${request.headers.host}`);\n\n // A callback from another tab or process is ignored\n if (\n url.pathname !== '/callback' ||\n url.searchParams.get('state') !== state\n ) {\n response.writeHead(404, { 'Content-Type': 'text/plain' });\n response.end('Not found');\n return;\n }\n\n const linkedRepository = url.searchParams.get('linkedRepository');\n\n logger(\n linkedRepository\n ? `Repository ${colorize(linkedRepository, ANSIColors.BLUE)} connected to the CMS project.`\n : 'Repository setup skipped.'\n );\n\n response.writeHead(200, {\n 'Content-Type': 'text/html',\n Connection: 'close',\n });\n response.end(DONE_HTML, () => {\n // Keep-alive sockets would otherwise hold the server open\n server.close();\n server.closeAllConnections();\n resolve({ linkedRepository });\n });\n });\n\n server.listen(0, () => {\n const address = server.address();\n const port = typeof address === 'object' && address ? address.port : 0;\n const searchParams = getRepositorySearchParams(\n options.detectedRepository\n );\n searchParams.set('port', String(port));\n searchParams.set('state', state);\n\n const pageUrl = `${cmsUrl}/auth/cli-repository?${searchParams.toString()}`;\n\n logger(`If the browser does not open, visit: ${colorizePath(pageUrl)}`);\n\n openBrowser(pageUrl);\n });\n });\n};\n"],"mappings":";;;;;;;;;;;;;;AAaA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;AAwBlB,MAAa,6BACX,uBACoB;CACpB,MAAM,eAAe,IAAI,gBAAgB;CAEzC,IAAI,CAAC,oBAAoB,OAAO;CAEhC,MAAM,EAAE,UAAU,OAAO,YAAY,QAAQ,gBAAgB,gBAC3D;CAEF,aAAa,IAAI,sBAAsB,QAAQ;CAC/C,aAAa,IAAI,mBAAmB,KAAK;CACzC,aAAa,IAAI,kBAAkB,UAAU;CAC7C,IAAI,QAAQ,aAAa,IAAI,oBAAoB,MAAM;CACvD,IAAI,gBAAgB,aAAa,IAAI,wBAAwB,cAAc;CAC3E,IAAI,aAAa,aAAa,IAAI,yBAAyB,WAAW;CAEtE,OAAO;AACT;;;;;AAkBA,MAAa,kBAAkB,OAC7B,UAAkC,CAAC,MACA;CACnC,MAAM,oBAAgBA,wCAAiB,QAAQ,aAAa;CAC5D,MAAM,aAASC,sCAAa,aAAa;CACzC,MAAM,SACJ,QAAQ,UACR,cAAc,OAAO,UACrB,QAAQ,IAAI,qBACZ;CACF,MAAM,YAAQC,yBAAY,EAAE,CAAC,CAAC,SAAS,KAAK;CAE5C,OAAO,IAAI,SAAgC,YAAY;EACrD,MAAM,SAASC,kBAAK,cAAc,SAAS,aAAa;GACtD,MAAM,MAAM,IAAIC,aAAI,QAAQ,OAAO,IAAI,UAAU,QAAQ,QAAQ,MAAM;GAGvE,IACE,IAAI,aAAa,eACjB,IAAI,aAAa,IAAI,OAAO,MAAM,OAClC;IACA,SAAS,UAAU,KAAK,EAAE,gBAAgB,aAAa,CAAC;IACxD,SAAS,IAAI,WAAW;IACxB;GACF;GAEA,MAAM,mBAAmB,IAAI,aAAa,IAAI,kBAAkB;GAEhE,OACE,mBACI,kBAAcC,kCAAS,kBAAkBC,wBAAW,IAAI,EAAE,kCAC1D,2BACN;GAEA,SAAS,UAAU,KAAK;IACtB,gBAAgB;IAChB,YAAY;GACd,CAAC;GACD,SAAS,IAAI,iBAAiB;IAE5B,OAAO,MAAM;IACb,OAAO,oBAAoB;IAC3B,QAAQ,EAAE,iBAAiB,CAAC;GAC9B,CAAC;EACH,CAAC;EAED,OAAO,OAAO,SAAS;GACrB,MAAM,UAAU,OAAO,QAAQ;GAC/B,MAAM,OAAO,OAAO,YAAY,YAAY,UAAU,QAAQ,OAAO;GACrE,MAAM,eAAe,0BACnB,QAAQ,kBACV;GACA,aAAa,IAAI,QAAQ,OAAO,IAAI,CAAC;GACrC,aAAa,IAAI,SAAS,KAAK;GAE/B,MAAM,UAAU,GAAG,OAAO,uBAAuB,aAAa,SAAS;GAEvE,OAAO,4CAAwCC,sCAAa,OAAO,GAAG;GAEtE,sCAAY,OAAO;EACrB,CAAC;CACH,CAAC;AACH"}
|
package/dist/cjs/build.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
let _intlayer_config_node = require("@intlayer/config/node");
|
|
3
|
+
let _intlayer_engine_logConfigDetails = require("@intlayer/engine/logConfigDetails");
|
|
3
4
|
let _intlayer_engine_utils = require("@intlayer/engine/utils");
|
|
4
5
|
let _intlayer_engine_watcher = require("@intlayer/engine/watcher");
|
|
5
|
-
let _intlayer_engine_logConfigDetails = require("@intlayer/engine/logConfigDetails");
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
// src/build.ts
|
|
8
8
|
/**
|
|
9
9
|
* Get locales dictionaries .content.{json|ts|tsx|js|jsx|mjs|cjs} and build the JSON dictionaries in the .intlayer directory.
|
|
10
10
|
* Watch mode available to get the change in the .content.{json|ts|tsx|js|jsx|mjs|cjs}
|
|
@@ -32,6 +32,5 @@ const build = async (options) => {
|
|
|
32
32
|
if (!options?.watch && parallelProcess) parallelProcess.kill();
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
//#endregion
|
|
36
35
|
exports.build = build;
|
|
37
36
|
//# sourceMappingURL=build.cjs.map
|
package/dist/cjs/bundle.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
|
|
2
|
+
// src/bundle.ts
|
|
3
3
|
/**
|
|
4
4
|
* Computes the tree-shaking defines derived from the project's built
|
|
5
5
|
* dictionaries (unused node types, dictionary selector usage) so the generated
|
|
@@ -41,6 +41,5 @@ const bundle = async (options) => {
|
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
//#endregion
|
|
45
44
|
exports.bundle = bundle;
|
|
46
45
|
//# sourceMappingURL=bundle.cjs.map
|
package/dist/cjs/ci.cjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
let _intlayer_config_logger = require("@intlayer/config/logger");
|
|
2
3
|
let _intlayer_engine_cli = require("@intlayer/engine/cli");
|
|
3
4
|
let node_path = require("node:path");
|
|
4
|
-
let _intlayer_config_logger = require("@intlayer/config/logger");
|
|
5
5
|
let node_child_process = require("node:child_process");
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
// src/ci.ts
|
|
8
8
|
/**
|
|
9
9
|
* Detects the command used to run the local `intlayer` binary. Prefers the
|
|
10
10
|
* package manager that launched the current process (`npm_config_user_agent`),
|
|
@@ -149,7 +149,6 @@ const runCI = async (commands) => {
|
|
|
149
149
|
return 0;
|
|
150
150
|
};
|
|
151
151
|
|
|
152
|
-
//#endregion
|
|
153
152
|
exports.CI_FLAG = CI_FLAG;
|
|
154
153
|
exports.credentialsKeyMatchesProject = credentialsKeyMatchesProject;
|
|
155
154
|
exports.getPackageManagerCommand = getPackageManagerCommand;
|
package/dist/cjs/cli.cjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_utils_getParentPackageJSON = require(
|
|
3
|
-
let node_path = require("node:path");
|
|
4
|
-
let node_url = require("node:url");
|
|
2
|
+
const require_utils_getParentPackageJSON = require("./utils/getParentPackageJSON.cjs");
|
|
5
3
|
let _intlayer_config_logger = require("@intlayer/config/logger");
|
|
6
4
|
let _intlayer_config_node = require("@intlayer/config/node");
|
|
5
|
+
let node_path = require("node:path");
|
|
6
|
+
let node_url = require("node:url");
|
|
7
7
|
let commander = require("commander");
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
// src/cli.ts
|
|
10
10
|
const isESModule = typeof require("url").pathToFileURL(__filename).href === "string";
|
|
11
11
|
const dirname = isESModule ? (0, node_path.dirname)((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href)) : __dirname;
|
|
12
12
|
const packageJson = require_utils_getParentPackageJSON.getParentPackageJSON(dirname);
|
|
@@ -154,25 +154,27 @@ const setAPI = () => {
|
|
|
154
154
|
/**
|
|
155
155
|
* INIT
|
|
156
156
|
*/
|
|
157
|
-
const initCmd = program.command("init").enablePositionalOptions().description("Install the Intlayer packages and set up the framework. Use --interactive, or the init subcommands, for the other setup steps (CI, skills, MCP, VS Code, LSP, lint, CMS, …)").option("--project-root [projectRoot]", "Project root directory").option("--no-gitignore", "Do not add .intlayer to .gitignore").option("--no-github-actions", "With --interactive: do not scaffold the GitHub Actions workflows, even if selected").option("--no-framework-setup", "Do not set up the project (Intlayer config, tsconfig, bundler plugin, middleware/proxy, providers in layout/page)").option("-i, --interactive", "Interactively choose what to set up (packages, skills, MCP, VS Code extension, LSP, …). Needs a terminal").option("--routing <routing>", "Locale routing: prefix-no-default | prefix-all | no-prefix | search-params | none").action(async (options) => {
|
|
158
|
-
const { init, parseLocaleRoutingChoice, getRoutingInitOptions } = await Promise.resolve().then(() => require("./init.cjs"));
|
|
157
|
+
const initCmd = program.command("init").enablePositionalOptions().description("Install the Intlayer packages and set up the framework. Use --interactive, or the init subcommands, for the other setup steps (CI, skills, MCP, VS Code, LSP, lint, CMS, …)").option("--project-root [projectRoot]", "Project root directory").option("--no-gitignore", "Do not add .intlayer to .gitignore").option("--no-github-actions", "With --interactive: do not scaffold the GitHub Actions workflows, even if selected").option("--no-framework-setup", "Do not set up the project (Intlayer config, tsconfig, bundler plugin, middleware/proxy, providers in layout/page)").option("-i, --interactive", "Interactively choose what to set up (packages, skills, MCP, VS Code extension, LSP, …). Needs a terminal").option("--routing <routing>", "Locale routing: prefix-no-default | prefix-all | no-prefix | search-params | none").option("--content <layout>", "Content declaration layout: multilingual | per-locale | centralized | namespaces").option("--content-format <format>", "Content format, used with --content: ts | json (multilingual, per-locale), json | po (centralized, namespaces)").option("--message-format <format>", "Message format of JSON catalogs, used with --content centralized | namespaces: icu | i18next | vue-i18n | intlayer").action(async (options) => {
|
|
158
|
+
const { init, parseLocaleRoutingChoice, getRoutingInitOptions, getContentInitOptions } = await Promise.resolve().then(() => require("./init.cjs"));
|
|
159
159
|
return init(options.projectRoot, {
|
|
160
160
|
noGitignore: options.gitignore === false,
|
|
161
161
|
noGithubActions: options.githubActions === false,
|
|
162
162
|
noFrameworkSetup: options.frameworkSetup === false,
|
|
163
163
|
upgradeToVersion: packageJson.version,
|
|
164
|
-
...options.routing ? getRoutingInitOptions(parseLocaleRoutingChoice(options.routing)) : {}
|
|
164
|
+
...options.routing ? getRoutingInitOptions(parseLocaleRoutingChoice(options.routing)) : {},
|
|
165
|
+
...getContentInitOptions(options.content, options.contentFormat, options.messageFormat)
|
|
165
166
|
}, options.interactive === true);
|
|
166
167
|
});
|
|
167
168
|
initCmd.command("packages").description("Install the missing Intlayer packages and upgrade the outdated ones").option("--project-root [projectRoot]", "Project root directory").action(async (options) => {
|
|
168
169
|
const { initSteps } = await Promise.resolve().then(() => require("./init.cjs"));
|
|
169
170
|
return initSteps(options.projectRoot, ["packages"], { upgradeToVersion: packageJson.version });
|
|
170
171
|
});
|
|
171
|
-
initCmd.command("project").alias("framework").description("Set up the project: Intlayer config, tsconfig, bundler plugin, middleware/proxy, providers in layout/page and .gitignore").option("--project-root [projectRoot]", "Project root directory").option("--no-gitignore", "Do not add .intlayer to .gitignore").option("--routing <routing>", "Locale routing: prefix-no-default | prefix-all | no-prefix | search-params | none").action(async (options) => {
|
|
172
|
-
const { initSteps, parseLocaleRoutingChoice, getRoutingInitOptions } = await Promise.resolve().then(() => require("./init.cjs"));
|
|
172
|
+
initCmd.command("project").alias("framework").description("Set up the project: Intlayer config, tsconfig, bundler plugin, middleware/proxy, providers in layout/page and .gitignore").option("--project-root [projectRoot]", "Project root directory").option("--no-gitignore", "Do not add .intlayer to .gitignore").option("--routing <routing>", "Locale routing: prefix-no-default | prefix-all | no-prefix | search-params | none").option("--content <layout>", "Content declaration layout: multilingual | per-locale | centralized | namespaces").option("--content-format <format>", "Content format, used with --content: ts | json (multilingual, per-locale), json | po (centralized, namespaces)").option("--message-format <format>", "Message format of JSON catalogs, used with --content centralized | namespaces: icu | i18next | vue-i18n | intlayer").action(async (options) => {
|
|
173
|
+
const { initSteps, parseLocaleRoutingChoice, getRoutingInitOptions, getContentInitOptions } = await Promise.resolve().then(() => require("./init.cjs"));
|
|
173
174
|
return initSteps(options.projectRoot, ["projectSetup"], {
|
|
174
175
|
noGitignore: options.gitignore === false,
|
|
175
|
-
...options.routing ? getRoutingInitOptions(parseLocaleRoutingChoice(options.routing)) : {}
|
|
176
|
+
...options.routing ? getRoutingInitOptions(parseLocaleRoutingChoice(options.routing)) : {},
|
|
177
|
+
...getContentInitOptions(options.content, options.contentFormat, options.messageFormat)
|
|
176
178
|
});
|
|
177
179
|
});
|
|
178
180
|
initCmd.command("github-actions").alias("ci").description("Scaffold the fill and test GitHub Actions workflows that run on every pull request").option("--project-root [projectRoot]", "Project root directory").action(async (options) => {
|
|
@@ -210,6 +212,10 @@ const setAPI = () => {
|
|
|
210
212
|
const { initCms } = await Promise.resolve().then(() => require("./init.cjs"));
|
|
211
213
|
return initCms(options.projectRoot);
|
|
212
214
|
});
|
|
215
|
+
initCmd.command("repository").description("Connect the git repository of the project (GitHub, GitLab, Bitbucket, Codeberg, Gitee) to its CMS project and set its build settings, through your browser").option("--project-root [projectRoot]", "Project root directory").action(async (options) => {
|
|
216
|
+
const { initRepository } = await Promise.resolve().then(() => require("./init.cjs"));
|
|
217
|
+
return initRepository(options.projectRoot);
|
|
218
|
+
});
|
|
213
219
|
initCmd.command("infra").description("Set up the Intlayer infrastructure: desktop app, all-in-one Docker container or Docker Compose stack (runs https://intlayer.org/install.sh, or install.ps1 on Windows)").option("-m, --mode <mode>", "Skip the menu: desktop | docker | compose (required without a terminal)").action(async (options) => {
|
|
214
220
|
const { initInfra, parseInfraMode } = await Promise.resolve().then(() => require("./initInfra.cjs"));
|
|
215
221
|
return initInfra({ mode: options.mode ? parseInfraMode(options.mode) : void 0 });
|
|
@@ -578,7 +584,7 @@ const setAPI = () => {
|
|
|
578
584
|
/**
|
|
579
585
|
* SCAN
|
|
580
586
|
*/
|
|
581
|
-
const scanCmd = program.command("scan").description("Scan a website to measure its page size and audit its i18n / SEO health").argument("<url>", "URL of the website to scan").option("--no-deep", "Disable the deeper puppeteer-based render scan").option("--json", "Output the results as JSON");
|
|
587
|
+
const scanCmd = program.command("scan").description("Scan a website to measure its page size and audit its i18n / SEO health").argument("<url>", "URL or domain of the website to scan (e.g. intlayer.org)").option("--no-deep", "Disable the deeper puppeteer-based render scan").option("--json", "Output the results as JSON");
|
|
582
588
|
applyConfigOptions(scanCmd);
|
|
583
589
|
scanCmd.action(async (url, options) => {
|
|
584
590
|
const { scan } = await Promise.resolve().then(() => require("./scan.cjs"));
|
|
@@ -616,7 +622,6 @@ const setAPI = () => {
|
|
|
616
622
|
return program;
|
|
617
623
|
};
|
|
618
624
|
|
|
619
|
-
//#endregion
|
|
620
625
|
exports.dirname = dirname;
|
|
621
626
|
exports.setAPI = setAPI;
|
|
622
627
|
//# sourceMappingURL=cli.cjs.map
|