@intlayer/cli 5.8.1 → 6.0.0-canary.0
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 +240 -0
- package/dist/cjs/IntlayerEventListener.cjs.map +1 -0
- package/dist/cjs/cli.cjs +29 -7
- package/dist/cjs/cli.cjs.map +1 -1
- package/dist/cjs/config.cjs +5 -1
- package/dist/cjs/config.cjs.map +1 -1
- package/dist/cjs/fill/autoFill.cjs +105 -0
- package/dist/cjs/fill/autoFill.cjs.map +1 -0
- package/dist/cjs/fill/formatAutoFillData.cjs +108 -0
- package/dist/cjs/fill/formatAutoFillData.cjs.map +1 -0
- package/dist/cjs/fill/formatAutoFilledFilePath.cjs +46 -0
- package/dist/cjs/fill/formatAutoFilledFilePath.cjs.map +1 -0
- package/dist/cjs/fill/getTargetDictionary.cjs +86 -0
- package/dist/cjs/fill/getTargetDictionary.cjs.map +1 -0
- package/dist/cjs/fill/index.cjs +257 -0
- package/dist/cjs/fill/index.cjs.map +1 -0
- package/dist/cjs/index.cjs +4 -2
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/listContentDeclaration.cjs +37 -19
- package/dist/cjs/listContentDeclaration.cjs.map +1 -1
- package/dist/cjs/liveSync.cjs +254 -0
- package/dist/cjs/liveSync.cjs.map +1 -0
- package/dist/cjs/pull.cjs +18 -22
- package/dist/cjs/pull.cjs.map +1 -1
- package/dist/cjs/push.cjs +28 -27
- package/dist/cjs/push.cjs.map +1 -1
- package/dist/cjs/pushConfig.cjs +8 -15
- package/dist/cjs/pushConfig.cjs.map +1 -1
- package/dist/cjs/reviewDoc.cjs +43 -26
- package/dist/cjs/reviewDoc.cjs.map +1 -1
- package/dist/cjs/test/index.cjs +91 -0
- package/dist/cjs/test/index.cjs.map +1 -0
- package/dist/cjs/test/listMissingTranslations.cjs +73 -0
- package/dist/cjs/test/listMissingTranslations.cjs.map +1 -0
- package/dist/cjs/translateDoc.cjs +40 -24
- package/dist/cjs/translateDoc.cjs.map +1 -1
- package/dist/cjs/utils/checkAIAccess.cjs +5 -1
- package/dist/cjs/utils/checkAIAccess.cjs.map +1 -1
- package/dist/esm/IntlayerEventListener.mjs +206 -0
- package/dist/esm/IntlayerEventListener.mjs.map +1 -0
- package/dist/esm/cli.mjs +26 -4
- package/dist/esm/cli.mjs.map +1 -1
- package/dist/esm/config.mjs +5 -1
- package/dist/esm/config.mjs.map +1 -1
- package/dist/esm/fill/autoFill.mjs +92 -0
- package/dist/esm/fill/autoFill.mjs.map +1 -0
- package/dist/esm/fill/formatAutoFillData.mjs +84 -0
- package/dist/esm/fill/formatAutoFillData.mjs.map +1 -0
- package/dist/esm/fill/formatAutoFilledFilePath.mjs +22 -0
- package/dist/esm/fill/formatAutoFilledFilePath.mjs.map +1 -0
- package/dist/esm/fill/getTargetDictionary.mjs +51 -0
- package/dist/esm/fill/getTargetDictionary.mjs.map +1 -0
- package/dist/esm/fill/index.mjs +240 -0
- package/dist/esm/fill/index.mjs.map +1 -0
- package/dist/esm/index.mjs +2 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/listContentDeclaration.mjs +38 -17
- package/dist/esm/listContentDeclaration.mjs.map +1 -1
- package/dist/esm/liveSync.mjs +220 -0
- package/dist/esm/liveSync.mjs.map +1 -0
- package/dist/esm/pull.mjs +19 -21
- package/dist/esm/pull.mjs.map +1 -1
- package/dist/esm/push.mjs +33 -27
- package/dist/esm/push.mjs.map +1 -1
- package/dist/esm/pushConfig.mjs +8 -15
- package/dist/esm/pushConfig.mjs.map +1 -1
- package/dist/esm/reviewDoc.mjs +53 -28
- package/dist/esm/reviewDoc.mjs.map +1 -1
- package/dist/esm/test/index.mjs +74 -0
- package/dist/esm/test/index.mjs.map +1 -0
- package/dist/esm/test/listMissingTranslations.mjs +41 -0
- package/dist/esm/test/listMissingTranslations.mjs.map +1 -0
- package/dist/esm/translateDoc.mjs +50 -27
- package/dist/esm/translateDoc.mjs.map +1 -1
- package/dist/esm/utils/checkAIAccess.mjs +5 -1
- package/dist/esm/utils/checkAIAccess.mjs.map +1 -1
- package/dist/types/IntlayerEventListener.d.ts +85 -0
- package/dist/types/IntlayerEventListener.d.ts.map +1 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/fill/autoFill.d.ts +4 -0
- package/dist/types/fill/autoFill.d.ts.map +1 -0
- package/dist/types/fill/formatAutoFillData.d.ts +9 -0
- package/dist/types/fill/formatAutoFillData.d.ts.map +1 -0
- package/dist/types/fill/formatAutoFilledFilePath.d.ts +3 -0
- package/dist/types/fill/formatAutoFilledFilePath.d.ts.map +1 -0
- package/dist/types/fill/getTargetDictionary.d.ts +4 -0
- package/dist/types/fill/getTargetDictionary.d.ts.map +1 -0
- package/dist/types/{fill.d.ts → fill/index.d.ts} +2 -5
- package/dist/types/fill/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/listContentDeclaration.d.ts +4 -5
- package/dist/types/listContentDeclaration.d.ts.map +1 -1
- package/dist/types/liveSync.d.ts +6 -0
- package/dist/types/liveSync.d.ts.map +1 -0
- package/dist/types/pull.d.ts.map +1 -1
- package/dist/types/push.d.ts +1 -1
- package/dist/types/push.d.ts.map +1 -1
- package/dist/types/pushConfig.d.ts +0 -1
- package/dist/types/pushConfig.d.ts.map +1 -1
- package/dist/types/reviewDoc.d.ts.map +1 -1
- package/dist/types/test/index.d.ts +8 -0
- package/dist/types/test/index.d.ts.map +1 -0
- package/dist/types/test/listMissingTranslations.d.ts +12 -0
- package/dist/types/test/listMissingTranslations.d.ts.map +1 -0
- package/dist/types/translateDoc.d.ts.map +1 -1
- package/dist/types/utils/checkAIAccess.d.ts.map +1 -1
- package/package.json +17 -15
- package/dist/cjs/fill.cjs +0 -405
- package/dist/cjs/fill.cjs.map +0 -1
- package/dist/esm/fill.mjs +0 -385
- package/dist/esm/fill.mjs.map +0 -1
- package/dist/types/fill.d.ts.map +0 -1
|
@@ -28,33 +28,51 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
29
|
var listContentDeclaration_exports = {};
|
|
30
30
|
__export(listContentDeclaration_exports, {
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
listContentDeclaration: () => listContentDeclaration,
|
|
32
|
+
listContentDeclarationRows: () => listContentDeclarationRows
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(listContentDeclaration_exports);
|
|
35
|
+
var import_chokidar = require("@intlayer/chokidar");
|
|
35
36
|
var import_config = require("@intlayer/config");
|
|
36
|
-
var
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
);
|
|
47
|
-
return contentDeclarationFilesPath;
|
|
37
|
+
var import_unmerged_dictionaries_entry = __toESM(require("@intlayer/unmerged-dictionaries-entry"));
|
|
38
|
+
var import_path = require("path");
|
|
39
|
+
const listContentDeclarationRows = (options) => {
|
|
40
|
+
const config = (0, import_config.getConfiguration)(options?.configOptions);
|
|
41
|
+
const rows = Object.values(import_unmerged_dictionaries_entry.default).flat().map((dictionary) => ({
|
|
42
|
+
key: dictionary.key ?? "",
|
|
43
|
+
path: (0, import_path.relative)(config.content.baseDir, dictionary.filePath ?? "Remote")
|
|
44
|
+
}));
|
|
45
|
+
return rows;
|
|
48
46
|
};
|
|
49
47
|
const listContentDeclaration = (options) => {
|
|
50
|
-
const contentDeclarationFilesPath = getContentDeclaration(options);
|
|
51
48
|
const config = (0, import_config.getConfiguration)(options?.configOptions);
|
|
52
|
-
const appLogger = (0, import_config.getAppLogger)(config
|
|
53
|
-
|
|
49
|
+
const appLogger = (0, import_config.getAppLogger)(config, {
|
|
50
|
+
config: {
|
|
51
|
+
prefix: ""
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
const rows = listContentDeclarationRows(options);
|
|
55
|
+
const lines = rows.map(
|
|
56
|
+
(r) => [
|
|
57
|
+
(0, import_config.colon)(` - ${(0, import_config.colorizeKey)(r.key)}`, {
|
|
58
|
+
colSize: rows.map((r2) => r2.key.length),
|
|
59
|
+
maxSize: 60
|
|
60
|
+
}),
|
|
61
|
+
" - ",
|
|
62
|
+
(0, import_chokidar.formatPath)(r.path)
|
|
63
|
+
].join("")
|
|
64
|
+
);
|
|
65
|
+
appLogger(`Content declaration files:`);
|
|
66
|
+
lines.forEach((l) => {
|
|
67
|
+
appLogger(l, {
|
|
68
|
+
level: "info"
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
appLogger(`Total content declaration files: ${(0, import_config.colorizeNumber)(rows.length)}`);
|
|
54
72
|
};
|
|
55
73
|
// Annotate the CommonJS export names for ESM import in node:
|
|
56
74
|
0 && (module.exports = {
|
|
57
|
-
|
|
58
|
-
|
|
75
|
+
listContentDeclaration,
|
|
76
|
+
listContentDeclarationRows
|
|
59
77
|
});
|
|
60
78
|
//# sourceMappingURL=listContentDeclaration.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/listContentDeclaration.ts"],"sourcesContent":["import {\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 unmergedDictionariesRecord 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 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,yCAAuC;AACvC,kBAAyB;AAMlB,MAAM,6BAA6B,CACxC,YACG;AACH,QAAM,aAAS,gCAAiB,SAAS,aAAa;AAEtD,QAAM,OAAO,OAAO,OAAO,mCAAAA,OAA0B,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,CAACC,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":["unmergedDictionariesRecord","r"]}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
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
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var liveSync_exports = {};
|
|
30
|
+
__export(liveSync_exports, {
|
|
31
|
+
liveSync: () => liveSync
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(liveSync_exports);
|
|
34
|
+
var import_IntlayerEventListener = require('./IntlayerEventListener.cjs');
|
|
35
|
+
var import_chokidar = require("@intlayer/chokidar");
|
|
36
|
+
var import_config = require("@intlayer/config");
|
|
37
|
+
var import_package = __toESM(require("@intlayer/config/package.json"));
|
|
38
|
+
var import_core = require("@intlayer/core");
|
|
39
|
+
var import_dictionaries_entry = require("@intlayer/dictionaries-entry");
|
|
40
|
+
var import_unmerged_dictionaries_entry = require("@intlayer/unmerged-dictionaries-entry");
|
|
41
|
+
var import_child_process = require("child_process");
|
|
42
|
+
var import_http = require("http");
|
|
43
|
+
const writeDictionary = async (dictionary, configuration) => {
|
|
44
|
+
const appLogger = (0, import_config.getAppLogger)(configuration);
|
|
45
|
+
appLogger(`Writing dictionary ${dictionary.key}`);
|
|
46
|
+
await (0, import_chokidar.buildDictionary)([dictionary], configuration);
|
|
47
|
+
};
|
|
48
|
+
const liveSync = async (options) => {
|
|
49
|
+
const configuration = (0, import_config.getConfiguration)();
|
|
50
|
+
const appLogger = (0, import_config.getAppLogger)(configuration, {
|
|
51
|
+
config: {
|
|
52
|
+
prefix: ""
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const { liveSyncPort, liveSyncURL } = configuration.editor;
|
|
56
|
+
let childProcess = null;
|
|
57
|
+
let eventListener = null;
|
|
58
|
+
let isHotReloadConnected = false;
|
|
59
|
+
let connectionStatus = "disconnected";
|
|
60
|
+
if (options?.process) {
|
|
61
|
+
const [command, ...args] = options.process.split(" ");
|
|
62
|
+
childProcess = (0, import_child_process.spawn)(command, args, {
|
|
63
|
+
stdio: "inherit",
|
|
64
|
+
shell: true
|
|
65
|
+
});
|
|
66
|
+
childProcess.on("error", (error) => {
|
|
67
|
+
appLogger(`Failed to start process '${options.process}':`, {
|
|
68
|
+
level: "error"
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
childProcess.on("exit", (code) => {
|
|
72
|
+
if (code !== 0) {
|
|
73
|
+
appLogger(`Process "${options.process}" exited with code ${code}`);
|
|
74
|
+
} else {
|
|
75
|
+
appLogger(`Process "${options.process}" exited successfully`);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (configuration.editor.liveSync && configuration.editor.backendURL && configuration.editor.clientId && configuration.editor.clientSecret) {
|
|
80
|
+
eventListener = new import_IntlayerEventListener.IntlayerEventListener(configuration);
|
|
81
|
+
connectionStatus = "connecting";
|
|
82
|
+
eventListener.onConnectionOpen = () => {
|
|
83
|
+
connectionStatus = "connected";
|
|
84
|
+
isHotReloadConnected = true;
|
|
85
|
+
appLogger("Live sync connection established");
|
|
86
|
+
};
|
|
87
|
+
eventListener.onConnectionError = (error) => {
|
|
88
|
+
connectionStatus = "error";
|
|
89
|
+
isHotReloadConnected = false;
|
|
90
|
+
const errorEvent = error;
|
|
91
|
+
appLogger(
|
|
92
|
+
`Live sync connection error: ${errorEvent.message ?? "Unknown error"}`,
|
|
93
|
+
{
|
|
94
|
+
level: "warn"
|
|
95
|
+
}
|
|
96
|
+
);
|
|
97
|
+
if (errorEvent.message?.includes("terminated") || errorEvent.message?.includes("closed")) {
|
|
98
|
+
appLogger(
|
|
99
|
+
"Server connection was terminated, automatic reconnection will be attempted...",
|
|
100
|
+
{
|
|
101
|
+
level: "info"
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
connectionStatus = "reconnecting";
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
eventListener.onDictionaryAdded = (dictionary) => writeDictionary(dictionary, configuration);
|
|
108
|
+
eventListener.onDictionaryChange = (dictionary) => writeDictionary(dictionary, configuration);
|
|
109
|
+
eventListener.onDictionaryDeleted = (dictionary) => writeDictionary(dictionary, configuration);
|
|
110
|
+
try {
|
|
111
|
+
await eventListener.initialize();
|
|
112
|
+
} catch (error) {
|
|
113
|
+
connectionStatus = "error";
|
|
114
|
+
isHotReloadConnected = false;
|
|
115
|
+
appLogger("Failed to initialize IntlayerEventListener:", {
|
|
116
|
+
level: "error"
|
|
117
|
+
});
|
|
118
|
+
appLogger(
|
|
119
|
+
`Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
120
|
+
{
|
|
121
|
+
level: "error"
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
} else if (!configuration.editor.liveSync) {
|
|
126
|
+
appLogger(
|
|
127
|
+
"Hot reload is disabled. Please enable it in the configuration (editor.liveSync)."
|
|
128
|
+
);
|
|
129
|
+
} else if (!configuration.editor.clientId || !configuration.editor.clientSecret) {
|
|
130
|
+
appLogger(
|
|
131
|
+
"Missing client credentials for hot reload. Please configure clientId and clientSecret"
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
const server = (0, import_http.createServer)(async (req, res) => {
|
|
135
|
+
if (req.method === "OPTIONS") {
|
|
136
|
+
res.writeHead(200, {
|
|
137
|
+
"Access-Control-Allow-Origin": "*",
|
|
138
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
139
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization"
|
|
140
|
+
});
|
|
141
|
+
res.end();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (req.url?.startsWith("/dictionaries")) {
|
|
145
|
+
res.writeHead(200, {
|
|
146
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
147
|
+
"Cache-Control": "no-store",
|
|
148
|
+
"Access-Control-Allow-Origin": "*",
|
|
149
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
150
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization"
|
|
151
|
+
});
|
|
152
|
+
const dictionaries = (0, import_dictionaries_entry.getDictionaries)();
|
|
153
|
+
const prefix = "/dictionaries/";
|
|
154
|
+
if (req.url.startsWith(prefix)) {
|
|
155
|
+
const [key, locale] = decodeURIComponent(req.url).slice(prefix.length).split("/");
|
|
156
|
+
const dictionary = dictionaries[key] ?? null;
|
|
157
|
+
if (locale) {
|
|
158
|
+
const sourceLocaleContent = (0, import_core.getLocalisedContent)(dictionary, locale, {
|
|
159
|
+
dictionaryKey: key,
|
|
160
|
+
keyPath: []
|
|
161
|
+
});
|
|
162
|
+
res.end(JSON.stringify(sourceLocaleContent));
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
res.end(JSON.stringify(dictionary));
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
res.end(JSON.stringify(dictionaries));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (req.url?.startsWith("/unmerged_dictionaries")) {
|
|
172
|
+
res.writeHead(200, {
|
|
173
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
174
|
+
"Cache-Control": "no-store",
|
|
175
|
+
"Access-Control-Allow-Origin": "*",
|
|
176
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
177
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization"
|
|
178
|
+
});
|
|
179
|
+
const unmergedDictionaries = (0, import_unmerged_dictionaries_entry.getUnmergedDictionaries)();
|
|
180
|
+
const prefix = "/unmerged_dictionaries/";
|
|
181
|
+
if (req.url.startsWith(prefix)) {
|
|
182
|
+
const key = decodeURIComponent(req.url.slice(prefix.length));
|
|
183
|
+
const one = unmergedDictionaries[key] ?? null;
|
|
184
|
+
res.end(JSON.stringify(one));
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
res.end(JSON.stringify(unmergedDictionaries));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (req.url === "/configuration") {
|
|
191
|
+
res.writeHead(200, {
|
|
192
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
193
|
+
"Cache-Control": "no-store",
|
|
194
|
+
"Access-Control-Allow-Origin": "*",
|
|
195
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
|
|
196
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization"
|
|
197
|
+
});
|
|
198
|
+
res.end(JSON.stringify(configuration));
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (req.url === "/health") {
|
|
202
|
+
res.writeHead(200, {
|
|
203
|
+
"Content-Type": "application/json; charset=utf-8"
|
|
204
|
+
});
|
|
205
|
+
res.end(JSON.stringify({ status: "ok" }));
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
res.end("Not found");
|
|
209
|
+
return;
|
|
210
|
+
});
|
|
211
|
+
const getLiveSyncParam = () => {
|
|
212
|
+
if (!configuration.editor.liveSync) return "\x1B[31m\u2717 Disabled\x1B[0m";
|
|
213
|
+
return "\x1B[32m\u2713 Enabled\x1B[0m";
|
|
214
|
+
};
|
|
215
|
+
server.listen(liveSyncPort, () => {
|
|
216
|
+
console.log(`
|
|
217
|
+
\x1B[1;90mINTLAYER v${import_package.default.version}\x1B[0m
|
|
218
|
+
|
|
219
|
+
Live server running at: \x1B[90m${liveSyncURL}\x1B[0m
|
|
220
|
+
- Backend URL: \x1B[90m${configuration.editor.backendURL ?? "-"}\x1B[0m
|
|
221
|
+
- Live sync: ${getLiveSyncParam()}
|
|
222
|
+
- Parallel process: ${options?.process === "" ? "-" : `\x1B[90m${options?.process}\x1B[0m`}
|
|
223
|
+
- Access key: ${configuration.editor.clientId ?? "-"}
|
|
224
|
+
`);
|
|
225
|
+
});
|
|
226
|
+
const cleanup = () => {
|
|
227
|
+
if (eventListener) {
|
|
228
|
+
appLogger("Closing SSE connection...");
|
|
229
|
+
eventListener.cleanup();
|
|
230
|
+
}
|
|
231
|
+
if (childProcess && !childProcess.killed) {
|
|
232
|
+
appLogger("Terminating parallel process...");
|
|
233
|
+
childProcess.kill("SIGTERM");
|
|
234
|
+
setTimeout(() => {
|
|
235
|
+
if (childProcess && !childProcess.killed) {
|
|
236
|
+
appLogger("Force killing parallel process...");
|
|
237
|
+
childProcess.kill("SIGKILL");
|
|
238
|
+
}
|
|
239
|
+
}, 5e3);
|
|
240
|
+
}
|
|
241
|
+
server.close(() => {
|
|
242
|
+
appLogger("Live sync server stopped");
|
|
243
|
+
process.exit(0);
|
|
244
|
+
});
|
|
245
|
+
};
|
|
246
|
+
process.on("SIGINT", cleanup);
|
|
247
|
+
process.on("SIGTERM", cleanup);
|
|
248
|
+
process.on("exit", cleanup);
|
|
249
|
+
};
|
|
250
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
251
|
+
0 && (module.exports = {
|
|
252
|
+
liveSync
|
|
253
|
+
});
|
|
254
|
+
//# sourceMappingURL=liveSync.cjs.map
|
|
@@ -0,0 +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"]}
|
package/dist/cjs/pull.cjs
CHANGED
|
@@ -36,16 +36,12 @@ var import_chokidar = require("@intlayer/chokidar");
|
|
|
36
36
|
var import_config = require("@intlayer/config");
|
|
37
37
|
var import_p_limit = __toESM(require("p-limit"));
|
|
38
38
|
var readline = __toESM(require("readline"));
|
|
39
|
-
const spinnerFrames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
40
|
-
const RESET = "\x1B[0m";
|
|
41
|
-
const GREEN = "\x1B[32m";
|
|
42
|
-
const RED = "\x1B[31m";
|
|
43
|
-
const BLUE = "\x1B[34m";
|
|
44
|
-
const GREY = "\x1B[90m";
|
|
45
|
-
const YELLOW = "\x1B[33m";
|
|
46
|
-
const GREY_DARK = "\x1B[90m";
|
|
47
39
|
const pull = async (options) => {
|
|
48
|
-
const appLogger = (0, import_config.getAppLogger)(options?.configOptions?.override
|
|
40
|
+
const appLogger = (0, import_config.getAppLogger)(options?.configOptions?.override, {
|
|
41
|
+
config: {
|
|
42
|
+
prefix: ""
|
|
43
|
+
}
|
|
44
|
+
});
|
|
49
45
|
try {
|
|
50
46
|
const config = (0, import_config.getConfiguration)(options?.configOptions);
|
|
51
47
|
const { clientId, clientSecret } = config.editor;
|
|
@@ -164,30 +160,30 @@ const getStatusLine = (statusObj) => {
|
|
|
164
160
|
let colorStart = "";
|
|
165
161
|
let colorEnd = "";
|
|
166
162
|
if (statusObj.status === "fetching") {
|
|
167
|
-
icon = spinnerFrames[statusObj.spinnerFrameIndex % spinnerFrames.length];
|
|
168
|
-
colorStart = BLUE;
|
|
169
|
-
colorEnd = RESET;
|
|
163
|
+
icon = import_config.spinnerFrames[statusObj.spinnerFrameIndex % import_config.spinnerFrames.length];
|
|
164
|
+
colorStart = import_config.ANSIColors.BLUE;
|
|
165
|
+
colorEnd = import_config.ANSIColors.RESET;
|
|
170
166
|
} else if (statusObj.status === "error") {
|
|
171
|
-
colorStart = RED;
|
|
172
|
-
colorEnd = RESET;
|
|
167
|
+
colorStart = import_config.ANSIColors.RED;
|
|
168
|
+
colorEnd = import_config.ANSIColors.RESET;
|
|
173
169
|
} else if (statusObj.status === "fetched" || statusObj.status === "imported" || statusObj.status === "updated" || statusObj.status === "up-to-date") {
|
|
174
|
-
colorStart = GREEN;
|
|
175
|
-
colorEnd = RESET;
|
|
170
|
+
colorStart = import_config.ANSIColors.GREEN;
|
|
171
|
+
colorEnd = import_config.ANSIColors.RESET;
|
|
176
172
|
} else if (statusObj.status === "reimported in JSON" || statusObj.status === "reimported in new location") {
|
|
177
|
-
colorStart = YELLOW;
|
|
178
|
-
colorEnd = RESET;
|
|
173
|
+
colorStart = import_config.ANSIColors.YELLOW;
|
|
174
|
+
colorEnd = import_config.ANSIColors.RESET;
|
|
179
175
|
} else {
|
|
180
|
-
colorStart = GREY;
|
|
181
|
-
colorEnd = RESET;
|
|
176
|
+
colorStart = import_config.ANSIColors.GREY;
|
|
177
|
+
colorEnd = import_config.ANSIColors.RESET;
|
|
182
178
|
}
|
|
183
|
-
return `- ${statusObj.dictionaryKey} ${GREY_DARK}[${colorStart}${icon}${statusObj.status}${GREY_DARK}]${colorEnd}`;
|
|
179
|
+
return `- ${statusObj.dictionaryKey} ${import_config.ANSIColors.GREY_DARK}[${colorStart}${icon}${statusObj.status}${import_config.ANSIColors.GREY_DARK}]${colorEnd}`;
|
|
184
180
|
};
|
|
185
181
|
const updateAllStatusLines = (dictionariesStatuses) => {
|
|
186
182
|
readline.moveCursor(process.stdout, 0, -dictionariesStatuses.length);
|
|
187
183
|
for (const statusObj of dictionariesStatuses) {
|
|
188
184
|
readline.clearLine(process.stdout, 0);
|
|
189
185
|
if (statusObj.status === "fetching") {
|
|
190
|
-
statusObj.spinnerFrameIndex = (statusObj.spinnerFrameIndex + 1) % spinnerFrames.length;
|
|
186
|
+
statusObj.spinnerFrameIndex = (statusObj.spinnerFrameIndex + 1) % import_config.spinnerFrames.length;
|
|
191
187
|
}
|
|
192
188
|
process.stdout.write(getStatusLine(statusObj) + "\n");
|
|
193
189
|
}
|
package/dist/cjs/pull.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pull.ts"],"sourcesContent":["import { getIntlayerAPI } from '@intlayer/api';\nimport {\n writeContentDeclaration,\n type DictionaryStatus,\n} from '@intlayer/chokidar';\nimport {\n getAppLogger,\n getConfiguration,\n GetConfigurationOptions,\n} from '@intlayer/config';\n\nimport type { Dictionary } from '@intlayer/core';\nimport pLimit from 'p-limit';\nimport * as readline from 'readline';\n\ntype PullOptions = {\n dictionaries?: string[];\n newDictionariesPath?: string;\n configOptions?: GetConfigurationOptions;\n};\n\ntype DictionariesStatus = {\n dictionaryKey: string;\n status: DictionaryStatus;\n icon: string;\n index: number;\n error?: Error;\n errorMessage?: string;\n spinnerFrameIndex?: number;\n};\n\nconst spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nconst RESET = '\\x1b[0m';\nconst GREEN = '\\x1b[32m';\nconst RED = '\\x1b[31m';\nconst BLUE = '\\x1b[34m';\nconst GREY = '\\x1b[90m';\nconst YELLOW = '\\x1b[33m';\nconst GREY_DARK = '\\x1b[90m';\n\n/**\n * Fetch distant dictionaries and write them locally,\n * with progress indicators and concurrency control.\n */\nexport const pull = async (options?: PullOptions): Promise<void> => {\n const appLogger = getAppLogger(options?.configOptions?.override);\n\n try {\n const config = getConfiguration(options?.configOptions);\n const { clientId, clientSecret } = config.editor;\n\n if (!clientId || !clientSecret) {\n throw new Error(\n 'Missing OAuth2 client ID or client secret. To get access token go to https://intlayer.org/dashboard/project.'\n );\n }\n\n const intlayerAPI = getIntlayerAPI(undefined, config);\n\n const oAuth2TokenResult = await intlayerAPI.oAuth.getOAuth2AccessToken();\n\n const oAuth2AccessToken = oAuth2TokenResult.data?.accessToken;\n\n // Get the list of dictionary keys\n const getDictionariesKeysResult =\n await intlayerAPI.dictionary.getDictionariesKeys({\n ...(oAuth2AccessToken && {\n headers: {\n Authorization: `Bearer ${oAuth2AccessToken}`,\n },\n }),\n });\n\n if (!getDictionariesKeysResult.data) {\n throw new Error('No distant dictionaries found');\n }\n\n let distantDictionariesKeys: string[] = getDictionariesKeysResult.data;\n\n if (options?.dictionaries) {\n // Filter the dictionaries from the provided list of IDs\n distantDictionariesKeys = distantDictionariesKeys.filter(\n (dictionaryKey) => options.dictionaries!.includes(dictionaryKey)\n );\n }\n\n // Check if dictionaries list is empty\n if (distantDictionariesKeys.length === 0) {\n appLogger('No dictionaries to fetch', {\n level: 'error',\n });\n return;\n }\n\n appLogger('Fetching dictionaries:');\n\n // Prepare dictionaries statuses\n const dictionariesStatuses: DictionariesStatus[] =\n distantDictionariesKeys.map((dictionaryKey, index) => ({\n dictionaryKey,\n icon: getStatusIcon('pending'),\n status: 'pending',\n index,\n spinnerFrameIndex: 0,\n }));\n\n // Output initial statuses\n for (const statusObj of dictionariesStatuses) {\n process.stdout.write(getStatusLine(statusObj) + '\\n');\n }\n\n // Start spinner timer\n const spinnerTimer = setInterval(() => {\n updateAllStatusLines(dictionariesStatuses);\n }, 100); // Update every 100ms\n\n // Process dictionaries in parallel with a concurrency limit\n const limit = pLimit(5); // Limit the number of concurrent requests\n\n const successfullyFetchedDictionaries: Dictionary[] = [];\n\n const processDictionary = async (\n statusObj: DictionariesStatus\n ): Promise<void> => {\n statusObj.status = 'fetching';\n try {\n // Fetch the dictionary\n const getDictionaryResult = await intlayerAPI.dictionary.getDictionary(\n statusObj.dictionaryKey,\n undefined,\n {\n ...(oAuth2AccessToken && {\n headers: {\n Authorization: `Bearer ${oAuth2AccessToken}`,\n },\n }),\n }\n );\n\n const distantDictionary = getDictionaryResult.data;\n\n if (!distantDictionary) {\n throw new Error(\n `Dictionary ${statusObj.dictionaryKey} not found on remote`\n );\n }\n\n // Now, write the dictionary to local file\n const { status } = await writeContentDeclaration(\n distantDictionary,\n config,\n options?.newDictionariesPath\n );\n\n statusObj.status = status;\n\n successfullyFetchedDictionaries.push(distantDictionary);\n } catch (error) {\n statusObj.status = 'error';\n statusObj.error = error as Error;\n statusObj.errorMessage = `Error fetching dictionary ${statusObj.dictionaryKey}: ${error}`;\n }\n };\n\n const fetchPromises = dictionariesStatuses.map((statusObj) =>\n limit(() => processDictionary(statusObj))\n );\n\n await Promise.all(fetchPromises);\n\n // Stop the spinner timer\n clearInterval(spinnerTimer);\n\n // Update statuses one last time\n updateAllStatusLines(dictionariesStatuses);\n\n // Output any error messages\n for (const statusObj of dictionariesStatuses) {\n if (statusObj.errorMessage) {\n appLogger(statusObj.errorMessage, {\n level: 'error',\n });\n }\n }\n } catch (error) {\n appLogger(error, {\n level: 'error',\n });\n }\n};\n\nconst getStatusIcon = (status: string): string => {\n const statusIcons: Record<string, string> = {\n pending: '⏲',\n fetching: '', // Spinner handled separately\n 'up-to-date': '✔',\n updated: '✔',\n fetched: '✔',\n error: '✖',\n };\n return statusIcons[status] ?? '';\n};\n\nconst getStatusLine = (statusObj: DictionariesStatus): string => {\n let icon = getStatusIcon(statusObj.status);\n let colorStart = '';\n let colorEnd = '';\n\n if (statusObj.status === 'fetching') {\n // Use spinner frame\n icon = spinnerFrames[statusObj.spinnerFrameIndex! % spinnerFrames.length];\n colorStart = BLUE;\n colorEnd = RESET;\n } else if (statusObj.status === 'error') {\n colorStart = RED;\n colorEnd = RESET;\n } else if (\n statusObj.status === 'fetched' ||\n statusObj.status === 'imported' ||\n statusObj.status === 'updated' ||\n statusObj.status === 'up-to-date'\n ) {\n colorStart = GREEN;\n colorEnd = RESET;\n } else if (\n statusObj.status === 'reimported in JSON' ||\n statusObj.status === 'reimported in new location'\n ) {\n colorStart = YELLOW;\n colorEnd = RESET;\n } else {\n colorStart = GREY;\n colorEnd = RESET;\n }\n\n return `- ${statusObj.dictionaryKey} ${GREY_DARK}[${colorStart}${icon}${statusObj.status}${GREY_DARK}]${colorEnd}`;\n};\n\nconst updateAllStatusLines = (dictionariesStatuses: DictionariesStatus[]) => {\n // Move cursor up to the first status line\n readline.moveCursor(process.stdout, 0, -dictionariesStatuses.length);\n for (const statusObj of dictionariesStatuses) {\n // Clear the line\n readline.clearLine(process.stdout, 0);\n\n if (statusObj.status === 'fetching') {\n // Update spinner frame\n statusObj.spinnerFrameIndex =\n (statusObj.spinnerFrameIndex! + 1) % spinnerFrames.length;\n }\n\n // Write the status line\n process.stdout.write(getStatusLine(statusObj) + '\\n');\n }\n};\n"],"mappings":"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","names":["pLimit"]}
|
|
1
|
+
{"version":3,"sources":["../../src/pull.ts"],"sourcesContent":["import { getIntlayerAPI } from '@intlayer/api';\nimport {\n writeContentDeclaration,\n type DictionaryStatus,\n} from '@intlayer/chokidar';\nimport {\n ANSIColors,\n getAppLogger,\n getConfiguration,\n GetConfigurationOptions,\n spinnerFrames,\n} from '@intlayer/config';\nimport type { Dictionary } from '@intlayer/core';\nimport pLimit from 'p-limit';\nimport * as readline from 'readline';\n\ntype PullOptions = {\n dictionaries?: string[];\n newDictionariesPath?: string;\n configOptions?: GetConfigurationOptions;\n};\n\ntype DictionariesStatus = {\n dictionaryKey: string;\n status: DictionaryStatus;\n icon: string;\n index: number;\n error?: Error;\n errorMessage?: string;\n spinnerFrameIndex?: number;\n};\n\n/**\n * Fetch distant dictionaries and write them locally,\n * with progress indicators and concurrency control.\n */\nexport const pull = async (options?: PullOptions): Promise<void> => {\n const appLogger = getAppLogger(options?.configOptions?.override, {\n config: {\n prefix: '',\n },\n });\n\n try {\n const config = getConfiguration(options?.configOptions);\n const { clientId, clientSecret } = config.editor;\n\n if (!clientId || !clientSecret) {\n throw new Error(\n 'Missing OAuth2 client ID or client secret. To get access token go to https://intlayer.org/dashboard/project.'\n );\n }\n\n const intlayerAPI = getIntlayerAPI(undefined, config);\n\n const oAuth2TokenResult = await intlayerAPI.oAuth.getOAuth2AccessToken();\n\n const oAuth2AccessToken = oAuth2TokenResult.data?.accessToken;\n\n // Get the list of dictionary keys\n const getDictionariesKeysResult =\n await intlayerAPI.dictionary.getDictionariesKeys({\n ...(oAuth2AccessToken && {\n headers: {\n Authorization: `Bearer ${oAuth2AccessToken}`,\n },\n }),\n });\n\n if (!getDictionariesKeysResult.data) {\n throw new Error('No distant dictionaries found');\n }\n\n let distantDictionariesKeys: string[] = getDictionariesKeysResult.data;\n\n if (options?.dictionaries) {\n // Filter the dictionaries from the provided list of IDs\n distantDictionariesKeys = distantDictionariesKeys.filter(\n (dictionaryKey) => options.dictionaries!.includes(dictionaryKey)\n );\n }\n\n // Check if dictionaries list is empty\n if (distantDictionariesKeys.length === 0) {\n appLogger('No dictionaries to fetch', {\n level: 'error',\n });\n return;\n }\n\n appLogger('Fetching dictionaries:');\n\n // Prepare dictionaries statuses\n const dictionariesStatuses: DictionariesStatus[] =\n distantDictionariesKeys.map((dictionaryKey, index) => ({\n dictionaryKey,\n icon: getStatusIcon('pending'),\n status: 'pending',\n index,\n spinnerFrameIndex: 0,\n }));\n\n // Output initial statuses\n for (const statusObj of dictionariesStatuses) {\n process.stdout.write(getStatusLine(statusObj) + '\\n');\n }\n\n // Start spinner timer\n const spinnerTimer = setInterval(() => {\n updateAllStatusLines(dictionariesStatuses);\n }, 100); // Update every 100ms\n\n // Process dictionaries in parallel with a concurrency limit\n const limit = pLimit(5); // Limit the number of concurrent requests\n\n const successfullyFetchedDictionaries: Dictionary[] = [];\n\n const processDictionary = async (\n statusObj: DictionariesStatus\n ): Promise<void> => {\n statusObj.status = 'fetching';\n try {\n // Fetch the dictionary\n const getDictionaryResult = await intlayerAPI.dictionary.getDictionary(\n statusObj.dictionaryKey,\n undefined,\n {\n ...(oAuth2AccessToken && {\n headers: {\n Authorization: `Bearer ${oAuth2AccessToken}`,\n },\n }),\n }\n );\n\n const distantDictionary = getDictionaryResult.data;\n\n if (!distantDictionary) {\n throw new Error(\n `Dictionary ${statusObj.dictionaryKey} not found on remote`\n );\n }\n\n // Now, write the dictionary to local file\n const { status } = await writeContentDeclaration(\n distantDictionary,\n config,\n options?.newDictionariesPath\n );\n\n statusObj.status = status;\n\n successfullyFetchedDictionaries.push(distantDictionary);\n } catch (error) {\n statusObj.status = 'error';\n statusObj.error = error as Error;\n statusObj.errorMessage = `Error fetching dictionary ${statusObj.dictionaryKey}: ${error}`;\n }\n };\n\n const fetchPromises = dictionariesStatuses.map((statusObj) =>\n limit(() => processDictionary(statusObj))\n );\n\n await Promise.all(fetchPromises);\n\n // Stop the spinner timer\n clearInterval(spinnerTimer);\n\n // Update statuses one last time\n updateAllStatusLines(dictionariesStatuses);\n\n // Output any error messages\n for (const statusObj of dictionariesStatuses) {\n if (statusObj.errorMessage) {\n appLogger(statusObj.errorMessage, {\n level: 'error',\n });\n }\n }\n } catch (error) {\n appLogger(error, {\n level: 'error',\n });\n }\n};\n\nconst getStatusIcon = (status: string): string => {\n const statusIcons: Record<string, string> = {\n pending: '⏲',\n fetching: '', // Spinner handled separately\n 'up-to-date': '✔',\n updated: '✔',\n fetched: '✔',\n error: '✖',\n };\n return statusIcons[status] ?? '';\n};\n\nconst getStatusLine = (statusObj: DictionariesStatus): string => {\n let icon = getStatusIcon(statusObj.status);\n let colorStart = '';\n let colorEnd = '';\n\n if (statusObj.status === 'fetching') {\n // Use spinner frame\n icon = spinnerFrames[statusObj.spinnerFrameIndex! % spinnerFrames.length];\n colorStart = ANSIColors.BLUE;\n colorEnd = ANSIColors.RESET;\n } else if (statusObj.status === 'error') {\n colorStart = ANSIColors.RED;\n colorEnd = ANSIColors.RESET;\n } else if (\n statusObj.status === 'fetched' ||\n statusObj.status === 'imported' ||\n statusObj.status === 'updated' ||\n statusObj.status === 'up-to-date'\n ) {\n colorStart = ANSIColors.GREEN;\n colorEnd = ANSIColors.RESET;\n } else if (\n statusObj.status === 'reimported in JSON' ||\n statusObj.status === 'reimported in new location'\n ) {\n colorStart = ANSIColors.YELLOW;\n colorEnd = ANSIColors.RESET;\n } else {\n colorStart = ANSIColors.GREY;\n colorEnd = ANSIColors.RESET;\n }\n\n return `- ${statusObj.dictionaryKey} ${ANSIColors.GREY_DARK}[${colorStart}${icon}${statusObj.status}${ANSIColors.GREY_DARK}]${colorEnd}`;\n};\n\nconst updateAllStatusLines = (dictionariesStatuses: DictionariesStatus[]) => {\n // Move cursor up to the first status line\n readline.moveCursor(process.stdout, 0, -dictionariesStatuses.length);\n for (const statusObj of dictionariesStatuses) {\n // Clear the line\n readline.clearLine(process.stdout, 0);\n\n if (statusObj.status === 'fetching') {\n // Update spinner frame\n statusObj.spinnerFrameIndex =\n (statusObj.spinnerFrameIndex! + 1) % spinnerFrames.length;\n }\n\n // Write the status line\n process.stdout.write(getStatusLine(statusObj) + '\\n');\n }\n};\n"],"mappings":"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","names":["pLimit"]}
|
package/dist/cjs/push.cjs
CHANGED
|
@@ -37,18 +37,14 @@ var import_config = require("@intlayer/config");
|
|
|
37
37
|
var import_dictionaries_entry = __toESM(require("@intlayer/dictionaries-entry"));
|
|
38
38
|
var fsPromises = __toESM(require("fs/promises"));
|
|
39
39
|
var import_p_limit = __toESM(require("p-limit"));
|
|
40
|
-
var import_path = require("path");
|
|
41
40
|
var readline = __toESM(require("readline"));
|
|
42
|
-
const spinnerFrames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
43
|
-
const RESET = "\x1B[0m";
|
|
44
|
-
const GREEN = "\x1B[32m";
|
|
45
|
-
const RED = "\x1B[31m";
|
|
46
|
-
const BLUE = "\x1B[34m";
|
|
47
|
-
const GREY = "\x1B[90m";
|
|
48
|
-
const GREY_DARK = "\x1B[90m";
|
|
49
41
|
const push = async (options) => {
|
|
50
42
|
const config = (0, import_config.getConfiguration)(options?.configOptions);
|
|
51
|
-
const appLogger = (0, import_config.getAppLogger)(config
|
|
43
|
+
const appLogger = (0, import_config.getAppLogger)(config, {
|
|
44
|
+
config: {
|
|
45
|
+
prefix: ""
|
|
46
|
+
}
|
|
47
|
+
});
|
|
52
48
|
const { clientId, clientSecret } = config.editor;
|
|
53
49
|
try {
|
|
54
50
|
if (!clientId || !clientSecret) {
|
|
@@ -186,8 +182,11 @@ const askUser = (question) => {
|
|
|
186
182
|
};
|
|
187
183
|
const deleteLocalDictionaries = async (dictionariesToDelete, options) => {
|
|
188
184
|
const config = (0, import_config.getConfiguration)(options?.configOptions);
|
|
189
|
-
const appLogger = (0, import_config.getAppLogger)(config
|
|
190
|
-
|
|
185
|
+
const appLogger = (0, import_config.getAppLogger)(config, {
|
|
186
|
+
config: {
|
|
187
|
+
prefix: ""
|
|
188
|
+
}
|
|
189
|
+
});
|
|
191
190
|
const filePathsSet = /* @__PURE__ */ new Set();
|
|
192
191
|
for (const dictionary of dictionariesToDelete) {
|
|
193
192
|
const { filePath } = dictionary;
|
|
@@ -200,19 +199,21 @@ const deleteLocalDictionaries = async (dictionariesToDelete, options) => {
|
|
|
200
199
|
filePathsSet.add(filePath);
|
|
201
200
|
}
|
|
202
201
|
for (const filePath of filePathsSet) {
|
|
203
|
-
const relativePath = (0, import_path.relative)(baseDir, filePath);
|
|
204
202
|
try {
|
|
205
203
|
const stats = await fsPromises.lstat(filePath);
|
|
206
204
|
if (stats.isFile()) {
|
|
207
205
|
await fsPromises.unlink(filePath);
|
|
208
|
-
appLogger(`Deleted file ${
|
|
206
|
+
appLogger(`Deleted file ${(0, import_chokidar.formatPath)(filePath)}`, {});
|
|
209
207
|
} else if (stats.isDirectory()) {
|
|
210
|
-
appLogger(`Path is a directory ${
|
|
208
|
+
appLogger(`Path is a directory ${(0, import_chokidar.formatPath)(filePath)}, skipping.`, {});
|
|
211
209
|
} else {
|
|
212
|
-
appLogger(
|
|
210
|
+
appLogger(
|
|
211
|
+
`Unknown file type for ${(0, import_chokidar.formatPath)(filePath)}, skipping.`,
|
|
212
|
+
{}
|
|
213
|
+
);
|
|
213
214
|
}
|
|
214
215
|
} catch (err) {
|
|
215
|
-
appLogger(`Error deleting ${
|
|
216
|
+
appLogger(`Error deleting ${(0, import_chokidar.formatPath)(filePath)}: ${err}`, {
|
|
216
217
|
level: "error"
|
|
217
218
|
});
|
|
218
219
|
}
|
|
@@ -234,27 +235,27 @@ const getStatusLine = (statusObj) => {
|
|
|
234
235
|
let colorStart = "";
|
|
235
236
|
let colorEnd = "";
|
|
236
237
|
if (statusObj.status === "pushing") {
|
|
237
|
-
icon = spinnerFrames[statusObj.spinnerFrameIndex % spinnerFrames.length];
|
|
238
|
-
colorStart = BLUE;
|
|
239
|
-
colorEnd = RESET;
|
|
238
|
+
icon = import_config.spinnerFrames[statusObj.spinnerFrameIndex % import_config.spinnerFrames.length];
|
|
239
|
+
colorStart = import_config.ANSIColors.BLUE;
|
|
240
|
+
colorEnd = import_config.ANSIColors.RESET;
|
|
240
241
|
} else if (statusObj.status === "error") {
|
|
241
|
-
colorStart = RED;
|
|
242
|
-
colorEnd = RESET;
|
|
242
|
+
colorStart = import_config.ANSIColors.RED;
|
|
243
|
+
colorEnd = import_config.ANSIColors.RESET;
|
|
243
244
|
} else if (statusObj.status === "pushed" || statusObj.status === "modified") {
|
|
244
|
-
colorStart = GREEN;
|
|
245
|
-
colorEnd = RESET;
|
|
245
|
+
colorStart = import_config.ANSIColors.GREEN;
|
|
246
|
+
colorEnd = import_config.ANSIColors.RESET;
|
|
246
247
|
} else {
|
|
247
|
-
colorStart = GREY;
|
|
248
|
-
colorEnd = RESET;
|
|
248
|
+
colorStart = import_config.ANSIColors.GREY;
|
|
249
|
+
colorEnd = import_config.ANSIColors.RESET;
|
|
249
250
|
}
|
|
250
|
-
return `- ${statusObj.dictionary.key} ${GREY_DARK}[${colorStart}${icon}${statusObj.status}${GREY_DARK}]${colorEnd}`;
|
|
251
|
+
return `- ${statusObj.dictionary.key} ${import_config.ANSIColors.GREY_DARK}[${colorStart}${icon}${statusObj.status}${import_config.ANSIColors.GREY_DARK}]${colorEnd}`;
|
|
251
252
|
};
|
|
252
253
|
const updateAllStatusLines = (dictionariesStatuses) => {
|
|
253
254
|
readline.moveCursor(process.stdout, 0, -dictionariesStatuses.length);
|
|
254
255
|
for (const statusObj of dictionariesStatuses) {
|
|
255
256
|
readline.clearLine(process.stdout, 0);
|
|
256
257
|
if (statusObj.status === "pushing") {
|
|
257
|
-
statusObj.spinnerFrameIndex = (statusObj.spinnerFrameIndex + 1) % spinnerFrames.length;
|
|
258
|
+
statusObj.spinnerFrameIndex = (statusObj.spinnerFrameIndex + 1) % import_config.spinnerFrames.length;
|
|
258
259
|
}
|
|
259
260
|
process.stdout.write(getStatusLine(statusObj) + "\n");
|
|
260
261
|
}
|