@tolgee/cli 1.1.0 → 1.1.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/README.md +11 -8
- package/dist/client/errors.js +1 -5
- package/dist/client/export.js +1 -4
- package/dist/client/import.js +5 -11
- package/dist/client/index.js +17 -23
- package/dist/client/internal/requester.js +14 -20
- package/dist/client/internal/schema.generated.js +1 -2
- package/dist/client/internal/schema.utils.js +1 -2
- package/dist/client/languages.js +1 -4
- package/dist/client/project.js +1 -4
- package/dist/commands/extract/check.js +11 -13
- package/dist/commands/extract/print.js +10 -12
- package/dist/commands/extract.js +8 -13
- package/dist/commands/login.js +16 -22
- package/dist/commands/pull.js +12 -14
- package/dist/commands/push.js +28 -30
- package/dist/commands/sync/compare.js +18 -23
- package/dist/commands/sync/sync.js +34 -39
- package/dist/commands/sync/syncUtils.js +10 -18
- package/dist/config/credentials.js +16 -25
- package/dist/config/tolgeerc.js +11 -14
- package/dist/constants.js +11 -18
- package/dist/extractor/extractor.js +13 -19
- package/dist/extractor/index.js +1 -2
- package/dist/extractor/machines/comments.js +10 -15
- package/dist/extractor/machines/react.js +36 -41
- package/dist/extractor/machines/shared/comments.js +3 -6
- package/dist/extractor/machines/shared/properties.js +13 -15
- package/dist/extractor/machines/svelte.js +30 -35
- package/dist/extractor/runner.js +8 -16
- package/dist/extractor/tokenizer.js +20 -21
- package/dist/extractor/warnings.js +9 -14
- package/dist/extractor/worker.js +23 -28
- package/dist/index.js +53 -58
- package/dist/options.js +14 -17
- package/dist/utils/ask.js +4 -12
- package/dist/utils/configPath.js +10 -10
- package/dist/utils/deferred.js +1 -5
- package/dist/utils/logger.js +8 -19
- package/dist/utils/moduleLoader.js +7 -15
- package/dist/utils/overwriteDir.js +13 -17
- package/dist/utils/zip.js +11 -16
- package/package.json +33 -30
package/dist/index.js
CHANGED
@@ -1,26 +1,21 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
const push_1 = __importDefault(require("./commands/push"));
|
18
|
-
const pull_1 = __importDefault(require("./commands/pull"));
|
19
|
-
const extract_1 = __importDefault(require("./commands/extract"));
|
20
|
-
const compare_1 = __importDefault(require("./commands/sync/compare"));
|
21
|
-
const sync_1 = __importDefault(require("./commands/sync/sync"));
|
2
|
+
import { Command } from 'commander';
|
3
|
+
import ansi from 'ansi-colors';
|
4
|
+
import { getApiKey, savePak, savePat } from './config/credentials.js';
|
5
|
+
import loadTolgeeRc from './config/tolgeerc.js';
|
6
|
+
import RestClient from './client/index.js';
|
7
|
+
import { HttpError } from './client/errors.js';
|
8
|
+
import { setDebug, isDebugEnabled, debug, info, error, } from './utils/logger.js';
|
9
|
+
import { API_KEY_OPT, API_URL_OPT, PROJECT_ID_OPT } from './options.js';
|
10
|
+
import { API_KEY_PAK_PREFIX, API_KEY_PAT_PREFIX, VERSION, } from './constants.js';
|
11
|
+
import { Login, Logout } from './commands/login.js';
|
12
|
+
import PushCommand from './commands/push.js';
|
13
|
+
import PullCommand from './commands/pull.js';
|
14
|
+
import ExtractCommand from './commands/extract.js';
|
15
|
+
import CompareCommand from './commands/sync/compare.js';
|
16
|
+
import SyncCommand from './commands/sync/sync.js';
|
22
17
|
const NO_KEY_COMMANDS = ['login', 'logout', 'extract'];
|
23
|
-
|
18
|
+
ansi.enabled = process.stdout.isTTY;
|
24
19
|
function topLevelName(command) {
|
25
20
|
return command.parent && command.parent.parent
|
26
21
|
? topLevelName(command.parent)
|
@@ -33,30 +28,30 @@ async function loadApiKey(cmd) {
|
|
33
28
|
return;
|
34
29
|
// Attempt to load --api-key from config store if not specified
|
35
30
|
// This is not done as part of the init routine or via the mandatory flag, as this is dependent on the API URL.
|
36
|
-
const key = await
|
31
|
+
const key = await getApiKey(opts.apiUrl, opts.projectId);
|
37
32
|
// No key in store, stop here.
|
38
33
|
if (!key)
|
39
34
|
return;
|
40
35
|
cmd.setOptionValue('apiKey', key);
|
41
36
|
program.setOptionValue('_removeApiKeyFromStore', () => {
|
42
|
-
if (key.startsWith(
|
43
|
-
|
37
|
+
if (key.startsWith(API_KEY_PAT_PREFIX)) {
|
38
|
+
savePat(opts.apiUrl);
|
44
39
|
}
|
45
40
|
else {
|
46
|
-
|
41
|
+
savePak(opts.apiUrl, opts.projectId);
|
47
42
|
}
|
48
43
|
});
|
49
44
|
}
|
50
45
|
function loadProjectId(cmd) {
|
51
46
|
const opts = cmd.optsWithGlobals();
|
52
|
-
if (opts.apiKey
|
47
|
+
if (opts.apiKey?.startsWith(API_KEY_PAK_PREFIX)) {
|
53
48
|
// Parse the key and ensure we can access the specified Project ID
|
54
|
-
const projectId =
|
49
|
+
const projectId = RestClient.projectIdFromKey(opts.apiKey);
|
55
50
|
program.setOptionValue('projectId', projectId);
|
56
51
|
if (opts.projectId !== -1 && opts.projectId !== projectId) {
|
57
|
-
|
58
|
-
|
59
|
-
|
52
|
+
error('The specified API key cannot be used to perform operations on the specified project.');
|
53
|
+
info(`The API key you specified is tied to project #${projectId}, you tried to perform operations on project #${opts.projectId}.`);
|
54
|
+
info('Learn more about how API keys in Tolgee work here: https://tolgee.io/platform/account_settings/api_keys_and_pat_tokens');
|
60
55
|
process.exit(1);
|
61
56
|
}
|
62
57
|
}
|
@@ -64,12 +59,12 @@ function loadProjectId(cmd) {
|
|
64
59
|
function validateOptions(cmd) {
|
65
60
|
const opts = cmd.optsWithGlobals();
|
66
61
|
if (opts.projectId === -1) {
|
67
|
-
|
68
|
-
|
62
|
+
error('No Project ID have been specified. You must either provide one via --project-id, or by setting up a `.tolgeerc` file.');
|
63
|
+
info('Learn more about configuring the CLI here: https://tolgee.io/tolgee-cli/project-configuration');
|
69
64
|
process.exit(1);
|
70
65
|
}
|
71
66
|
if (!opts.apiKey) {
|
72
|
-
|
67
|
+
error('No API key has been provided. You must either provide one via --api-key, or login via `tolgee login`.');
|
73
68
|
process.exit(1);
|
74
69
|
}
|
75
70
|
}
|
@@ -79,7 +74,7 @@ async function preHandler(prog, cmd) {
|
|
79
74
|
loadProjectId(cmd);
|
80
75
|
validateOptions(cmd);
|
81
76
|
const opts = cmd.optsWithGlobals();
|
82
|
-
const client = new
|
77
|
+
const client = new RestClient({
|
83
78
|
apiUrl: opts.apiUrl,
|
84
79
|
apiKey: opts.apiKey,
|
85
80
|
projectId: opts.projectId,
|
@@ -87,28 +82,28 @@ async function preHandler(prog, cmd) {
|
|
87
82
|
cmd.setOptionValue('client', client);
|
88
83
|
}
|
89
84
|
// Apply verbosity
|
90
|
-
|
85
|
+
setDebug(prog.opts().verbose);
|
91
86
|
}
|
92
|
-
const program = new
|
93
|
-
.version(
|
94
|
-
.configureOutput({ writeErr:
|
87
|
+
const program = new Command('tolgee')
|
88
|
+
.version(VERSION)
|
89
|
+
.configureOutput({ writeErr: error })
|
95
90
|
.description('Command Line Interface to interact with the Tolgee Platform')
|
96
91
|
.option('-v, --verbose', 'Enable verbose logging.')
|
97
92
|
.hook('preAction', preHandler);
|
98
93
|
// Global options
|
99
|
-
program.addOption(
|
100
|
-
program.addOption(
|
101
|
-
program.addOption(
|
94
|
+
program.addOption(API_URL_OPT);
|
95
|
+
program.addOption(API_KEY_OPT);
|
96
|
+
program.addOption(PROJECT_ID_OPT);
|
102
97
|
// Register commands
|
103
|
-
program.addCommand(
|
104
|
-
program.addCommand(
|
105
|
-
program.addCommand(
|
106
|
-
program.addCommand(
|
107
|
-
program.addCommand(
|
108
|
-
program.addCommand(
|
109
|
-
program.addCommand(
|
98
|
+
program.addCommand(Login);
|
99
|
+
program.addCommand(Logout);
|
100
|
+
program.addCommand(PushCommand);
|
101
|
+
program.addCommand(PullCommand);
|
102
|
+
program.addCommand(ExtractCommand);
|
103
|
+
program.addCommand(CompareCommand);
|
104
|
+
program.addCommand(SyncCommand);
|
110
105
|
async function loadConfig() {
|
111
|
-
const tgConfig = await (
|
106
|
+
const tgConfig = await loadTolgeeRc();
|
112
107
|
if (tgConfig) {
|
113
108
|
for (const [key, value] of Object.entries(tgConfig)) {
|
114
109
|
program.setOptionValue(key, value);
|
@@ -116,26 +111,26 @@ async function loadConfig() {
|
|
116
111
|
}
|
117
112
|
}
|
118
113
|
async function handleHttpError(e) {
|
119
|
-
|
120
|
-
|
121
|
-
|
114
|
+
error('An error occurred while requesting the API.');
|
115
|
+
error(`${e.request.method} ${e.request.url}`);
|
116
|
+
error(e.getErrorText());
|
122
117
|
// Remove token from store if necessary
|
123
118
|
if (e.response.status === 401) {
|
124
119
|
const removeFn = program.getOptionValue('_removeApiKeyFromStore');
|
125
120
|
if (removeFn) {
|
126
|
-
|
121
|
+
info('Removing the API key from the authentication store.');
|
127
122
|
removeFn();
|
128
123
|
}
|
129
124
|
}
|
130
125
|
// Print server output for server errors
|
131
|
-
if (
|
126
|
+
if (isDebugEnabled()) {
|
132
127
|
// We cannot parse the response as JSON and pull error codes here as we may be here due to a 5xx error:
|
133
128
|
// by nature 5xx class errors can happen for a lot of reasons (e.g. upstream issues, server issues,
|
134
129
|
// catastrophic failure) which means the output is completely unpredictable. While some errors are
|
135
130
|
// formatted by the Tolgee server, reality is there's a huge chance the 5xx error hasn't been raised
|
136
131
|
// by Tolgee's error handler.
|
137
132
|
const res = await e.response.text();
|
138
|
-
|
133
|
+
debug(`Server response:\n\n---\n${res}\n---`);
|
139
134
|
}
|
140
135
|
}
|
141
136
|
async function run() {
|
@@ -144,7 +139,7 @@ async function run() {
|
|
144
139
|
await program.parseAsync();
|
145
140
|
}
|
146
141
|
catch (e) {
|
147
|
-
if (e instanceof
|
142
|
+
if (e instanceof HttpError) {
|
148
143
|
await handleHttpError(e);
|
149
144
|
process.exit(1);
|
150
145
|
}
|
@@ -152,8 +147,8 @@ async function run() {
|
|
152
147
|
// - The error should be handled here but isn't
|
153
148
|
// - The error should be handled in the command but isn't
|
154
149
|
// - Something went wrong with the code
|
155
|
-
|
156
|
-
|
150
|
+
error('An unexpected error occurred while running the command.');
|
151
|
+
error('Please report this to our issue tracker: https://github.com/tolgee/tolgee-cli/issues');
|
157
152
|
console.log(e.stack);
|
158
153
|
process.exit(1);
|
159
154
|
}
|
package/dist/options.js
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
const path_1 = require("path");
|
6
|
-
const commander_1 = require("commander");
|
7
|
-
const constants_1 = require("./constants");
|
1
|
+
import { existsSync } from 'fs';
|
2
|
+
import { resolve } from 'path';
|
3
|
+
import { Option, InvalidArgumentError } from 'commander';
|
4
|
+
import { DEFAULT_API_URL } from './constants.js';
|
8
5
|
function parseProjectId(v) {
|
9
6
|
const val = Number(v);
|
10
7
|
if (!Number.isInteger(val) || val < 1) {
|
11
|
-
throw new
|
8
|
+
throw new InvalidArgumentError('Not a valid project ID.');
|
12
9
|
}
|
13
10
|
return val;
|
14
11
|
}
|
@@ -17,21 +14,21 @@ function parseUrlArgument(v) {
|
|
17
14
|
return new URL(v);
|
18
15
|
}
|
19
16
|
catch {
|
20
|
-
throw new
|
17
|
+
throw new InvalidArgumentError('Malformed URL.');
|
21
18
|
}
|
22
19
|
}
|
23
20
|
function parsePath(v) {
|
24
|
-
const path =
|
25
|
-
if (!
|
26
|
-
throw new
|
21
|
+
const path = resolve(v);
|
22
|
+
if (!existsSync(path)) {
|
23
|
+
throw new InvalidArgumentError(`The specified path "${v}" does not exist.`);
|
27
24
|
}
|
28
25
|
return path;
|
29
26
|
}
|
30
|
-
|
31
|
-
|
27
|
+
export const API_KEY_OPT = new Option('-ak, --api-key <key>', 'Tolgee API Key. Can be a Project API Key or a Personal Access Token.').env('TOLGEE_API_KEY');
|
28
|
+
export const PROJECT_ID_OPT = new Option('-p, --project-id <id>', 'Project ID. Only required when using a Personal Access Token.')
|
32
29
|
.default(-1)
|
33
30
|
.argParser(parseProjectId);
|
34
|
-
|
35
|
-
.default(
|
31
|
+
export const API_URL_OPT = new Option('-au, --api-url <url>', 'The url of Tolgee API.')
|
32
|
+
.default(DEFAULT_API_URL)
|
36
33
|
.argParser(parseUrlArgument);
|
37
|
-
|
34
|
+
export const EXTRACTOR = new Option('-e, --extractor <extractor>', `A path to a custom extractor to use instead of the default one.`).argParser(parsePath);
|
package/dist/utils/ask.js
CHANGED
@@ -1,13 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.askBoolean = exports.askString = void 0;
|
7
|
-
const readline_1 = __importDefault(require("readline")); // readline/promises is Node 17, currently supporting Node 16+
|
8
|
-
async function askString(question) {
|
1
|
+
import readline from 'readline'; // readline/promises is Node 17, currently supporting Node 16+
|
2
|
+
export async function askString(question) {
|
9
3
|
return new Promise((resolve) => {
|
10
|
-
const rl =
|
4
|
+
const rl = readline.createInterface({
|
11
5
|
input: process.stdin,
|
12
6
|
output: process.stdout,
|
13
7
|
});
|
@@ -17,8 +11,7 @@ async function askString(question) {
|
|
17
11
|
});
|
18
12
|
});
|
19
13
|
}
|
20
|
-
|
21
|
-
async function askBoolean(question, def = false) {
|
14
|
+
export async function askBoolean(question, def = false) {
|
22
15
|
const yn = def === true ? '[Y/n]' : '[y/N]';
|
23
16
|
let res = def;
|
24
17
|
const str = await askString(`${question} ${yn}`);
|
@@ -31,4 +24,3 @@ async function askBoolean(question, def = false) {
|
|
31
24
|
}
|
32
25
|
return res;
|
33
26
|
}
|
34
|
-
exports.askBoolean = askBoolean;
|
package/dist/utils/configPath.js
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
import { homedir } from 'os';
|
2
|
+
import { resolve } from 'path';
|
3
|
+
export default function getConfigPath() {
|
4
|
+
if (process.env.TOLGEE_CLI_CONFIG_PATH) {
|
5
|
+
return process.env.TOLGEE_CLI_CONFIG_PATH;
|
6
|
+
}
|
6
7
|
switch (process.platform) {
|
7
8
|
case 'win32':
|
8
|
-
return
|
9
|
+
return resolve(process.env.APPDATA, 'tolgee');
|
9
10
|
case 'darwin':
|
10
|
-
return
|
11
|
+
return resolve(homedir(), 'Library', 'Application Support', 'tolgee');
|
11
12
|
default:
|
12
13
|
return process.env.XDG_CONFIG_HOME
|
13
|
-
?
|
14
|
-
:
|
14
|
+
? resolve(process.env.XDG_CONFIG_HOME, 'tolgee')
|
15
|
+
: resolve(homedir(), '.config', 'tolgee');
|
15
16
|
}
|
16
17
|
}
|
17
|
-
exports.default = getConfigPath;
|
package/dist/utils/deferred.js
CHANGED
@@ -1,11 +1,7 @@
|
|
1
|
-
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.createDeferred = void 0;
|
4
|
-
function createDeferred() {
|
1
|
+
export function createDeferred() {
|
5
2
|
const deferred = {};
|
6
3
|
deferred.promise = new Promise((resolve, reject) => {
|
7
4
|
Object.assign(deferred, { resolve: resolve, reject: reject });
|
8
5
|
});
|
9
6
|
return deferred;
|
10
7
|
}
|
11
|
-
exports.createDeferred = createDeferred;
|
package/dist/utils/logger.js
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.loading = exports.error = exports.warn = exports.success = exports.info = exports.debug = exports.isDebugEnabled = exports.setDebug = void 0;
|
4
1
|
const SYMBOLS = [' 🐁', ' 🐁 ', ' 🐁 ', '🐁 '];
|
5
2
|
let debugEnabled = false;
|
6
3
|
/**
|
@@ -8,66 +5,59 @@ let debugEnabled = false;
|
|
8
5
|
*
|
9
6
|
* @param enabled Whether debugging messages should be logged.
|
10
7
|
*/
|
11
|
-
function setDebug(enabled) {
|
8
|
+
export function setDebug(enabled) {
|
12
9
|
debugEnabled = enabled;
|
13
10
|
}
|
14
|
-
exports.setDebug = setDebug;
|
15
11
|
/**
|
16
12
|
* Gets the current status of debug logging.
|
17
13
|
*
|
18
14
|
* @returns Whether debugging is enabled.
|
19
15
|
*/
|
20
|
-
function isDebugEnabled() {
|
16
|
+
export function isDebugEnabled() {
|
21
17
|
return debugEnabled;
|
22
18
|
}
|
23
|
-
exports.isDebugEnabled = isDebugEnabled;
|
24
19
|
/**
|
25
20
|
* Logs a debug message to the console if debugging is enabled.
|
26
21
|
*
|
27
22
|
* @param msg The message.
|
28
23
|
*/
|
29
|
-
function debug(msg) {
|
24
|
+
export function debug(msg) {
|
30
25
|
if (debugEnabled) {
|
31
26
|
console.log(`⚪ ${msg}`);
|
32
27
|
}
|
33
28
|
}
|
34
|
-
exports.debug = debug;
|
35
29
|
/**
|
36
30
|
* Logs an informative message to the console.
|
37
31
|
*
|
38
32
|
* @param msg The message.
|
39
33
|
*/
|
40
|
-
function info(msg) {
|
34
|
+
export function info(msg) {
|
41
35
|
console.log(`🔵 ${msg}`);
|
42
36
|
}
|
43
|
-
exports.info = info;
|
44
37
|
/**
|
45
38
|
* Logs a success to the console.
|
46
39
|
*
|
47
40
|
* @param msg The message.
|
48
41
|
*/
|
49
|
-
function success(msg) {
|
42
|
+
export function success(msg) {
|
50
43
|
console.log(`✅ ${msg}`);
|
51
44
|
}
|
52
|
-
exports.success = success;
|
53
45
|
/**
|
54
46
|
* Logs a warning message to the console.
|
55
47
|
*
|
56
48
|
* @param msg The message.
|
57
49
|
*/
|
58
|
-
function warn(msg) {
|
50
|
+
export function warn(msg) {
|
59
51
|
console.log(`🟡 ${msg}`);
|
60
52
|
}
|
61
|
-
exports.warn = warn;
|
62
53
|
/**
|
63
54
|
* Logs an error message to the console.
|
64
55
|
*
|
65
56
|
* @param msg The message.
|
66
57
|
*/
|
67
|
-
function error(msg) {
|
58
|
+
export function error(msg) {
|
68
59
|
console.log(`🔴 ${msg}`);
|
69
60
|
}
|
70
|
-
exports.error = error;
|
71
61
|
/**
|
72
62
|
* Shows a loading indicator for a Promise until it resolves.
|
73
63
|
*
|
@@ -75,7 +65,7 @@ exports.error = error;
|
|
75
65
|
* @param promise The promise to watch.
|
76
66
|
* @returns The promise passed in parameter. Useful for decorating without using a buffer variable.
|
77
67
|
*/
|
78
|
-
function loading(comment, promise) {
|
68
|
+
export function loading(comment, promise) {
|
79
69
|
if (!process.stdout.isTTY) {
|
80
70
|
// Simple stdout without animations
|
81
71
|
process.stdout.write(comment);
|
@@ -96,4 +86,3 @@ function loading(comment, promise) {
|
|
96
86
|
});
|
97
87
|
return promise;
|
98
88
|
}
|
99
|
-
exports.loading = loading;
|
@@ -1,16 +1,9 @@
|
|
1
|
-
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.loadModule = void 0;
|
4
|
-
const path_1 = require("path");
|
1
|
+
import { extname } from 'path';
|
5
2
|
let tsService;
|
6
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
7
|
-
function realImport(file) {
|
8
|
-
return eval('import(file)');
|
9
|
-
}
|
10
3
|
async function registerTsNode() {
|
11
4
|
if (!tsService) {
|
12
5
|
try {
|
13
|
-
const tsNode =
|
6
|
+
const tsNode = await import('ts-node');
|
14
7
|
tsService = tsNode.register({ compilerOptions: { module: 'CommonJS' } });
|
15
8
|
}
|
16
9
|
catch (e) {
|
@@ -22,23 +15,22 @@ async function registerTsNode() {
|
|
22
15
|
}
|
23
16
|
}
|
24
17
|
async function importTypeScript(file) {
|
25
|
-
if ((
|
26
|
-
return
|
18
|
+
if (extname(import.meta.url) === '.ts') {
|
19
|
+
return import(file);
|
27
20
|
}
|
28
21
|
await registerTsNode();
|
29
22
|
tsService.enabled(true);
|
30
|
-
const mdl = await
|
23
|
+
const mdl = await import(file);
|
31
24
|
tsService.enabled(false);
|
32
25
|
return mdl;
|
33
26
|
}
|
34
|
-
async function loadModule(module) {
|
27
|
+
export async function loadModule(module) {
|
35
28
|
if (module.endsWith('.ts')) {
|
36
29
|
return importTypeScript(module);
|
37
30
|
}
|
38
|
-
const mdl = await
|
31
|
+
const mdl = await import(module);
|
39
32
|
if (mdl.default?.default) {
|
40
33
|
return mdl.default;
|
41
34
|
}
|
42
35
|
return mdl;
|
43
36
|
}
|
44
|
-
exports.loadModule = loadModule;
|
@@ -1,30 +1,27 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
const ask_1 = require("./ask");
|
7
|
-
const logger_1 = require("./logger");
|
8
|
-
async function overwriteDir(path, overwrite) {
|
1
|
+
import { resolve } from 'path';
|
2
|
+
import { stat, rm, mkdir } from 'fs/promises';
|
3
|
+
import { askBoolean } from './ask.js';
|
4
|
+
import { warn, error } from './logger.js';
|
5
|
+
export async function overwriteDir(path, overwrite) {
|
9
6
|
try {
|
10
|
-
const stats = await
|
7
|
+
const stats = await stat(path);
|
11
8
|
if (!stats.isDirectory()) {
|
12
|
-
|
9
|
+
error('The specified path already exists and is not a directory.');
|
13
10
|
process.exit(1);
|
14
11
|
}
|
15
12
|
if (!overwrite) {
|
16
13
|
if (!process.stdout.isTTY) {
|
17
|
-
|
14
|
+
error('The specified path already exists.');
|
18
15
|
process.exit(1);
|
19
16
|
}
|
20
|
-
|
21
|
-
const userOverwrite = await
|
17
|
+
warn(`The specified path ${resolve(path)} already exists.`);
|
18
|
+
const userOverwrite = await askBoolean('Do you want to overwrite data? *BE CAREFUL, ALL THE CONTENTS OF THE DESTINATION FOLDER WILL BE DESTROYED*.');
|
22
19
|
if (!userOverwrite) {
|
23
|
-
|
20
|
+
error('Aborting.');
|
24
21
|
process.exit(1);
|
25
22
|
}
|
26
23
|
// Purge data as requested.
|
27
|
-
await
|
24
|
+
await rm(path, { recursive: true });
|
28
25
|
}
|
29
26
|
}
|
30
27
|
catch (e) {
|
@@ -33,6 +30,5 @@ async function overwriteDir(path, overwrite) {
|
|
33
30
|
}
|
34
31
|
}
|
35
32
|
// Create the directory
|
36
|
-
await
|
33
|
+
await mkdir(path, { recursive: true });
|
37
34
|
}
|
38
|
-
exports.overwriteDir = overwriteDir;
|
package/dist/utils/zip.js
CHANGED
@@ -1,10 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
const promises_1 = require("fs/promises");
|
6
|
-
const path_1 = require("path");
|
7
|
-
const yauzl_1 = require("yauzl");
|
1
|
+
import { createWriteStream } from 'fs';
|
2
|
+
import { mkdir } from 'fs/promises';
|
3
|
+
import { join, dirname } from 'path';
|
4
|
+
import { fromBuffer } from 'yauzl';
|
8
5
|
const ZIP_PARSER_OPTS = {
|
9
6
|
strictFileNames: true,
|
10
7
|
decodeStrings: true,
|
@@ -14,7 +11,7 @@ function dumpFile(zip, entry, dest) {
|
|
14
11
|
zip.openReadStream(entry, (err, stream) => {
|
15
12
|
if (err)
|
16
13
|
throw err;
|
17
|
-
const writeStream =
|
14
|
+
const writeStream = createWriteStream(dest);
|
18
15
|
stream.pipe(writeStream);
|
19
16
|
// Unlock reading loop
|
20
17
|
stream.on('end', () => zip.readEntry());
|
@@ -26,11 +23,11 @@ function dumpFile(zip, entry, dest) {
|
|
26
23
|
* @param zipBlob The ZIP blob
|
27
24
|
* @param dest The destination path
|
28
25
|
*/
|
29
|
-
function unzipBuffer(zipBlob, dest) {
|
26
|
+
export function unzipBuffer(zipBlob, dest) {
|
30
27
|
return new Promise((resolve, reject) => {
|
31
28
|
zipBlob.arrayBuffer().then((buffer) => {
|
32
29
|
const nodeBuffer = Buffer.from(buffer);
|
33
|
-
|
30
|
+
fromBuffer(nodeBuffer, ZIP_PARSER_OPTS, (err, zip) => {
|
34
31
|
if (err) {
|
35
32
|
return reject(err);
|
36
33
|
}
|
@@ -39,14 +36,13 @@ function unzipBuffer(zipBlob, dest) {
|
|
39
36
|
});
|
40
37
|
});
|
41
38
|
}
|
42
|
-
exports.unzipBuffer = unzipBuffer;
|
43
39
|
/**
|
44
40
|
* Unzips a ZIP file loaded in memory to a destination on disk.
|
45
41
|
*
|
46
42
|
* @param file The ZIP file
|
47
43
|
* @param dest The destination path
|
48
44
|
*/
|
49
|
-
function unzip(zip, dest) {
|
45
|
+
export function unzip(zip, dest) {
|
50
46
|
// Enforce expected & security options.
|
51
47
|
// Lazy entries is what this reader is based upon.
|
52
48
|
// Decode strings ensures file paths are sanitized by yazul
|
@@ -68,11 +64,11 @@ function unzip(zip, dest) {
|
|
68
64
|
zip.readEntry();
|
69
65
|
return;
|
70
66
|
}
|
71
|
-
const entryPath =
|
67
|
+
const entryPath = join(dest, entry.fileName);
|
72
68
|
// Handle directory creation
|
73
|
-
const entryDirName =
|
69
|
+
const entryDirName = dirname(entryPath);
|
74
70
|
if (!seenDirectories.has(entryDirName)) {
|
75
|
-
|
71
|
+
mkdir(entryDirName, { recursive: true }).then(() => dumpFile(zip, entry, entryPath));
|
76
72
|
}
|
77
73
|
else {
|
78
74
|
dumpFile(zip, entry, entryPath);
|
@@ -80,4 +76,3 @@ function unzip(zip, dest) {
|
|
80
76
|
});
|
81
77
|
});
|
82
78
|
}
|
83
|
-
exports.unzip = unzip;
|