@tolgee/cli 2.3.4 → 2.4.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/commands/push.js +2 -2
- package/dist/config/tolgeerc.js +4 -4
- package/dist/extractor/runner.js +18 -11
- package/dist/extractor/worker.js +21 -19
- package/dist/utils/moduleLoader.js +15 -22
- package/package.json +25 -16
- package/dist/utils/windowsCompatibleGlob.js +0 -7
package/dist/commands/push.js
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
import { extname, join } from 'path';
|
2
2
|
import { readdir, readFile, stat } from 'fs/promises';
|
3
3
|
import { Command, Option } from 'commander';
|
4
|
+
import { glob } from 'tinyglobby';
|
4
5
|
import { loading, success, error, warn, exitWithError, } from '../utils/logger.js';
|
5
6
|
import { askString } from '../utils/ask.js';
|
6
7
|
import { mapImportFormat } from '../utils/mapImportFormat.js';
|
7
8
|
import { handleLoadableError } from '../client/TolgeeClient.js';
|
8
|
-
import { windowsCompatibleGlob } from '../utils/windowsCompatibleGlob.js';
|
9
9
|
async function allInPattern(pattern) {
|
10
10
|
const files = [];
|
11
|
-
const items = await
|
11
|
+
const items = await glob(pattern);
|
12
12
|
for (const item of items) {
|
13
13
|
if ((await stat(item)).isDirectory()) {
|
14
14
|
files.push(...(await readDirectory(item)));
|
package/dist/config/tolgeerc.js
CHANGED
@@ -28,25 +28,25 @@ function parseConfig(input, configDir) {
|
|
28
28
|
}
|
29
29
|
// convert relative paths in config to absolute
|
30
30
|
if (rc.extractor !== undefined) {
|
31
|
-
rc.extractor = resolve(configDir, rc.extractor);
|
31
|
+
rc.extractor = resolve(configDir, rc.extractor).replace(/\\/g, '/');
|
32
32
|
if (!existsSync(rc.extractor)) {
|
33
33
|
throw new Error(`Invalid config: extractor points to a file that does not exists (${rc.extractor})`);
|
34
34
|
}
|
35
35
|
}
|
36
36
|
// convert relative paths in config to absolute
|
37
37
|
if (rc.patterns !== undefined) {
|
38
|
-
rc.patterns = rc.patterns.map((pattern) => resolve(configDir, pattern));
|
38
|
+
rc.patterns = rc.patterns.map((pattern) => resolve(configDir, pattern).replace(/\\/g, '/'));
|
39
39
|
}
|
40
40
|
// convert relative paths in config to absolute
|
41
41
|
if (rc.push?.files) {
|
42
42
|
rc.push.files = rc.push.files.map((r) => ({
|
43
43
|
...r,
|
44
|
-
path: resolve(configDir, r.path),
|
44
|
+
path: resolve(configDir, r.path).replace(/\\/g, '/'),
|
45
45
|
}));
|
46
46
|
}
|
47
47
|
// convert relative paths in config to absolute
|
48
48
|
if (rc.pull?.path !== undefined) {
|
49
|
-
rc.pull.path = resolve(configDir, rc.pull.path);
|
49
|
+
rc.pull.path = resolve(configDir, rc.pull.path).replace(/\\/g, '/');
|
50
50
|
}
|
51
51
|
return rc;
|
52
52
|
}
|
package/dist/extractor/runner.js
CHANGED
@@ -1,18 +1,27 @@
|
|
1
|
+
import { glob } from 'tinyglobby';
|
1
2
|
import { extname } from 'path';
|
2
3
|
import { callWorker } from './worker.js';
|
3
4
|
import { exitWithError } from '../utils/logger.js';
|
4
|
-
import { windowsCompatibleGlob } from '../utils/windowsCompatibleGlob.js';
|
5
5
|
export const NullNamespace = Symbol('namespace.null');
|
6
6
|
function parseVerbose(v) {
|
7
7
|
return Array.isArray(v) ? v : v ? [] : undefined;
|
8
8
|
}
|
9
9
|
export async function extractKeysFromFile(file, parserType, options, extractor) {
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
if (typeof extractor !== 'undefined') {
|
11
|
+
return callWorker({
|
12
|
+
extractor,
|
13
|
+
file,
|
14
|
+
options,
|
15
|
+
});
|
16
|
+
}
|
17
|
+
else if (typeof parserType !== 'undefined') {
|
18
|
+
return callWorker({
|
19
|
+
parserType,
|
20
|
+
file,
|
21
|
+
options,
|
22
|
+
});
|
23
|
+
}
|
24
|
+
throw new Error('Internal error: neither the parser type nor a custom extractors have been defined! Please report this.');
|
16
25
|
}
|
17
26
|
export function findPossibleFrameworks(fileNames) {
|
18
27
|
const possibleFrameworks = [];
|
@@ -54,14 +63,12 @@ export async function extractKeysOfFiles(opts) {
|
|
54
63
|
if (!opts.patterns?.length) {
|
55
64
|
exitWithError("Missing '--patterns' or 'config.patterns' option");
|
56
65
|
}
|
57
|
-
const files = await
|
58
|
-
nodir: true,
|
59
|
-
});
|
66
|
+
const files = await glob(opts.patterns, { onlyFiles: true });
|
60
67
|
if (files.length === 0) {
|
61
68
|
exitWithError('No files were matched for extraction');
|
62
69
|
}
|
63
70
|
let parserType = opts.parser;
|
64
|
-
if (!parserType) {
|
71
|
+
if (!parserType && !opts.extractor) {
|
65
72
|
parserType = detectParserType(files);
|
66
73
|
}
|
67
74
|
const result = new Map();
|
package/dist/extractor/worker.js
CHANGED
@@ -1,30 +1,26 @@
|
|
1
1
|
import { fileURLToPath } from 'url';
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {
|
2
|
+
import { extname, resolve } from 'path';
|
3
|
+
import { isMainThread, parentPort, SHARE_ENV, Worker } from 'worker_threads';
|
4
|
+
import { readFileSync } from 'fs';
|
5
5
|
import internalExtractor from './extractor.js';
|
6
6
|
import { loadModule } from '../utils/moduleLoader.js';
|
7
7
|
import { createDeferred } from '../utils/deferred.js';
|
8
8
|
const FILE_TIME_LIMIT = 60 * 1000; // one minute
|
9
|
-
const
|
9
|
+
const IS_TSX = extname(import.meta.url) === '.ts';
|
10
10
|
// --- Worker functions
|
11
|
-
let loadedExtractor = Symbol('unloaded');
|
12
11
|
let extractor;
|
13
12
|
async function handleJob(args) {
|
14
13
|
const file = resolve(args.file);
|
15
|
-
const code =
|
16
|
-
if (args
|
17
|
-
if (
|
18
|
-
loadedExtractor = args.extractor;
|
14
|
+
const code = readFileSync(file, 'utf8');
|
15
|
+
if ('extractor' in args) {
|
16
|
+
if (!extractor) {
|
19
17
|
extractor = await loadModule(args.extractor).then((mdl) => mdl.default);
|
20
18
|
}
|
21
19
|
return extractor(code, file, args.options);
|
22
20
|
}
|
23
|
-
|
24
|
-
return internalExtractor(code, file, args.parserType, args.options);
|
25
|
-
}
|
21
|
+
return internalExtractor(code, file, args.parserType, args.options);
|
26
22
|
}
|
27
|
-
|
23
|
+
function workerInit() {
|
28
24
|
parentPort.on('message', (params) => {
|
29
25
|
handleJob(params)
|
30
26
|
.then((res) => parentPort.postMessage({ data: res }))
|
@@ -37,12 +33,18 @@ if (!isMainThread)
|
|
37
33
|
let worker;
|
38
34
|
const jobQueue = [];
|
39
35
|
function createWorker() {
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
36
|
+
let worker;
|
37
|
+
if (IS_TSX) {
|
38
|
+
worker = new Worker(`import('tsx/esm/api').then(({ register }) => { register(); import('${fileURLToPath(new URL(import.meta.url))}') })`, {
|
39
|
+
env: SHARE_ENV,
|
40
|
+
eval: true,
|
41
|
+
});
|
42
|
+
}
|
43
|
+
else {
|
44
|
+
worker = new Worker(fileURLToPath(new URL(import.meta.url)), {
|
45
|
+
env: SHARE_ENV,
|
46
|
+
});
|
47
|
+
}
|
46
48
|
let timeout;
|
47
49
|
let currentDeferred;
|
48
50
|
function workOrDie() {
|
@@ -1,33 +1,26 @@
|
|
1
|
-
import {
|
2
|
-
let
|
3
|
-
|
4
|
-
if (!tsService) {
|
5
|
-
// try {
|
6
|
-
// const tsNode = await import('ts-node');
|
7
|
-
// tsService = tsNode.register({ compilerOptions: { module: 'CommonJS' } });
|
8
|
-
// } catch (e: any) {
|
9
|
-
// if (e.code === 'ERR_MODULE_NOT_FOUND') {
|
10
|
-
// throw new Error('ts-node is required to load TypeScript files.');
|
11
|
-
// }
|
12
|
-
// throw e;
|
13
|
-
// }
|
14
|
-
}
|
15
|
-
}
|
1
|
+
import { pathToFileURL } from 'url';
|
2
|
+
let jiti;
|
3
|
+
// https://github.com/eslint/eslint/blob/6f37b0747a14dfa9a9e3bdebc5caed1f39b6b0e2/lib/config/config-loader.js#L164-L197
|
16
4
|
async function importTypeScript(file) {
|
17
|
-
|
5
|
+
// @ts-ignore
|
6
|
+
if (!!globalThis.Bun || !!globalThis.Deno) {
|
7
|
+
// We're in an env that natively supports TS
|
18
8
|
return import(file);
|
19
9
|
}
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
10
|
+
if (!jiti) {
|
11
|
+
const { createJiti } = await import('jiti').catch(() => {
|
12
|
+
throw new Error("The 'jiti' library is required for loading TypeScript extractors. Make sure to install it.");
|
13
|
+
});
|
14
|
+
jiti = createJiti(import.meta.url);
|
15
|
+
}
|
16
|
+
return jiti.import(file);
|
25
17
|
}
|
26
18
|
export async function loadModule(module) {
|
27
19
|
if (module.endsWith('.ts')) {
|
28
20
|
return importTypeScript(module);
|
29
21
|
}
|
30
|
-
const
|
22
|
+
const fileUrl = pathToFileURL(module);
|
23
|
+
const mdl = await import(fileUrl.href);
|
31
24
|
if (mdl.default?.default) {
|
32
25
|
return mdl.default;
|
33
26
|
}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@tolgee/cli",
|
3
|
-
"version": "2.
|
3
|
+
"version": "2.4.0",
|
4
4
|
"type": "module",
|
5
5
|
"description": "A tool to interact with the Tolgee Platform through CLI",
|
6
6
|
"repository": {
|
@@ -34,40 +34,49 @@
|
|
34
34
|
"base32-decode": "^1.0.0",
|
35
35
|
"commander": "^12.1.0",
|
36
36
|
"cosmiconfig": "^9.0.0",
|
37
|
-
"glob": "^11.0.0",
|
38
37
|
"json5": "^2.2.3",
|
39
38
|
"jsonschema": "^1.4.1",
|
40
|
-
"openapi-fetch": "
|
39
|
+
"openapi-fetch": "0.13.1",
|
40
|
+
"tinyglobby": "^0.2.10",
|
41
41
|
"unescape-js": "^1.1.4",
|
42
42
|
"vscode-oniguruma": "^2.0.1",
|
43
43
|
"vscode-textmate": "^9.1.0",
|
44
|
-
"yauzl": "^3.
|
44
|
+
"yauzl": "^3.2.0"
|
45
45
|
},
|
46
46
|
"devDependencies": {
|
47
|
-
"@eslint/js": "^9.
|
47
|
+
"@eslint/js": "^9.16.0",
|
48
48
|
"@semantic-release/changelog": "^6.0.3",
|
49
49
|
"@semantic-release/git": "^10.0.1",
|
50
50
|
"@tsconfig/node18": "^18.2.4",
|
51
|
-
"@tsconfig/recommended": "^1.0.
|
51
|
+
"@tsconfig/recommended": "^1.0.8",
|
52
52
|
"@types/eslint__js": "^8.42.3",
|
53
53
|
"@types/js-yaml": "^4.0.9",
|
54
|
-
"@types/node": "^22.1
|
54
|
+
"@types/node": "^22.10.1",
|
55
55
|
"@types/yauzl": "^2.10.3",
|
56
56
|
"cross-env": "^7.0.3",
|
57
|
-
"eslint": "^9.
|
57
|
+
"eslint": "^9.16.0",
|
58
58
|
"eslint-config-prettier": "^9.1.0",
|
59
59
|
"eslint-plugin-prettier": "^5.2.1",
|
60
|
+
"jiti": "^2.4.1",
|
60
61
|
"js-yaml": "^4.1.0",
|
61
|
-
"json-schema-to-typescript": "^15.0.
|
62
|
-
"openapi-typescript": "^7.
|
62
|
+
"json-schema-to-typescript": "^15.0.3",
|
63
|
+
"openapi-typescript": "^7.4.4",
|
63
64
|
"premove": "^4.0.0",
|
64
|
-
"prettier": "^3.
|
65
|
-
"semantic-release": "^24.
|
65
|
+
"prettier": "^3.4.1",
|
66
|
+
"semantic-release": "^24.2.0",
|
66
67
|
"tree-cli": "^0.6.7",
|
67
|
-
"tsx": "^4.
|
68
|
-
"typescript": "
|
69
|
-
"typescript-eslint": "^8.0
|
70
|
-
"vitest": "^2.
|
68
|
+
"tsx": "^4.19.2",
|
69
|
+
"typescript": "~5.6.3",
|
70
|
+
"typescript-eslint": "^8.17.0",
|
71
|
+
"vitest": "^2.1.8"
|
72
|
+
},
|
73
|
+
"peerDependencies": {
|
74
|
+
"jiti": ">= 2"
|
75
|
+
},
|
76
|
+
"peerDependenciesMeta": {
|
77
|
+
"jiti": {
|
78
|
+
"optional": true
|
79
|
+
}
|
71
80
|
},
|
72
81
|
"engines": {
|
73
82
|
"node": ">= 18"
|