@intlayer/cli 6.0.0 → 6.0.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/fill/index.cjs +76 -84
- package/dist/cjs/fill/index.cjs.map +1 -1
- package/dist/cjs/{fill/getTargetDictionary.cjs → getTargetDictionary.cjs} +6 -15
- package/dist/cjs/getTargetDictionary.cjs.map +1 -0
- package/dist/cjs/listContentDeclaration.cjs +3 -12
- package/dist/cjs/listContentDeclaration.cjs.map +1 -1
- package/dist/cjs/liveSync.cjs +2 -2
- package/dist/cjs/liveSync.cjs.map +1 -1
- package/dist/cjs/pull.cjs +3 -6
- package/dist/cjs/pull.cjs.map +1 -1
- package/dist/cjs/push.cjs +13 -9
- package/dist/cjs/push.cjs.map +1 -1
- package/dist/cjs/pushConfig.cjs +3 -10
- package/dist/cjs/pushConfig.cjs.map +1 -1
- package/dist/cjs/reviewDoc.cjs +3 -2
- package/dist/cjs/reviewDoc.cjs.map +1 -1
- package/dist/cjs/test/index.cjs +1 -1
- package/dist/cjs/test/index.cjs.map +1 -1
- package/dist/cjs/test/listMissingTranslations.cjs +8 -16
- package/dist/cjs/test/listMissingTranslations.cjs.map +1 -1
- package/dist/cjs/translateDoc.cjs +3 -2
- package/dist/cjs/translateDoc.cjs.map +1 -1
- package/dist/cjs/utils/checkAccess.cjs +79 -0
- package/dist/cjs/utils/checkAccess.cjs.map +1 -0
- package/dist/esm/fill/index.mjs +83 -74
- package/dist/esm/fill/index.mjs.map +1 -1
- package/dist/esm/{fill/getTargetDictionary.mjs → getTargetDictionary.mjs} +4 -3
- package/dist/esm/getTargetDictionary.mjs.map +1 -0
- package/dist/esm/listContentDeclaration.mjs +2 -1
- package/dist/esm/listContentDeclaration.mjs.map +1 -1
- package/dist/esm/liveSync.mjs +2 -2
- package/dist/esm/liveSync.mjs.map +1 -1
- package/dist/esm/pull.mjs +3 -6
- package/dist/esm/pull.mjs.map +1 -1
- package/dist/esm/push.mjs +11 -7
- package/dist/esm/push.mjs.map +1 -1
- package/dist/esm/pushConfig.mjs +3 -10
- package/dist/esm/pushConfig.mjs.map +1 -1
- package/dist/esm/reviewDoc.mjs +3 -2
- package/dist/esm/reviewDoc.mjs.map +1 -1
- package/dist/esm/test/index.mjs +1 -1
- package/dist/esm/test/index.mjs.map +1 -1
- package/dist/esm/test/listMissingTranslations.mjs +8 -4
- package/dist/esm/test/listMissingTranslations.mjs.map +1 -1
- package/dist/esm/translateDoc.mjs +3 -2
- package/dist/esm/translateDoc.mjs.map +1 -1
- package/dist/esm/utils/checkAccess.mjs +54 -0
- package/dist/esm/utils/checkAccess.mjs.map +1 -0
- package/dist/types/fill/index.d.ts +3 -9
- package/dist/types/fill/index.d.ts.map +1 -1
- package/dist/types/getTargetDictionary.d.ts +15 -0
- package/dist/types/getTargetDictionary.d.ts.map +1 -0
- package/dist/types/listContentDeclaration.d.ts.map +1 -1
- package/dist/types/pull.d.ts.map +1 -1
- package/dist/types/push.d.ts.map +1 -1
- package/dist/types/pushConfig.d.ts.map +1 -1
- package/dist/types/reviewDoc.d.ts.map +1 -1
- package/dist/types/test/listMissingTranslations.d.ts +4 -4
- package/dist/types/test/listMissingTranslations.d.ts.map +1 -1
- package/dist/types/translateDoc.d.ts.map +1 -1
- package/dist/types/utils/checkAccess.d.ts +5 -0
- package/dist/types/utils/checkAccess.d.ts.map +1 -0
- package/package.json +16 -16
- package/dist/cjs/fill/getTargetDictionary.cjs.map +0 -1
- package/dist/cjs/utils/checkAIAccess.cjs +0 -44
- package/dist/cjs/utils/checkAIAccess.cjs.map +0 -1
- package/dist/esm/fill/getTargetDictionary.mjs.map +0 -1
- package/dist/esm/utils/checkAIAccess.mjs +0 -20
- package/dist/esm/utils/checkAIAccess.mjs.map +0 -1
- package/dist/types/fill/getTargetDictionary.d.ts +0 -4
- package/dist/types/fill/getTargetDictionary.d.ts.map +0 -1
- package/dist/types/utils/checkAIAccess.d.ts +0 -4
- package/dist/types/utils/checkAIAccess.d.ts.map +0 -1
package/dist/cjs/fill/index.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
var fill_exports = {};
|
|
30
20
|
__export(fill_exports, {
|
|
@@ -35,12 +25,11 @@ var import_api = require("@intlayer/api");
|
|
|
35
25
|
var import_chokidar = require("@intlayer/chokidar");
|
|
36
26
|
var import_config = require("@intlayer/config");
|
|
37
27
|
var import_core = require("@intlayer/core");
|
|
38
|
-
var import_dictionaries_entry =
|
|
39
|
-
var import_p_limit = __toESM(require("p-limit"));
|
|
28
|
+
var import_dictionaries_entry = require("@intlayer/dictionaries-entry");
|
|
40
29
|
var import_path = require("path");
|
|
41
|
-
var
|
|
30
|
+
var import_getTargetDictionary = require('../getTargetDictionary.cjs');
|
|
31
|
+
var import_checkAccess = require('../utils/checkAccess.cjs');
|
|
42
32
|
var import_autoFill = require('./autoFill.cjs');
|
|
43
|
-
var import_getTargetDictionary = require('./getTargetDictionary.cjs');
|
|
44
33
|
const NB_CONCURRENT_TRANSLATIONS = 8;
|
|
45
34
|
const fill = async (options) => {
|
|
46
35
|
const configuration = (0, import_config.getConfiguration)(options.configOptions);
|
|
@@ -56,37 +45,40 @@ const fill = async (options) => {
|
|
|
56
45
|
const mode = options.mode ?? "complete";
|
|
57
46
|
const baseLocale = options.sourceLocale ?? defaultLocale;
|
|
58
47
|
const outputLocales = (options.outputLocales ? (0, import_getTargetDictionary.ensureArray)(options.outputLocales) : locales).filter((locale) => locale !== baseLocale);
|
|
59
|
-
(0,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const oAuth2TokenResult = await intlayerAuthAPI.getOAuth2AccessToken();
|
|
64
|
-
oAuth2AccessToken = oAuth2TokenResult.data?.accessToken;
|
|
65
|
-
}
|
|
66
|
-
appLogger("Starting fill function", {
|
|
67
|
-
level: "info"
|
|
68
|
-
});
|
|
69
|
-
const targetUnmergedDictionaries = await (0, import_getTargetDictionary.getTargetDictionary)(options);
|
|
48
|
+
const hasAIAccess = await (0, import_checkAccess.checkAIAccess)(configuration, options.aiOptions);
|
|
49
|
+
if (!hasAIAccess) return;
|
|
50
|
+
const intlayerAPI = (0, import_api.getIntlayerAPIProxy)(void 0, configuration);
|
|
51
|
+
const targetUnmergedDictionaries = await (0, import_getTargetDictionary.getTargetUnmergedDictionaries)(options);
|
|
70
52
|
const affectedDictionaryKeys = /* @__PURE__ */ new Set();
|
|
71
53
|
targetUnmergedDictionaries.forEach((dict) => {
|
|
72
54
|
affectedDictionaryKeys.add(dict.key);
|
|
73
55
|
});
|
|
74
|
-
appLogger(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
56
|
+
appLogger([
|
|
57
|
+
"Affected dictionary keys for processing:",
|
|
58
|
+
Array.from(affectedDictionaryKeys).map((key) => (0, import_config.colorizeKey)(key)).join(", ")
|
|
59
|
+
]);
|
|
60
|
+
const maxKeyLength = Math.max(
|
|
61
|
+
...targetUnmergedDictionaries.map((dict) => dict.key.length)
|
|
62
|
+
);
|
|
63
|
+
const maxLocaleLength = Math.max(
|
|
64
|
+
...locales.map((locale) => (0, import_chokidar.formatLocale)(locale).length)
|
|
82
65
|
);
|
|
83
66
|
for (const targetUnmergedDictionary of targetUnmergedDictionaries) {
|
|
67
|
+
const dictionaryPreset = (0, import_config.colon)(
|
|
68
|
+
[
|
|
69
|
+
(0, import_config.colorize)(" - [", import_config.ANSIColors.GREY_DARK),
|
|
70
|
+
(0, import_config.colorizeKey)(targetUnmergedDictionary.key),
|
|
71
|
+
(0, import_config.colorize)("]", import_config.ANSIColors.GREY_DARK)
|
|
72
|
+
].join(""),
|
|
73
|
+
{ colSize: maxKeyLength + 6 }
|
|
74
|
+
);
|
|
84
75
|
const dictionaryKey = targetUnmergedDictionary.key;
|
|
85
|
-
const
|
|
76
|
+
const dictionariesRecord = (0, import_dictionaries_entry.getDictionaries)(configuration);
|
|
77
|
+
const mainDictionaryToProcess = dictionariesRecord[dictionaryKey];
|
|
86
78
|
const sourceLocale = targetUnmergedDictionary.locale ?? baseLocale;
|
|
87
79
|
if (!mainDictionaryToProcess) {
|
|
88
80
|
appLogger(
|
|
89
|
-
|
|
81
|
+
`${dictionaryPreset} Dictionary not found in dictionariesRecord. Skipping.`,
|
|
90
82
|
{
|
|
91
83
|
level: "warn"
|
|
92
84
|
}
|
|
@@ -94,21 +86,21 @@ const fill = async (options) => {
|
|
|
94
86
|
continue;
|
|
95
87
|
}
|
|
96
88
|
if (!targetUnmergedDictionary.filePath) {
|
|
97
|
-
appLogger(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
level: "warn"
|
|
101
|
-
}
|
|
102
|
-
);
|
|
89
|
+
appLogger(`${dictionaryPreset} Dictionary has no file path. Skipping.`, {
|
|
90
|
+
level: "warn"
|
|
91
|
+
});
|
|
103
92
|
continue;
|
|
104
93
|
}
|
|
105
94
|
const relativePath = (0, import_path.relative)(
|
|
106
95
|
configuration.content.baseDir,
|
|
107
96
|
targetUnmergedDictionary.filePath
|
|
108
97
|
);
|
|
109
|
-
appLogger(
|
|
110
|
-
|
|
111
|
-
|
|
98
|
+
appLogger(
|
|
99
|
+
`${dictionaryPreset} Processing content declaration: ${(0, import_config.colorizePath)(relativePath)}`,
|
|
100
|
+
{
|
|
101
|
+
level: "info"
|
|
102
|
+
}
|
|
103
|
+
);
|
|
112
104
|
const sourceLocaleContent = (0, import_core.getFilterTranslationsOnlyContent)(
|
|
113
105
|
mainDictionaryToProcess,
|
|
114
106
|
sourceLocale,
|
|
@@ -116,7 +108,7 @@ const fill = async (options) => {
|
|
|
116
108
|
);
|
|
117
109
|
if (Object.keys(sourceLocaleContent).length === 0) {
|
|
118
110
|
appLogger(
|
|
119
|
-
|
|
111
|
+
`${dictionaryPreset} No content found for dictionary in source locale ${(0, import_chokidar.formatLocale)(sourceLocale)}. Skipping translation for this dictionary.`,
|
|
120
112
|
{
|
|
121
113
|
level: "warn"
|
|
122
114
|
}
|
|
@@ -124,9 +116,6 @@ const fill = async (options) => {
|
|
|
124
116
|
continue;
|
|
125
117
|
}
|
|
126
118
|
const result = [];
|
|
127
|
-
const limit = (0, import_p_limit.default)(
|
|
128
|
-
options.nbConcurrentTranslations ?? NB_CONCURRENT_TRANSLATIONS
|
|
129
|
-
);
|
|
130
119
|
let outputLocalesList = outputLocales;
|
|
131
120
|
if (mode === "complete") {
|
|
132
121
|
const missingLocales = (0, import_core.getMissingLocalesContent)(
|
|
@@ -140,10 +129,28 @@ const fill = async (options) => {
|
|
|
140
129
|
);
|
|
141
130
|
outputLocalesList = missingLocales;
|
|
142
131
|
}
|
|
143
|
-
|
|
144
|
-
(
|
|
132
|
+
if (outputLocalesList.length === 0) {
|
|
133
|
+
appLogger(
|
|
134
|
+
`${dictionaryPreset} No locales to fill - Skipping dictionary`,
|
|
135
|
+
{
|
|
136
|
+
level: "warn"
|
|
137
|
+
}
|
|
138
|
+
);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const translationResults = await (0, import_chokidar.parallelize)(
|
|
142
|
+
outputLocalesList,
|
|
143
|
+
async (targetLocale) => {
|
|
144
|
+
const localePreset = (0, import_config.colon)(
|
|
145
|
+
[
|
|
146
|
+
(0, import_config.colorize)("[", import_config.ANSIColors.GREY_DARK),
|
|
147
|
+
(0, import_chokidar.formatLocale)(targetLocale),
|
|
148
|
+
(0, import_config.colorize)("]", import_config.ANSIColors.GREY_DARK)
|
|
149
|
+
].join(""),
|
|
150
|
+
{ colSize: maxLocaleLength }
|
|
151
|
+
);
|
|
145
152
|
appLogger(
|
|
146
|
-
|
|
153
|
+
`${dictionaryPreset}${localePreset} Preparing translation for dictionary from ${(0, import_chokidar.formatLocale)(sourceLocale)} to ${(0, import_chokidar.formatLocale)(targetLocale)}`,
|
|
147
154
|
{
|
|
148
155
|
level: "info"
|
|
149
156
|
}
|
|
@@ -154,36 +161,21 @@ const fill = async (options) => {
|
|
|
154
161
|
{ dictionaryKey, keyPath: [] }
|
|
155
162
|
);
|
|
156
163
|
try {
|
|
157
|
-
const translationResult = await
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
outputLocale: targetLocale,
|
|
169
|
-
mode,
|
|
170
|
-
aiOptions: options.aiOptions
|
|
171
|
-
},
|
|
172
|
-
{
|
|
173
|
-
...oAuth2AccessToken && {
|
|
174
|
-
headers: {
|
|
175
|
-
Authorization: `Bearer ${oAuth2AccessToken}`
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
);
|
|
164
|
+
const translationResult = await intlayerAPI.ai.translateJSON({
|
|
165
|
+
entryFileContent: sourceLocaleContent.content,
|
|
166
|
+
// Should be JSON, ensure getLocalisedContent provides this.
|
|
167
|
+
presetOutputContent: presetOutputContent.content,
|
|
168
|
+
// Should be JSON
|
|
169
|
+
dictionaryDescription: mainDictionaryToProcess.description ?? "",
|
|
170
|
+
entryLocale: sourceLocale,
|
|
171
|
+
outputLocale: targetLocale,
|
|
172
|
+
mode,
|
|
173
|
+
aiOptions: options.aiOptions
|
|
174
|
+
});
|
|
180
175
|
if (!translationResult.data?.fileContent) {
|
|
181
|
-
appLogger(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
level: "error"
|
|
185
|
-
}
|
|
186
|
-
);
|
|
176
|
+
appLogger(`${dictionaryPreset}${localePreset} No content result`, {
|
|
177
|
+
level: "error"
|
|
178
|
+
});
|
|
187
179
|
return null;
|
|
188
180
|
}
|
|
189
181
|
const processedPerLocaleDictionary = (0, import_chokidar.processPerLocaleDictionary)({
|
|
@@ -194,16 +186,16 @@ const fill = async (options) => {
|
|
|
194
186
|
return processedPerLocaleDictionary;
|
|
195
187
|
} catch (error) {
|
|
196
188
|
appLogger(
|
|
197
|
-
|
|
189
|
+
`${dictionaryPreset}${localePreset} ${(0, import_config.colorize)("Error filling", import_config.ANSIColors.RED)}: ` + error,
|
|
198
190
|
{
|
|
199
191
|
level: "error"
|
|
200
192
|
}
|
|
201
193
|
);
|
|
202
194
|
return null;
|
|
203
195
|
}
|
|
204
|
-
}
|
|
196
|
+
},
|
|
197
|
+
options.nbConcurrentTranslations ?? NB_CONCURRENT_TRANSLATIONS
|
|
205
198
|
);
|
|
206
|
-
const translationResults = await Promise.all(translationPromises);
|
|
207
199
|
translationResults.forEach((translationResult) => {
|
|
208
200
|
if (translationResult) {
|
|
209
201
|
result.push(translationResult);
|
|
@@ -241,7 +233,7 @@ const fill = async (options) => {
|
|
|
241
233
|
);
|
|
242
234
|
if (formattedDict.filePath) {
|
|
243
235
|
appLogger(
|
|
244
|
-
|
|
236
|
+
`${dictionaryPreset} Content declaration written to ${(0, import_chokidar.formatPath)(formattedDict.filePath)}`,
|
|
245
237
|
{
|
|
246
238
|
level: "info"
|
|
247
239
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/fill/index.ts"],"sourcesContent":["import { AIOptions, getAiAPI, getOAuthAPI } from '@intlayer/api'; // Importing only getAiAPI for now\nimport {\n formatLocale,\n formatPath,\n ListGitFilesOptions,\n mergeDictionaries,\n prepareIntlayer,\n processPerLocaleDictionary,\n reduceDictionaryContent,\n writeContentDeclaration,\n} from '@intlayer/chokidar';\nimport {\n colorizeKey,\n colorizePath,\n getAppLogger,\n getConfiguration,\n GetConfigurationOptions,\n Locales,\n} from '@intlayer/config';\nimport {\n type ContentNode,\n type Dictionary,\n getFilterTranslationsOnlyContent,\n getLocalisedContent,\n getMissingLocalesContent,\n} from '@intlayer/core';\nimport dictionariesRecord from '@intlayer/dictionaries-entry';\nimport pLimit from 'p-limit';\nimport { relative } from 'path';\nimport { checkAIAccess } from '../utils/checkAIAccess';\nimport { autoFill } from './autoFill';\nimport { ensureArray, getTargetDictionary } from './getTargetDictionary';\n\nconst NB_CONCURRENT_TRANSLATIONS = 8;\n\n// Arguments for the fill function\nexport type FillOptions = {\n sourceLocale?: Locales;\n outputLocales?: Locales | Locales[];\n file?: string | string[];\n mode?: 'complete' | 'review';\n keys?: string | string[];\n excludedKeys?: string | string[];\n filter?: (entry: Dictionary) => boolean; // DictionaryEntry needs to be defined\n pathFilter?: string | string[];\n gitOptions?: ListGitFilesOptions;\n configOptions?: GetConfigurationOptions;\n aiOptions?: AIOptions; // Added aiOptions to be passed to translateJSON\n verbose?: boolean;\n nbConcurrentTranslations?: number;\n build?: boolean;\n};\n\n/**\n * Fill translations based on the provided options.\n */\nexport const fill = async (options: FillOptions): Promise<void> => {\n const configuration = getConfiguration(options.configOptions);\n const appLogger = getAppLogger(configuration, {\n config: {\n prefix: '',\n },\n });\n\n if (options.build) {\n await prepareIntlayer(configuration);\n }\n\n const { defaultLocale, locales } = configuration.internationalization;\n const mode = options.mode ?? 'complete';\n const baseLocale = options.sourceLocale ?? defaultLocale;\n const outputLocales = (\n options.outputLocales ? ensureArray(options.outputLocales) : locales\n ).filter((locale) => locale !== baseLocale);\n\n checkAIAccess(configuration, options.aiOptions);\n\n let oAuth2AccessToken: string | undefined;\n if (configuration.editor.clientId) {\n const intlayerAuthAPI = getOAuthAPI(configuration);\n const oAuth2TokenResult = await intlayerAuthAPI.getOAuth2AccessToken();\n\n oAuth2AccessToken = oAuth2TokenResult.data?.accessToken;\n }\n\n appLogger('Starting fill function', {\n level: 'info',\n });\n\n const targetUnmergedDictionaries = await getTargetDictionary(options);\n\n const affectedDictionaryKeys = new Set<string>();\n targetUnmergedDictionaries.forEach((dict) => {\n affectedDictionaryKeys.add(dict.key);\n });\n\n appLogger(\n [\n 'Affected dictionary keys for processing:',\n Array.from(affectedDictionaryKeys)\n .map((key) => colorizeKey(key))\n .join(', '),\n ],\n {\n isVerbose: true,\n }\n );\n\n for (const targetUnmergedDictionary of targetUnmergedDictionaries) {\n const dictionaryKey = targetUnmergedDictionary.key;\n const mainDictionaryToProcess = dictionariesRecord[dictionaryKey];\n const sourceLocale: Locales =\n (targetUnmergedDictionary.locale as Locales) ?? baseLocale;\n\n if (!mainDictionaryToProcess) {\n appLogger(\n `Dictionary with key '${colorizeKey(dictionaryKey)}' not found in dictionariesRecord. Skipping.`,\n {\n level: 'warn',\n }\n );\n continue;\n }\n\n if (!targetUnmergedDictionary.filePath) {\n appLogger(\n `Dictionary with key '${colorizeKey(dictionaryKey)}' has no file path. Skipping.`,\n {\n level: 'warn',\n }\n );\n continue;\n }\n\n const relativePath = relative(\n configuration.content.baseDir,\n targetUnmergedDictionary.filePath\n );\n\n appLogger(`Processing content declaration: ${colorizePath(relativePath)}`, {\n level: 'info',\n });\n\n const sourceLocaleContent = getFilterTranslationsOnlyContent(\n mainDictionaryToProcess as unknown as ContentNode,\n sourceLocale,\n { dictionaryKey, keyPath: [] }\n );\n\n if (Object.keys(sourceLocaleContent).length === 0) {\n appLogger(\n `No content found for dictionary '${colorizeKey(dictionaryKey)}' in source locale ${formatLocale(sourceLocale)}. Skipping translation for this dictionary.`,\n {\n level: 'warn',\n }\n );\n continue;\n }\n\n const result: Dictionary[] = [];\n\n // 5. for each locale to translate (exclude base locale) generate json translations\n // Limit concurrent translations to 5 at a time\n const limit = pLimit(\n options.nbConcurrentTranslations ?? NB_CONCURRENT_TRANSLATIONS\n );\n\n // Determine output locales\n let outputLocalesList: Locales[] = outputLocales;\n\n // If mode is review, translate all locales\n // If mode is complete, translate only the locales that are not the source locale\n if (mode === 'complete') {\n const missingLocales = getMissingLocalesContent(\n mainDictionaryToProcess as unknown as ContentNode,\n outputLocales,\n {\n dictionaryKey: mainDictionaryToProcess.key,\n keyPath: [],\n plugins: [],\n }\n );\n\n outputLocalesList = missingLocales;\n }\n\n const translationPromises = outputLocalesList.map((targetLocale) =>\n limit(async () => {\n appLogger(\n `Preparing translation for '${colorizeKey(dictionaryKey)}' dictionary from ${formatLocale(sourceLocale)} to ${formatLocale(targetLocale)}`,\n {\n level: 'info',\n }\n );\n\n const presetOutputContent = getLocalisedContent(\n mainDictionaryToProcess as unknown as ContentNode,\n targetLocale,\n { dictionaryKey, keyPath: [] }\n );\n\n try {\n const translationResult = await getAiAPI(\n undefined,\n configuration\n ).translateJSON(\n {\n entryFileContent: sourceLocaleContent.content, // Should be JSON, ensure getLocalisedContent provides this.\n presetOutputContent: presetOutputContent.content, // Should be JSON\n dictionaryDescription: mainDictionaryToProcess.description,\n entryLocale: sourceLocale,\n outputLocale: targetLocale,\n mode,\n aiOptions: options.aiOptions,\n },\n {\n ...(oAuth2AccessToken && {\n headers: {\n Authorization: `Bearer ${oAuth2AccessToken}`,\n },\n }),\n }\n );\n\n if (!translationResult.data?.fileContent) {\n appLogger(\n `No content result found for '${colorizeKey(dictionaryKey)}' to ${formatLocale(targetLocale)}`,\n {\n level: 'error',\n }\n );\n return null;\n }\n\n const processedPerLocaleDictionary = processPerLocaleDictionary({\n ...mainDictionaryToProcess,\n content: translationResult.data?.fileContent,\n locale: targetLocale,\n });\n\n return processedPerLocaleDictionary;\n } catch (error) {\n appLogger(\n `Error filling '${colorizeKey(dictionaryKey)}' to ${formatLocale(targetLocale)}:` +\n error,\n {\n level: 'error',\n }\n );\n return null;\n }\n })\n );\n\n // Wait for all translations to complete\n const translationResults = await Promise.all(translationPromises);\n\n // Filter out null results and add to result array\n translationResults.forEach((translationResult) => {\n if (translationResult) {\n result.push(translationResult);\n }\n });\n\n const dictionaryToMerge =\n mode === 'review'\n ? [...result, mainDictionaryToProcess] // Mode review: generated content will override the base one\n : [mainDictionaryToProcess, ...result]; // Mode complete: base content will override the generated one\n\n const mergedResults = mergeDictionaries(dictionaryToMerge);\n\n let formattedDict = targetUnmergedDictionary;\n\n if (formattedDict.locale) {\n const presetOutputContent = getLocalisedContent(\n mainDictionaryToProcess as unknown as ContentNode,\n formattedDict.locale,\n { dictionaryKey, keyPath: [] }\n );\n\n formattedDict = {\n ...formattedDict,\n content: presetOutputContent.content,\n };\n }\n\n const reducedResult = reduceDictionaryContent(mergedResults, formattedDict);\n\n if (formattedDict.autoFill || configuration.content.autoFill) {\n await autoFill(\n mergedResults,\n targetUnmergedDictionary,\n formattedDict.autoFill ?? configuration.content.autoFill,\n outputLocalesList,\n [sourceLocale],\n configuration\n );\n } else {\n await writeContentDeclaration(\n { ...formattedDict, content: reducedResult.content },\n configuration,\n formattedDict.filePath\n );\n\n if (formattedDict.filePath) {\n appLogger(\n `Content declaration for '${colorizeKey(dictionaryKey)}' written to ${formatPath(formattedDict.filePath)}`,\n {\n level: 'info',\n }\n );\n }\n }\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAiD;AACjD,sBASO;AACP,oBAOO;AACP,kBAMO;AACP,gCAA+B;AAC/B,qBAAmB;AACnB,kBAAyB;AACzB,2BAA8B;AAC9B,sBAAyB;AACzB,iCAAiD;AAEjD,MAAM,6BAA6B;AAuB5B,MAAM,OAAO,OAAO,YAAwC;AACjE,QAAM,oBAAgB,gCAAiB,QAAQ,aAAa;AAC5D,QAAM,gBAAY,4BAAa,eAAe;AAAA,IAC5C,QAAQ;AAAA,MACN,QAAQ;AAAA,IACV;AAAA,EACF,CAAC;AAED,MAAI,QAAQ,OAAO;AACjB,cAAM,iCAAgB,aAAa;AAAA,EACrC;AAEA,QAAM,EAAE,eAAe,QAAQ,IAAI,cAAc;AACjD,QAAM,OAAO,QAAQ,QAAQ;AAC7B,QAAM,aAAa,QAAQ,gBAAgB;AAC3C,QAAM,iBACJ,QAAQ,oBAAgB,wCAAY,QAAQ,aAAa,IAAI,SAC7D,OAAO,CAAC,WAAW,WAAW,UAAU;AAE1C,0CAAc,eAAe,QAAQ,SAAS;AAE9C,MAAI;AACJ,MAAI,cAAc,OAAO,UAAU;AACjC,UAAM,sBAAkB,wBAAY,aAAa;AACjD,UAAM,oBAAoB,MAAM,gBAAgB,qBAAqB;AAErE,wBAAoB,kBAAkB,MAAM;AAAA,EAC9C;AAEA,YAAU,0BAA0B;AAAA,IAClC,OAAO;AAAA,EACT,CAAC;AAED,QAAM,6BAA6B,UAAM,gDAAoB,OAAO;AAEpE,QAAM,yBAAyB,oBAAI,IAAY;AAC/C,6BAA2B,QAAQ,CAAC,SAAS;AAC3C,2BAAuB,IAAI,KAAK,GAAG;AAAA,EACrC,CAAC;AAED;AAAA,IACE;AAAA,MACE;AAAA,MACA,MAAM,KAAK,sBAAsB,EAC9B,IAAI,CAAC,YAAQ,2BAAY,GAAG,CAAC,EAC7B,KAAK,IAAI;AAAA,IACd;AAAA,IACA;AAAA,MACE,WAAW;AAAA,IACb;AAAA,EACF;AAEA,aAAW,4BAA4B,4BAA4B;AACjE,UAAM,gBAAgB,yBAAyB;AAC/C,UAAM,0BAA0B,0BAAAA,QAAmB,aAAa;AAChE,UAAM,eACH,yBAAyB,UAAsB;AAElD,QAAI,CAAC,yBAAyB;AAC5B;AAAA,QACE,4BAAwB,2BAAY,aAAa,CAAC;AAAA,QAClD;AAAA,UACE,OAAO;AAAA,QACT;AAAA,MACF;AACA;AAAA,IACF;AAEA,QAAI,CAAC,yBAAyB,UAAU;AACtC;AAAA,QACE,4BAAwB,2BAAY,aAAa,CAAC;AAAA,QAClD;AAAA,UACE,OAAO;AAAA,QACT;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,mBAAe;AAAA,MACnB,cAAc,QAAQ;AAAA,MACtB,yBAAyB;AAAA,IAC3B;AAEA,cAAU,uCAAmC,4BAAa,YAAY,CAAC,IAAI;AAAA,MACzE,OAAO;AAAA,IACT,CAAC;AAED,UAAM,0BAAsB;AAAA,MAC1B;AAAA,MACA;AAAA,MACA,EAAE,eAAe,SAAS,CAAC,EAAE;AAAA,IAC/B;AAEA,QAAI,OAAO,KAAK,mBAAmB,EAAE,WAAW,GAAG;AACjD;AAAA,QACE,wCAAoC,2BAAY,aAAa,CAAC,0BAAsB,8BAAa,YAAY,CAAC;AAAA,QAC9G;AAAA,UACE,OAAO;AAAA,QACT;AAAA,MACF;AACA;AAAA,IACF;AAEA,UAAM,SAAuB,CAAC;AAI9B,UAAM,YAAQ,eAAAC;AAAA,MACZ,QAAQ,4BAA4B;AAAA,IACtC;AAGA,QAAI,oBAA+B;AAInC,QAAI,SAAS,YAAY;AACvB,YAAM,qBAAiB;AAAA,QACrB;AAAA,QACA;AAAA,QACA;AAAA,UACE,eAAe,wBAAwB;AAAA,UACvC,SAAS,CAAC;AAAA,UACV,SAAS,CAAC;AAAA,QACZ;AAAA,MACF;AAEA,0BAAoB;AAAA,IACtB;AAEA,UAAM,sBAAsB,kBAAkB;AAAA,MAAI,CAAC,iBACjD,MAAM,YAAY;AAChB;AAAA,UACE,kCAA8B,2BAAY,aAAa,CAAC,yBAAqB,8BAAa,YAAY,CAAC,WAAO,8BAAa,YAAY,CAAC;AAAA,UACxI;AAAA,YACE,OAAO;AAAA,UACT;AAAA,QACF;AAEA,cAAM,0BAAsB;AAAA,UAC1B;AAAA,UACA;AAAA,UACA,EAAE,eAAe,SAAS,CAAC,EAAE;AAAA,QAC/B;AAEA,YAAI;AACF,gBAAM,oBAAoB,UAAM;AAAA,YAC9B;AAAA,YACA;AAAA,UACF,EAAE;AAAA,YACA;AAAA,cACE,kBAAkB,oBAAoB;AAAA;AAAA,cACtC,qBAAqB,oBAAoB;AAAA;AAAA,cACzC,uBAAuB,wBAAwB;AAAA,cAC/C,aAAa;AAAA,cACb,cAAc;AAAA,cACd;AAAA,cACA,WAAW,QAAQ;AAAA,YACrB;AAAA,YACA;AAAA,cACE,GAAI,qBAAqB;AAAA,gBACvB,SAAS;AAAA,kBACP,eAAe,UAAU,iBAAiB;AAAA,gBAC5C;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAEA,cAAI,CAAC,kBAAkB,MAAM,aAAa;AACxC;AAAA,cACE,oCAAgC,2BAAY,aAAa,CAAC,YAAQ,8BAAa,YAAY,CAAC;AAAA,cAC5F;AAAA,gBACE,OAAO;AAAA,cACT;AAAA,YACF;AACA,mBAAO;AAAA,UACT;AAEA,gBAAM,mCAA+B,4CAA2B;AAAA,YAC9D,GAAG;AAAA,YACH,SAAS,kBAAkB,MAAM;AAAA,YACjC,QAAQ;AAAA,UACV,CAAC;AAED,iBAAO;AAAA,QACT,SAAS,OAAO;AACd;AAAA,YACE,sBAAkB,2BAAY,aAAa,CAAC,YAAQ,8BAAa,YAAY,CAAC,MAC5E;AAAA,YACF;AAAA,cACE,OAAO;AAAA,YACT;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AAAA,MACF,CAAC;AAAA,IACH;AAGA,UAAM,qBAAqB,MAAM,QAAQ,IAAI,mBAAmB;AAGhE,uBAAmB,QAAQ,CAAC,sBAAsB;AAChD,UAAI,mBAAmB;AACrB,eAAO,KAAK,iBAAiB;AAAA,MAC/B;AAAA,IACF,CAAC;AAED,UAAM,oBACJ,SAAS,WACL,CAAC,GAAG,QAAQ,uBAAuB,IACnC,CAAC,yBAAyB,GAAG,MAAM;AAEzC,UAAM,oBAAgB,mCAAkB,iBAAiB;AAEzD,QAAI,gBAAgB;AAEpB,QAAI,cAAc,QAAQ;AACxB,YAAM,0BAAsB;AAAA,QAC1B;AAAA,QACA,cAAc;AAAA,QACd,EAAE,eAAe,SAAS,CAAC,EAAE;AAAA,MAC/B;AAEA,sBAAgB;AAAA,QACd,GAAG;AAAA,QACH,SAAS,oBAAoB;AAAA,MAC/B;AAAA,IACF;AAEA,UAAM,oBAAgB,yCAAwB,eAAe,aAAa;AAE1E,QAAI,cAAc,YAAY,cAAc,QAAQ,UAAU;AAC5D,gBAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA,cAAc,YAAY,cAAc,QAAQ;AAAA,QAChD;AAAA,QACA,CAAC,YAAY;AAAA,QACb;AAAA,MACF;AAAA,IACF,OAAO;AACL,gBAAM;AAAA,QACJ,EAAE,GAAG,eAAe,SAAS,cAAc,QAAQ;AAAA,QACnD;AAAA,QACA,cAAc;AAAA,MAChB;AAEA,UAAI,cAAc,UAAU;AAC1B;AAAA,UACE,gCAA4B,2BAAY,aAAa,CAAC,oBAAgB,4BAAW,cAAc,QAAQ,CAAC;AAAA,UACxG;AAAA,YACE,OAAO;AAAA,UACT;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":["dictionariesRecord","pLimit"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/fill/index.ts"],"sourcesContent":["import { AIOptions, getIntlayerAPIProxy } from '@intlayer/api'; // Importing only getAiAPI for now\nimport {\n formatLocale,\n formatPath,\n ListGitFilesOptions,\n mergeDictionaries,\n parallelize,\n prepareIntlayer,\n processPerLocaleDictionary,\n reduceDictionaryContent,\n writeContentDeclaration,\n} from '@intlayer/chokidar';\nimport {\n ANSIColors,\n colon,\n colorize,\n colorizeKey,\n colorizePath,\n getAppLogger,\n getConfiguration,\n Locales,\n} from '@intlayer/config';\nimport {\n type ContentNode,\n type Dictionary,\n getFilterTranslationsOnlyContent,\n getLocalisedContent,\n getMissingLocalesContent,\n} from '@intlayer/core';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport { relative } from 'path';\nimport {\n ensureArray,\n GetTargetDictionaryOptions,\n getTargetUnmergedDictionaries,\n} from '../getTargetDictionary';\nimport { checkAIAccess } from '../utils/checkAccess';\nimport { autoFill } from './autoFill';\n\nconst NB_CONCURRENT_TRANSLATIONS = 8;\n\n// Arguments for the fill function\nexport type FillOptions = {\n sourceLocale?: Locales;\n outputLocales?: Locales | Locales[];\n mode?: 'complete' | 'review';\n gitOptions?: ListGitFilesOptions;\n aiOptions?: AIOptions; // Added aiOptions to be passed to translateJSON\n verbose?: boolean;\n nbConcurrentTranslations?: number;\n build?: boolean;\n} & GetTargetDictionaryOptions;\n\n/**\n * Fill translations based on the provided options.\n */\nexport const fill = async (options: FillOptions): Promise<void> => {\n const configuration = getConfiguration(options.configOptions);\n const appLogger = getAppLogger(configuration, {\n config: {\n prefix: '',\n },\n });\n\n if (options.build) {\n await prepareIntlayer(configuration);\n }\n\n const { defaultLocale, locales } = configuration.internationalization;\n const mode = options.mode ?? 'complete';\n const baseLocale = options.sourceLocale ?? defaultLocale;\n const outputLocales = (\n options.outputLocales ? ensureArray(options.outputLocales) : locales\n ).filter((locale) => locale !== baseLocale);\n\n const hasAIAccess = await checkAIAccess(configuration, options.aiOptions);\n\n if (!hasAIAccess) return;\n\n const intlayerAPI = getIntlayerAPIProxy(undefined, configuration);\n\n const targetUnmergedDictionaries =\n await getTargetUnmergedDictionaries(options);\n\n const affectedDictionaryKeys = new Set<string>();\n targetUnmergedDictionaries.forEach((dict) => {\n affectedDictionaryKeys.add(dict.key);\n });\n\n appLogger([\n 'Affected dictionary keys for processing:',\n Array.from(affectedDictionaryKeys)\n .map((key) => colorizeKey(key))\n .join(', '),\n ]);\n\n const maxKeyLength = Math.max(\n ...targetUnmergedDictionaries.map((dict) => dict.key.length)\n );\n const maxLocaleLength = Math.max(\n ...locales.map((locale) => formatLocale(locale).length)\n );\n\n for (const targetUnmergedDictionary of targetUnmergedDictionaries) {\n const dictionaryPreset = colon(\n [\n colorize(' - [', ANSIColors.GREY_DARK),\n colorizeKey(targetUnmergedDictionary.key),\n colorize(']', ANSIColors.GREY_DARK),\n ].join(''),\n { colSize: maxKeyLength + 6 }\n );\n\n const dictionaryKey = targetUnmergedDictionary.key;\n const dictionariesRecord = getDictionaries(configuration);\n\n const mainDictionaryToProcess: Dictionary =\n dictionariesRecord[dictionaryKey];\n\n const sourceLocale: Locales =\n (targetUnmergedDictionary.locale as Locales) ?? baseLocale;\n\n if (!mainDictionaryToProcess) {\n appLogger(\n `${dictionaryPreset} Dictionary not found in dictionariesRecord. Skipping.`,\n {\n level: 'warn',\n }\n );\n continue;\n }\n\n if (!targetUnmergedDictionary.filePath) {\n appLogger(`${dictionaryPreset} Dictionary has no file path. Skipping.`, {\n level: 'warn',\n });\n continue;\n }\n\n const relativePath = relative(\n configuration.content.baseDir,\n targetUnmergedDictionary.filePath\n );\n\n appLogger(\n `${dictionaryPreset} Processing content declaration: ${colorizePath(relativePath)}`,\n {\n level: 'info',\n }\n );\n\n const sourceLocaleContent = getFilterTranslationsOnlyContent(\n mainDictionaryToProcess as unknown as ContentNode,\n sourceLocale,\n { dictionaryKey, keyPath: [] }\n );\n\n if (Object.keys(sourceLocaleContent).length === 0) {\n appLogger(\n `${dictionaryPreset} No content found for dictionary in source locale ${formatLocale(sourceLocale)}. Skipping translation for this dictionary.`,\n {\n level: 'warn',\n }\n );\n continue;\n }\n\n const result: Dictionary[] = [];\n\n // Determine output locales\n let outputLocalesList: Locales[] = outputLocales;\n\n // If mode is review, translate all locales\n // If mode is complete, translate only the locales that are not the source locale\n if (mode === 'complete') {\n const missingLocales = getMissingLocalesContent(\n mainDictionaryToProcess as unknown as ContentNode,\n outputLocales,\n {\n dictionaryKey: mainDictionaryToProcess.key,\n keyPath: [],\n plugins: [],\n }\n );\n\n outputLocalesList = missingLocales;\n }\n\n if (outputLocalesList.length === 0) {\n appLogger(\n `${dictionaryPreset} No locales to fill - Skipping dictionary`,\n\n {\n level: 'warn',\n }\n );\n continue;\n }\n\n const translationResults = await parallelize(\n outputLocalesList,\n async (targetLocale) => {\n const localePreset = colon(\n [\n colorize('[', ANSIColors.GREY_DARK),\n formatLocale(targetLocale),\n colorize(']', ANSIColors.GREY_DARK),\n ].join(''),\n { colSize: maxLocaleLength }\n );\n\n appLogger(\n `${dictionaryPreset}${localePreset} Preparing translation for dictionary from ${formatLocale(sourceLocale)} to ${formatLocale(targetLocale)}`,\n {\n level: 'info',\n }\n );\n\n const presetOutputContent = getLocalisedContent(\n mainDictionaryToProcess as unknown as ContentNode,\n targetLocale,\n { dictionaryKey, keyPath: [] }\n );\n\n try {\n const translationResult = await intlayerAPI.ai.translateJSON({\n entryFileContent: sourceLocaleContent.content, // Should be JSON, ensure getLocalisedContent provides this.\n presetOutputContent: presetOutputContent.content, // Should be JSON\n dictionaryDescription: mainDictionaryToProcess.description ?? '',\n entryLocale: sourceLocale,\n outputLocale: targetLocale,\n mode,\n aiOptions: options.aiOptions,\n });\n\n if (!translationResult.data?.fileContent) {\n appLogger(`${dictionaryPreset}${localePreset} No content result`, {\n level: 'error',\n });\n return null;\n }\n\n const processedPerLocaleDictionary = processPerLocaleDictionary({\n ...mainDictionaryToProcess,\n content: translationResult.data?.fileContent,\n locale: targetLocale,\n });\n\n return processedPerLocaleDictionary;\n } catch (error) {\n appLogger(\n `${dictionaryPreset}${localePreset} ${colorize('Error filling', ANSIColors.RED)}: ` +\n error,\n {\n level: 'error',\n }\n );\n return null;\n }\n },\n options.nbConcurrentTranslations ?? NB_CONCURRENT_TRANSLATIONS\n );\n\n // Filter out null results and add to result array\n translationResults.forEach((translationResult) => {\n if (translationResult) {\n result.push(translationResult);\n }\n });\n\n const dictionaryToMerge =\n mode === 'review'\n ? [...result, mainDictionaryToProcess] // Mode review: generated content will override the base one\n : [mainDictionaryToProcess, ...result]; // Mode complete: base content will override the generated one\n\n const mergedResults = mergeDictionaries(dictionaryToMerge);\n\n let formattedDict = targetUnmergedDictionary;\n\n if (formattedDict.locale) {\n const presetOutputContent = getLocalisedContent(\n mainDictionaryToProcess as unknown as ContentNode,\n formattedDict.locale,\n { dictionaryKey, keyPath: [] }\n );\n\n formattedDict = {\n ...formattedDict,\n content: presetOutputContent.content,\n };\n }\n\n const reducedResult = reduceDictionaryContent(mergedResults, formattedDict);\n\n if (formattedDict.autoFill || configuration.content.autoFill) {\n await autoFill(\n mergedResults,\n targetUnmergedDictionary,\n formattedDict.autoFill ?? configuration.content.autoFill,\n outputLocalesList,\n [sourceLocale],\n configuration\n );\n } else {\n await writeContentDeclaration(\n { ...formattedDict, content: reducedResult.content },\n configuration,\n formattedDict.filePath\n );\n\n if (formattedDict.filePath) {\n appLogger(\n `${dictionaryPreset} Content declaration written to ${formatPath(formattedDict.filePath)}`,\n {\n level: 'info',\n }\n );\n }\n }\n }\n};\n"],"mappings":"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","names":[]}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,30 +15,23 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
var getTargetDictionary_exports = {};
|
|
30
20
|
__export(getTargetDictionary_exports, {
|
|
31
21
|
ensureArray: () => ensureArray,
|
|
32
|
-
|
|
22
|
+
getTargetUnmergedDictionaries: () => getTargetUnmergedDictionaries
|
|
33
23
|
});
|
|
34
24
|
module.exports = __toCommonJS(getTargetDictionary_exports);
|
|
35
25
|
var import_chokidar = require("@intlayer/chokidar");
|
|
36
26
|
var import_config = require("@intlayer/config");
|
|
37
|
-
var import_unmerged_dictionaries_entry =
|
|
27
|
+
var import_unmerged_dictionaries_entry = require("@intlayer/unmerged-dictionaries-entry");
|
|
38
28
|
var import_path = require("path");
|
|
39
29
|
const ensureArray = (value) => [value].flat();
|
|
40
|
-
const
|
|
30
|
+
const getTargetUnmergedDictionaries = async (options) => {
|
|
41
31
|
const configuration = (0, import_config.getConfiguration)(options.configOptions);
|
|
42
32
|
const { baseDir } = configuration.content;
|
|
43
|
-
|
|
33
|
+
const unmergedDictionariesRecord = (0, import_unmerged_dictionaries_entry.getUnmergedDictionaries)(configuration);
|
|
34
|
+
let result = Object.values(unmergedDictionariesRecord).flat();
|
|
44
35
|
if (typeof options.file !== "undefined") {
|
|
45
36
|
const fileArray = ensureArray(options.file);
|
|
46
37
|
const absoluteFilePaths = fileArray.map((file) => (0, import_path.join)(baseDir, file));
|
|
@@ -81,6 +72,6 @@ const getTargetDictionary = async (options) => {
|
|
|
81
72
|
// Annotate the CommonJS export names for ESM import in node:
|
|
82
73
|
0 && (module.exports = {
|
|
83
74
|
ensureArray,
|
|
84
|
-
|
|
75
|
+
getTargetUnmergedDictionaries
|
|
85
76
|
});
|
|
86
77
|
//# sourceMappingURL=getTargetDictionary.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/getTargetDictionary.ts"],"sourcesContent":["import { listGitFiles, ListGitFilesOptions } from '@intlayer/chokidar';\nimport { getConfiguration, GetConfigurationOptions } from '@intlayer/config';\nimport { Dictionary } from '@intlayer/core';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { join } from 'path';\n\nexport const ensureArray = <T>(value: T | T[]): T[] => [value].flat() as T[];\n\n// Arguments for the fill function\nexport type GetTargetDictionaryOptions = {\n file?: string | string[];\n keys?: string | string[];\n excludedKeys?: string | string[];\n filter?: (entry: Dictionary) => boolean; // DictionaryEntry needs to be defined\n pathFilter?: string | string[];\n gitOptions?: ListGitFilesOptions;\n configOptions?: GetConfigurationOptions;\n};\n\nexport const getTargetUnmergedDictionaries = async (\n options: GetTargetDictionaryOptions\n): Promise<Dictionary[]> => {\n const configuration = getConfiguration(options.configOptions);\n\n const { baseDir } = configuration.content;\n\n const unmergedDictionariesRecord = getUnmergedDictionaries(configuration);\n let result = Object.values(unmergedDictionariesRecord).flat();\n\n // 1. if filePath not defined, list all content declaration files based on unmerged dictionaries list\n if (typeof options.file !== 'undefined') {\n const fileArray = ensureArray(options.file);\n const absoluteFilePaths = fileArray.map((file) => join(baseDir, file));\n\n result = result.filter(\n (dict) =>\n dict.filePath &&\n (absoluteFilePaths.includes(dict.filePath) ||\n absoluteFilePaths.includes(join(baseDir, dict.filePath)))\n );\n }\n\n if (typeof options.keys !== 'undefined') {\n result = result.filter((dict) =>\n ensureArray(options.keys)?.includes(dict.key)\n );\n }\n\n if (typeof options.excludedKeys !== 'undefined') {\n result = result.filter(\n (dict) => !ensureArray(options.excludedKeys)?.includes(dict.key)\n );\n }\n\n if (typeof options.pathFilter !== 'undefined') {\n result = result.filter((dict) =>\n ensureArray(options.pathFilter)?.includes(dict.filePath ?? '')\n );\n }\n\n if (typeof options.filter !== 'undefined') {\n result = result.filter(options.filter);\n }\n\n const gitOptions = options.gitOptions;\n if (gitOptions) {\n const gitChangedFiles = await listGitFiles(gitOptions);\n\n if (gitChangedFiles) {\n // Convert dictionary file paths to be relative to git root for comparison\n\n // Filter dictionaries based on git changed files\n result = result.filter((dict) => {\n if (!dict.filePath) return false;\n\n return gitChangedFiles.some((gitFile) => dict.filePath === gitFile);\n });\n }\n }\n\n return result.filter((dict) => !dict.autoFilled);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAkD;AAClD,oBAA0D;AAE1D,yCAAwC;AACxC,kBAAqB;AAEd,MAAM,cAAc,CAAI,UAAwB,CAAC,KAAK,EAAE,KAAK;AAa7D,MAAM,gCAAgC,OAC3C,YAC0B;AAC1B,QAAM,oBAAgB,gCAAiB,QAAQ,aAAa;AAE5D,QAAM,EAAE,QAAQ,IAAI,cAAc;AAElC,QAAM,iCAA6B,4DAAwB,aAAa;AACxE,MAAI,SAAS,OAAO,OAAO,0BAA0B,EAAE,KAAK;AAG5D,MAAI,OAAO,QAAQ,SAAS,aAAa;AACvC,UAAM,YAAY,YAAY,QAAQ,IAAI;AAC1C,UAAM,oBAAoB,UAAU,IAAI,CAAC,aAAS,kBAAK,SAAS,IAAI,CAAC;AAErE,aAAS,OAAO;AAAA,MACd,CAAC,SACC,KAAK,aACJ,kBAAkB,SAAS,KAAK,QAAQ,KACvC,kBAAkB,aAAS,kBAAK,SAAS,KAAK,QAAQ,CAAC;AAAA,IAC7D;AAAA,EACF;AAEA,MAAI,OAAO,QAAQ,SAAS,aAAa;AACvC,aAAS,OAAO;AAAA,MAAO,CAAC,SACtB,YAAY,QAAQ,IAAI,GAAG,SAAS,KAAK,GAAG;AAAA,IAC9C;AAAA,EACF;AAEA,MAAI,OAAO,QAAQ,iBAAiB,aAAa;AAC/C,aAAS,OAAO;AAAA,MACd,CAAC,SAAS,CAAC,YAAY,QAAQ,YAAY,GAAG,SAAS,KAAK,GAAG;AAAA,IACjE;AAAA,EACF;AAEA,MAAI,OAAO,QAAQ,eAAe,aAAa;AAC7C,aAAS,OAAO;AAAA,MAAO,CAAC,SACtB,YAAY,QAAQ,UAAU,GAAG,SAAS,KAAK,YAAY,EAAE;AAAA,IAC/D;AAAA,EACF;AAEA,MAAI,OAAO,QAAQ,WAAW,aAAa;AACzC,aAAS,OAAO,OAAO,QAAQ,MAAM;AAAA,EACvC;AAEA,QAAM,aAAa,QAAQ;AAC3B,MAAI,YAAY;AACd,UAAM,kBAAkB,UAAM,8BAAa,UAAU;AAErD,QAAI,iBAAiB;AAInB,eAAS,OAAO,OAAO,CAAC,SAAS;AAC/B,YAAI,CAAC,KAAK,SAAU,QAAO;AAE3B,eAAO,gBAAgB,KAAK,CAAC,YAAY,KAAK,aAAa,OAAO;AAAA,MACpE,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO,OAAO,OAAO,CAAC,SAAS,CAAC,KAAK,UAAU;AACjD;","names":[]}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
var listContentDeclaration_exports = {};
|
|
30
20
|
__export(listContentDeclaration_exports, {
|
|
@@ -34,11 +24,12 @@ __export(listContentDeclaration_exports, {
|
|
|
34
24
|
module.exports = __toCommonJS(listContentDeclaration_exports);
|
|
35
25
|
var import_chokidar = require("@intlayer/chokidar");
|
|
36
26
|
var import_config = require("@intlayer/config");
|
|
37
|
-
var import_unmerged_dictionaries_entry =
|
|
27
|
+
var import_unmerged_dictionaries_entry = require("@intlayer/unmerged-dictionaries-entry");
|
|
38
28
|
var import_path = require("path");
|
|
39
29
|
const listContentDeclarationRows = (options) => {
|
|
40
30
|
const config = (0, import_config.getConfiguration)(options?.configOptions);
|
|
41
|
-
const
|
|
31
|
+
const unmergedDictionariesRecord = (0, import_unmerged_dictionaries_entry.getUnmergedDictionaries)(config);
|
|
32
|
+
const rows = Object.values(unmergedDictionariesRecord).flat().map((dictionary) => ({
|
|
42
33
|
key: dictionary.key ?? "",
|
|
43
34
|
path: (0, import_path.relative)(config.content.baseDir, dictionary.filePath ?? "Remote")
|
|
44
35
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/listContentDeclaration.ts"],"sourcesContent":["import { formatPath } from '@intlayer/chokidar';\nimport {\n colon,\n colorizeKey,\n colorizeNumber,\n getAppLogger,\n getConfiguration,\n type GetConfigurationOptions,\n} from '@intlayer/config';\nimport
|
|
1
|
+
{"version":3,"sources":["../../src/listContentDeclaration.ts"],"sourcesContent":["import { formatPath } from '@intlayer/chokidar';\nimport {\n colon,\n colorizeKey,\n colorizeNumber,\n getAppLogger,\n getConfiguration,\n type GetConfigurationOptions,\n} from '@intlayer/config';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { relative } from 'path';\n\ntype ListContentDeclarationOptions = {\n configOptions?: GetConfigurationOptions;\n};\n\nexport const listContentDeclarationRows = (\n options?: ListContentDeclarationOptions\n) => {\n const config = getConfiguration(options?.configOptions);\n\n const unmergedDictionariesRecord = getUnmergedDictionaries(config);\n\n const rows = Object.values(unmergedDictionariesRecord)\n .flat()\n .map((dictionary) => ({\n key: dictionary.key ?? '',\n path: relative(config.content.baseDir, dictionary.filePath ?? 'Remote'),\n }));\n return rows;\n};\n\nexport const listContentDeclaration = (\n options?: ListContentDeclarationOptions\n) => {\n const config = getConfiguration(options?.configOptions);\n const appLogger = getAppLogger(config, {\n config: {\n prefix: '',\n },\n });\n\n const rows = listContentDeclarationRows(options);\n\n const lines = rows.map((r) =>\n [\n colon(` - ${colorizeKey(r.key)}`, {\n colSize: rows.map((r) => r.key.length),\n maxSize: 60,\n }),\n ' - ',\n formatPath(r.path),\n ].join('')\n );\n\n appLogger(`Content declaration files:`);\n\n lines.forEach((l) => {\n appLogger(l, {\n level: 'info',\n });\n });\n\n appLogger(`Total content declaration files: ${colorizeNumber(rows.length)}`);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAA2B;AAC3B,oBAOO;AACP,yCAAwC;AACxC,kBAAyB;AAMlB,MAAM,6BAA6B,CACxC,YACG;AACH,QAAM,aAAS,gCAAiB,SAAS,aAAa;AAEtD,QAAM,iCAA6B,4DAAwB,MAAM;AAEjE,QAAM,OAAO,OAAO,OAAO,0BAA0B,EAClD,KAAK,EACL,IAAI,CAAC,gBAAgB;AAAA,IACpB,KAAK,WAAW,OAAO;AAAA,IACvB,UAAM,sBAAS,OAAO,QAAQ,SAAS,WAAW,YAAY,QAAQ;AAAA,EACxE,EAAE;AACJ,SAAO;AACT;AAEO,MAAM,yBAAyB,CACpC,YACG;AACH,QAAM,aAAS,gCAAiB,SAAS,aAAa;AACtD,QAAM,gBAAY,4BAAa,QAAQ;AAAA,IACrC,QAAQ;AAAA,MACN,QAAQ;AAAA,IACV;AAAA,EACF,CAAC;AAED,QAAM,OAAO,2BAA2B,OAAO;AAE/C,QAAM,QAAQ,KAAK;AAAA,IAAI,CAAC,MACtB;AAAA,UACE,qBAAM,UAAM,2BAAY,EAAE,GAAG,CAAC,IAAI;AAAA,QAChC,SAAS,KAAK,IAAI,CAACA,OAAMA,GAAE,IAAI,MAAM;AAAA,QACrC,SAAS;AAAA,MACX,CAAC;AAAA,MACD;AAAA,UACA,4BAAW,EAAE,IAAI;AAAA,IACnB,EAAE,KAAK,EAAE;AAAA,EACX;AAEA,YAAU,4BAA4B;AAEtC,QAAM,QAAQ,CAAC,MAAM;AACnB,cAAU,GAAG;AAAA,MACX,OAAO;AAAA,IACT,CAAC;AAAA,EACH,CAAC;AAED,YAAU,wCAAoC,8BAAe,KAAK,MAAM,CAAC,EAAE;AAC7E;","names":["r"]}
|
package/dist/cjs/liveSync.cjs
CHANGED
|
@@ -149,7 +149,7 @@ const liveSync = async (options) => {
|
|
|
149
149
|
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
150
150
|
"Access-Control-Allow-Headers": "Content-Type, Authorization"
|
|
151
151
|
});
|
|
152
|
-
const dictionaries = (0, import_dictionaries_entry.getDictionaries)();
|
|
152
|
+
const dictionaries = (0, import_dictionaries_entry.getDictionaries)(configuration);
|
|
153
153
|
const prefix = "/dictionaries/";
|
|
154
154
|
if (req.url.startsWith(prefix)) {
|
|
155
155
|
const [key, locale] = decodeURIComponent(req.url).slice(prefix.length).split("/");
|
|
@@ -176,7 +176,7 @@ const liveSync = async (options) => {
|
|
|
176
176
|
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
177
177
|
"Access-Control-Allow-Headers": "Content-Type, Authorization"
|
|
178
178
|
});
|
|
179
|
-
const unmergedDictionaries = (0, import_unmerged_dictionaries_entry.getUnmergedDictionaries)();
|
|
179
|
+
const unmergedDictionaries = (0, import_unmerged_dictionaries_entry.getUnmergedDictionaries)(configuration);
|
|
180
180
|
const prefix = "/unmerged_dictionaries/";
|
|
181
181
|
if (req.url.startsWith(prefix)) {
|
|
182
182
|
const key = decodeURIComponent(req.url.slice(prefix.length));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/liveSync.ts"],"sourcesContent":["import { IntlayerEventListener } from './IntlayerEventListener';\n// @ts-ignore: @intlayer/backend is not built yet\nimport type { DictionaryAPI } from '@intlayer/backend';\nimport { buildDictionary } from '@intlayer/chokidar';\nimport type { IntlayerConfig } from '@intlayer/config';\nimport { getAppLogger, getConfiguration } from '@intlayer/config';\nimport packageJson from '@intlayer/config/package.json';\nimport { getLocalisedContent } from '@intlayer/core';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { ChildProcess, spawn } from 'child_process';\nimport { createServer } from 'http';\n\ntype LiveSyncOptions = {\n process?: string;\n};\n\nconst writeDictionary = async (\n dictionary: DictionaryAPI,\n configuration: IntlayerConfig\n) => {\n const appLogger = getAppLogger(configuration);\n appLogger(`Writing dictionary ${dictionary.key}`);\n await buildDictionary([dictionary], configuration);\n};\n\nexport const liveSync = async (options?: LiveSyncOptions) => {\n const configuration = getConfiguration();\n const appLogger = getAppLogger(configuration, {\n config: {\n prefix: '',\n },\n });\n\n const { liveSyncPort, liveSyncURL } = configuration.editor;\n\n let childProcess: ChildProcess | null = null;\n let eventListener: IntlayerEventListener | null = null;\n let isHotReloadConnected = false;\n let connectionStatus = 'disconnected'; // 'connected', 'connecting', 'reconnecting', 'disconnected', 'error'\n\n // Start the parallel process if provided\n if (options?.process) {\n const [command, ...args] = options.process.split(' ');\n\n childProcess = spawn(command, args, {\n stdio: 'inherit',\n shell: true,\n });\n\n childProcess.on('error', (error) => {\n appLogger(`Failed to start process '${options.process}':`, {\n level: 'error',\n });\n });\n\n childProcess.on('exit', (code) => {\n if (code !== 0) {\n appLogger(`Process \"${options.process}\" exited with code ${code}`);\n } else {\n appLogger(`Process \"${options.process}\" exited successfully`);\n }\n });\n }\n\n // Initialize the event listener for hot reload if configured\n if (\n configuration.editor.liveSync &&\n configuration.editor.backendURL &&\n configuration.editor.clientId &&\n configuration.editor.clientSecret\n ) {\n eventListener = new IntlayerEventListener(configuration);\n connectionStatus = 'connecting';\n\n // Set up connection callbacks\n eventListener.onConnectionOpen = () => {\n connectionStatus = 'connected';\n isHotReloadConnected = true;\n appLogger('Live sync connection established');\n };\n\n eventListener.onConnectionError = (error) => {\n connectionStatus = 'error';\n isHotReloadConnected = false;\n const errorEvent = error as any;\n appLogger(\n `Live sync connection error: ${errorEvent.message ?? 'Unknown error'}`,\n {\n level: 'warn',\n }\n );\n\n // If this is a \"terminated: other side closed\" error, it's likely a server restart\n if (\n errorEvent.message?.includes('terminated') ||\n errorEvent.message?.includes('closed')\n ) {\n appLogger(\n 'Server connection was terminated, automatic reconnection will be attempted...',\n {\n level: 'info',\n }\n );\n connectionStatus = 'reconnecting';\n }\n };\n\n // Set up dictionary change callbacks\n eventListener.onDictionaryAdded = (dictionary) =>\n writeDictionary(dictionary, configuration);\n eventListener.onDictionaryChange = (dictionary) =>\n writeDictionary(dictionary, configuration);\n eventListener.onDictionaryDeleted = (dictionary) =>\n writeDictionary(dictionary, configuration);\n\n try {\n await eventListener.initialize();\n } catch (error) {\n connectionStatus = 'error';\n isHotReloadConnected = false;\n appLogger('Failed to initialize IntlayerEventListener:', {\n level: 'error',\n });\n appLogger(\n `Error: ${error instanceof Error ? error.message : String(error)}`,\n {\n level: 'error',\n }\n );\n }\n } else if (!configuration.editor.liveSync) {\n appLogger(\n 'Hot reload is disabled. Please enable it in the configuration (editor.liveSync).'\n );\n } else if (\n !configuration.editor.clientId ||\n !configuration.editor.clientSecret\n ) {\n appLogger(\n 'Missing client credentials for hot reload. Please configure clientId and clientSecret'\n );\n }\n\n const server = createServer(async (req, res) => {\n // Handle CORS preflight requests\n if (req.method === 'OPTIONS') {\n res.writeHead(200, {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n\n res.end();\n return;\n }\n\n if (req.url?.startsWith('/dictionaries')) {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n const dictionaries = getDictionaries();\n\n const prefix = '/dictionaries/';\n if (req.url.startsWith(prefix)) {\n const [key, locale] = decodeURIComponent(req.url)\n .slice(prefix.length)\n .split('/');\n\n const dictionary = dictionaries[key] ?? null;\n\n if (locale) {\n const sourceLocaleContent = getLocalisedContent(dictionary, locale, {\n dictionaryKey: key,\n keyPath: [],\n });\n\n res.end(JSON.stringify(sourceLocaleContent));\n return;\n }\n\n res.end(JSON.stringify(dictionary));\n return;\n }\n\n res.end(JSON.stringify(dictionaries));\n return;\n }\n\n if (req.url?.startsWith('/unmerged_dictionaries')) {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n const unmergedDictionaries = getUnmergedDictionaries();\n\n const prefix = '/unmerged_dictionaries/';\n if (req.url.startsWith(prefix)) {\n const key = decodeURIComponent(req.url.slice(prefix.length));\n const one = unmergedDictionaries[key] ?? null;\n\n res.end(JSON.stringify(one));\n return;\n }\n\n res.end(JSON.stringify(unmergedDictionaries));\n return;\n }\n\n if (req.url === '/configuration') {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n res.end(JSON.stringify(configuration));\n return;\n }\n\n if (req.url === '/health') {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n });\n res.end(JSON.stringify({ status: 'ok' }));\n return;\n }\n\n res.end('Not found');\n return;\n });\n\n const getLiveSyncParam = () => {\n if (!configuration.editor.liveSync) return '\\x1b[31m✗ Disabled\\x1b[0m';\n\n return '\\x1b[32m✓ Enabled\\x1b[0m';\n };\n server.listen(liveSyncPort, () => {\n console.log(`\n \\x1b[1;90mINTLAYER v${packageJson.version}\\x1b[0m\n \n Live server running at: \\x1b[90m${liveSyncURL}\\x1b[0m\n - Backend URL: \\x1b[90m${configuration.editor.backendURL ?? '-'}\\x1b[0m\n - Live sync: ${getLiveSyncParam()}\n - Parallel process: ${options?.process === '' ? '-' : `\\x1b[90m${options?.process}\\x1b[0m`}\n - Access key: ${configuration.editor.clientId ?? '-'}\n `);\n });\n\n // Cleanup function to terminate child process and event listener when the main process exits\n const cleanup = () => {\n // Clean up event listener\n if (eventListener) {\n appLogger('Closing SSE connection...');\n eventListener.cleanup();\n }\n\n // Clean up child process\n if (childProcess && !childProcess.killed) {\n appLogger('Terminating parallel process...');\n childProcess.kill('SIGTERM');\n\n // Force kill after 5 seconds if process doesn't terminate gracefully\n setTimeout(() => {\n if (childProcess && !childProcess.killed) {\n appLogger('Force killing parallel process...');\n childProcess.kill('SIGKILL');\n }\n }, 5000);\n }\n\n server.close(() => {\n appLogger('Live sync server stopped');\n process.exit(0);\n });\n };\n\n // Handle process termination signals\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n process.on('exit', cleanup);\n};\n"],"mappings":"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","names":["packageJson"]}
|
|
1
|
+
{"version":3,"sources":["../../src/liveSync.ts"],"sourcesContent":["import { IntlayerEventListener } from './IntlayerEventListener';\n// @ts-ignore: @intlayer/backend is not built yet\nimport type { DictionaryAPI } from '@intlayer/backend';\nimport { buildDictionary } from '@intlayer/chokidar';\nimport type { IntlayerConfig } from '@intlayer/config';\nimport { getAppLogger, getConfiguration } from '@intlayer/config';\nimport packageJson from '@intlayer/config/package.json';\nimport { getLocalisedContent } from '@intlayer/core';\nimport { getDictionaries } from '@intlayer/dictionaries-entry';\nimport { getUnmergedDictionaries } from '@intlayer/unmerged-dictionaries-entry';\nimport { ChildProcess, spawn } from 'child_process';\nimport { createServer } from 'http';\n\ntype LiveSyncOptions = {\n process?: string;\n};\n\nconst writeDictionary = async (\n dictionary: DictionaryAPI,\n configuration: IntlayerConfig\n) => {\n const appLogger = getAppLogger(configuration);\n appLogger(`Writing dictionary ${dictionary.key}`);\n await buildDictionary([dictionary], configuration);\n};\n\nexport const liveSync = async (options?: LiveSyncOptions) => {\n const configuration = getConfiguration();\n const appLogger = getAppLogger(configuration, {\n config: {\n prefix: '',\n },\n });\n\n const { liveSyncPort, liveSyncURL } = configuration.editor;\n\n let childProcess: ChildProcess | null = null;\n let eventListener: IntlayerEventListener | null = null;\n let isHotReloadConnected = false;\n let connectionStatus = 'disconnected'; // 'connected', 'connecting', 'reconnecting', 'disconnected', 'error'\n\n // Start the parallel process if provided\n if (options?.process) {\n const [command, ...args] = options.process.split(' ');\n\n childProcess = spawn(command, args, {\n stdio: 'inherit',\n shell: true,\n });\n\n childProcess.on('error', (error) => {\n appLogger(`Failed to start process '${options.process}':`, {\n level: 'error',\n });\n });\n\n childProcess.on('exit', (code) => {\n if (code !== 0) {\n appLogger(`Process \"${options.process}\" exited with code ${code}`);\n } else {\n appLogger(`Process \"${options.process}\" exited successfully`);\n }\n });\n }\n\n // Initialize the event listener for hot reload if configured\n if (\n configuration.editor.liveSync &&\n configuration.editor.backendURL &&\n configuration.editor.clientId &&\n configuration.editor.clientSecret\n ) {\n eventListener = new IntlayerEventListener(configuration);\n connectionStatus = 'connecting';\n\n // Set up connection callbacks\n eventListener.onConnectionOpen = () => {\n connectionStatus = 'connected';\n isHotReloadConnected = true;\n appLogger('Live sync connection established');\n };\n\n eventListener.onConnectionError = (error) => {\n connectionStatus = 'error';\n isHotReloadConnected = false;\n const errorEvent = error as any;\n appLogger(\n `Live sync connection error: ${errorEvent.message ?? 'Unknown error'}`,\n {\n level: 'warn',\n }\n );\n\n // If this is a \"terminated: other side closed\" error, it's likely a server restart\n if (\n errorEvent.message?.includes('terminated') ||\n errorEvent.message?.includes('closed')\n ) {\n appLogger(\n 'Server connection was terminated, automatic reconnection will be attempted...',\n {\n level: 'info',\n }\n );\n connectionStatus = 'reconnecting';\n }\n };\n\n // Set up dictionary change callbacks\n eventListener.onDictionaryAdded = (dictionary) =>\n writeDictionary(dictionary, configuration);\n eventListener.onDictionaryChange = (dictionary) =>\n writeDictionary(dictionary, configuration);\n eventListener.onDictionaryDeleted = (dictionary) =>\n writeDictionary(dictionary, configuration);\n\n try {\n await eventListener.initialize();\n } catch (error) {\n connectionStatus = 'error';\n isHotReloadConnected = false;\n appLogger('Failed to initialize IntlayerEventListener:', {\n level: 'error',\n });\n appLogger(\n `Error: ${error instanceof Error ? error.message : String(error)}`,\n {\n level: 'error',\n }\n );\n }\n } else if (!configuration.editor.liveSync) {\n appLogger(\n 'Hot reload is disabled. Please enable it in the configuration (editor.liveSync).'\n );\n } else if (\n !configuration.editor.clientId ||\n !configuration.editor.clientSecret\n ) {\n appLogger(\n 'Missing client credentials for hot reload. Please configure clientId and clientSecret'\n );\n }\n\n const server = createServer(async (req, res) => {\n // Handle CORS preflight requests\n if (req.method === 'OPTIONS') {\n res.writeHead(200, {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n\n res.end();\n return;\n }\n\n if (req.url?.startsWith('/dictionaries')) {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n const dictionaries = getDictionaries(configuration);\n\n const prefix = '/dictionaries/';\n if (req.url.startsWith(prefix)) {\n const [key, locale] = decodeURIComponent(req.url)\n .slice(prefix.length)\n .split('/');\n\n const dictionary = dictionaries[key] ?? null;\n\n if (locale) {\n const sourceLocaleContent = getLocalisedContent(dictionary, locale, {\n dictionaryKey: key,\n keyPath: [],\n });\n\n res.end(JSON.stringify(sourceLocaleContent));\n return;\n }\n\n res.end(JSON.stringify(dictionary));\n return;\n }\n\n res.end(JSON.stringify(dictionaries));\n return;\n }\n\n if (req.url?.startsWith('/unmerged_dictionaries')) {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n const unmergedDictionaries = getUnmergedDictionaries(configuration);\n\n const prefix = '/unmerged_dictionaries/';\n if (req.url.startsWith(prefix)) {\n const key = decodeURIComponent(req.url.slice(prefix.length));\n const one = unmergedDictionaries[key] ?? null;\n\n res.end(JSON.stringify(one));\n return;\n }\n\n res.end(JSON.stringify(unmergedDictionaries));\n return;\n }\n\n if (req.url === '/configuration') {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n 'Cache-Control': 'no-store',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n });\n res.end(JSON.stringify(configuration));\n return;\n }\n\n if (req.url === '/health') {\n res.writeHead(200, {\n 'Content-Type': 'application/json; charset=utf-8',\n });\n res.end(JSON.stringify({ status: 'ok' }));\n return;\n }\n\n res.end('Not found');\n return;\n });\n\n const getLiveSyncParam = () => {\n if (!configuration.editor.liveSync) return '\\x1b[31m✗ Disabled\\x1b[0m';\n\n return '\\x1b[32m✓ Enabled\\x1b[0m';\n };\n server.listen(liveSyncPort, () => {\n console.log(`\n \\x1b[1;90mINTLAYER v${packageJson.version}\\x1b[0m\n \n Live server running at: \\x1b[90m${liveSyncURL}\\x1b[0m\n - Backend URL: \\x1b[90m${configuration.editor.backendURL ?? '-'}\\x1b[0m\n - Live sync: ${getLiveSyncParam()}\n - Parallel process: ${options?.process === '' ? '-' : `\\x1b[90m${options?.process}\\x1b[0m`}\n - Access key: ${configuration.editor.clientId ?? '-'}\n `);\n });\n\n // Cleanup function to terminate child process and event listener when the main process exits\n const cleanup = () => {\n // Clean up event listener\n if (eventListener) {\n appLogger('Closing SSE connection...');\n eventListener.cleanup();\n }\n\n // Clean up child process\n if (childProcess && !childProcess.killed) {\n appLogger('Terminating parallel process...');\n childProcess.kill('SIGTERM');\n\n // Force kill after 5 seconds if process doesn't terminate gracefully\n setTimeout(() => {\n if (childProcess && !childProcess.killed) {\n appLogger('Force killing parallel process...');\n childProcess.kill('SIGKILL');\n }\n }, 5000);\n }\n\n server.close(() => {\n appLogger('Live sync server stopped');\n process.exit(0);\n });\n };\n\n // Handle process termination signals\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n process.on('exit', cleanup);\n};\n"],"mappings":"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","names":["packageJson"]}
|
package/dist/cjs/pull.cjs
CHANGED
|
@@ -27,6 +27,7 @@ var import_config = require("@intlayer/config");
|
|
|
27
27
|
var import_fs = require("fs");
|
|
28
28
|
var import_path = require("path");
|
|
29
29
|
var import_pullLog = require('./pullLog.cjs');
|
|
30
|
+
var import_checkAccess = require('./utils/checkAccess.cjs');
|
|
30
31
|
const pull = async (options) => {
|
|
31
32
|
const appLogger = (0, import_config.getAppLogger)(options?.configOptions?.override, {
|
|
32
33
|
config: {
|
|
@@ -35,12 +36,8 @@ const pull = async (options) => {
|
|
|
35
36
|
});
|
|
36
37
|
try {
|
|
37
38
|
const config = (0, import_config.getConfiguration)(options?.configOptions);
|
|
38
|
-
const
|
|
39
|
-
if (!
|
|
40
|
-
throw new Error(
|
|
41
|
-
"Missing OAuth2 client ID or client secret. To get access token go to https://intlayer.org/dashboard/project."
|
|
42
|
-
);
|
|
43
|
-
}
|
|
39
|
+
const hasCMSAuth = await (0, import_checkAccess.checkCMSAuth)(config);
|
|
40
|
+
if (!hasCMSAuth) return;
|
|
44
41
|
const intlayerAPI = (0, import_api.getIntlayerAPIProxy)(void 0, config);
|
|
45
42
|
const getDictionariesUpdateTimestampResult = await intlayerAPI.dictionary.getDictionariesUpdateTimestamp();
|
|
46
43
|
if (!getDictionariesUpdateTimestampResult.data) {
|