esa-cli 1.0.10 → 1.0.11
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 +206 -22
- package/bin/enter.cjs +45 -12
- package/dist/bin/enter.cjs +45 -12
- package/dist/commands/commit/index.js +5 -4
- package/dist/commands/deployments/delete.js +1 -1
- package/dist/commands/deployments/list.js +1 -1
- package/dist/commands/dev/build.js +4 -1
- package/dist/commands/dev/doProcess.js +94 -36
- package/dist/commands/domain/add.js +1 -1
- package/dist/commands/domain/delete.js +2 -3
- package/dist/commands/domain/list.js +1 -1
- package/dist/commands/init/helper.js +12 -8
- package/dist/commands/init/index.js +3 -4
- package/dist/commands/login/index.js +9 -5
- package/dist/commands/logout.js +3 -3
- package/dist/commands/route/add.js +1 -1
- package/dist/commands/route/delete.js +1 -1
- package/dist/commands/route/list.js +1 -1
- package/dist/commands/routine/delete.js +1 -2
- package/dist/commands/routine/list.js +1 -1
- package/dist/commands/site/list.js +1 -1
- package/dist/commands/utils.js +9 -3
- package/dist/components/mutiSelectTable.js +16 -83
- package/dist/components/routeBuilder.js +30 -54
- package/dist/components/selectInput.js +27 -13
- package/dist/docs/Commands_en.md +14 -2
- package/dist/docs/Commands_zh_CN.md +11 -1
- package/dist/i18n/locales.json +1 -1
- package/dist/index.js +8 -3
- package/dist/libs/api.js +0 -8
- package/dist/libs/logger.js +7 -2
- package/dist/utils/fileMd5.js +13 -3
- package/dist/utils/fileUtils/base.js +14 -18
- package/dist/utils/fileUtils/index.js +20 -0
- package/package.json +18 -20
- package/zh_CN.md +2 -2
- package/dist/components/descriptionInput.js +0 -38
- package/dist/components/filterSelector.js +0 -132
- package/dist/components/selectItem.js +0 -6
- package/dist/components/yesNoPrompt.js +0 -9
|
@@ -17,7 +17,7 @@ const listDomain = {
|
|
|
17
17
|
command: 'list',
|
|
18
18
|
describe: `🔍 ${t('domain_list_describe').d('List all related domains')}`,
|
|
19
19
|
handler: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
-
handleListDomains();
|
|
20
|
+
yield handleListDomains();
|
|
21
21
|
})
|
|
22
22
|
};
|
|
23
23
|
export default listDomain;
|
|
@@ -257,7 +257,7 @@ export const configProjectName = (initParams) => __awaiter(void 0, void 0, void
|
|
|
257
257
|
return true;
|
|
258
258
|
}
|
|
259
259
|
}));
|
|
260
|
-
initParams.name = name;
|
|
260
|
+
initParams.name = name || defaultName;
|
|
261
261
|
});
|
|
262
262
|
export const configCategory = (initParams) => __awaiter(void 0, void 0, void 0, function* () {
|
|
263
263
|
if (initParams.category || initParams.framework || initParams.template) {
|
|
@@ -429,7 +429,7 @@ export const applyFileEdits = (initParams) => __awaiter(void 0, void 0, void 0,
|
|
|
429
429
|
// Very small glob subset: *, ?, {a,b,c}
|
|
430
430
|
let escaped = pattern
|
|
431
431
|
.replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&') // escape regex specials first
|
|
432
|
-
.replace(
|
|
432
|
+
.replace(/\*/g, '.*')
|
|
433
433
|
.replace(/\\\?/g, '.');
|
|
434
434
|
// restore and convert {a,b} to (a|b)
|
|
435
435
|
escaped = escaped.replace(/\\\{([^}]+)\\\}/g, (_, inner) => {
|
|
@@ -455,7 +455,10 @@ export const applyFileEdits = (initParams) => __awaiter(void 0, void 0, void 0,
|
|
|
455
455
|
let matchedFiles = [];
|
|
456
456
|
if (edit.matchType === 'exact') {
|
|
457
457
|
const absExact = path.join(targetPath, edit.match);
|
|
458
|
-
matchedFiles =
|
|
458
|
+
matchedFiles =
|
|
459
|
+
fs.existsSync(absExact) || edit.createIfMissing !== false
|
|
460
|
+
? [edit.match]
|
|
461
|
+
: [];
|
|
459
462
|
}
|
|
460
463
|
else if (edit.matchType === 'glob') {
|
|
461
464
|
const regex = toRegexFromGlob(edit.match);
|
|
@@ -482,8 +485,8 @@ export const applyFileEdits = (initParams) => __awaiter(void 0, void 0, void 0,
|
|
|
482
485
|
const abs = path.join(targetPath, rel);
|
|
483
486
|
if (payload == null)
|
|
484
487
|
continue;
|
|
485
|
-
if (!fs.existsSync(abs))
|
|
486
|
-
continue;
|
|
488
|
+
if (!fs.existsSync(abs) && edit.createIfMissing === false)
|
|
489
|
+
continue;
|
|
487
490
|
fs.ensureDirSync(path.dirname(abs));
|
|
488
491
|
fs.writeFileSync(abs, payload, 'utf-8');
|
|
489
492
|
}
|
|
@@ -497,7 +500,7 @@ export const applyFileEdits = (initParams) => __awaiter(void 0, void 0, void 0,
|
|
|
497
500
|
}
|
|
498
501
|
});
|
|
499
502
|
export const installESACli = (initParams) => __awaiter(void 0, void 0, void 0, function* () {
|
|
500
|
-
if (
|
|
503
|
+
if (typeof initParams.installEsaCli !== 'boolean') {
|
|
501
504
|
const install = (yield promptParameter({
|
|
502
505
|
type: 'confirm',
|
|
503
506
|
question: 'Do you want to install esa-cli as a dev dependency?',
|
|
@@ -567,7 +570,7 @@ export const initGit = (initParams) => __awaiter(void 0, void 0, void 0, functio
|
|
|
567
570
|
log.step('You have not installed Git, Git skipped');
|
|
568
571
|
return true;
|
|
569
572
|
}
|
|
570
|
-
if (
|
|
573
|
+
if (typeof initParams.git !== 'boolean') {
|
|
571
574
|
const initGit = (yield promptParameter({
|
|
572
575
|
type: 'confirm',
|
|
573
576
|
question: t('init_git').d('Do you want to init git in your project?'),
|
|
@@ -612,7 +615,8 @@ export function getGitVersion() {
|
|
|
612
615
|
}
|
|
613
616
|
export function isGitInstalled() {
|
|
614
617
|
return __awaiter(this, void 0, void 0, function* () {
|
|
615
|
-
|
|
618
|
+
const gitVersion = yield getGitVersion();
|
|
619
|
+
return gitVersion !== '' && gitVersion !== null;
|
|
616
620
|
});
|
|
617
621
|
}
|
|
618
622
|
/**
|
|
@@ -57,8 +57,7 @@ const init = {
|
|
|
57
57
|
})
|
|
58
58
|
.option('install-esa-cli', {
|
|
59
59
|
describe: 'Install esa-cli as a dev dependency',
|
|
60
|
-
type: 'boolean'
|
|
61
|
-
default: false
|
|
60
|
+
type: 'boolean'
|
|
62
61
|
});
|
|
63
62
|
},
|
|
64
63
|
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -67,7 +66,7 @@ const init = {
|
|
|
67
66
|
})
|
|
68
67
|
};
|
|
69
68
|
export default init;
|
|
70
|
-
const handleInit = (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
+
export const handleInit = (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
70
|
yield checkAndUpdatePackage('esa-template');
|
|
72
71
|
const initParams = getInitParamsFromArgv(argv);
|
|
73
72
|
yield create(initParams);
|
|
@@ -96,7 +95,7 @@ const config = (initParams) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
96
95
|
});
|
|
97
96
|
const deploy = (initParams) => __awaiter(void 0, void 0, void 0, function* () {
|
|
98
97
|
intro(`Deploy an application with ESA ${chalk.gray('Step 3 of 3')}`);
|
|
99
|
-
if (
|
|
98
|
+
if (typeof initParams.deploy !== 'boolean') {
|
|
100
99
|
const deploy = (yield promptParameter({
|
|
101
100
|
type: 'confirm',
|
|
102
101
|
question: t('auto_deploy').d('Do you want to deploy your project?'),
|
|
@@ -66,17 +66,21 @@ const login = {
|
|
|
66
66
|
});
|
|
67
67
|
},
|
|
68
68
|
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
-
handleLogin(argv);
|
|
69
|
+
yield handleLogin(argv);
|
|
70
70
|
})
|
|
71
71
|
};
|
|
72
72
|
export default login;
|
|
73
73
|
export function handleLogin(argv) {
|
|
74
74
|
return __awaiter(this, void 0, void 0, function* () {
|
|
75
75
|
generateDefaultConfig();
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
76
|
+
const envAccessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID ||
|
|
77
|
+
process.env.ESA_ACCESS_KEY_ID;
|
|
78
|
+
const envAccessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET ||
|
|
79
|
+
process.env.ESA_ACCESS_KEY_SECRET;
|
|
80
|
+
const envSecurityToken = process.env.ALIBABA_CLOUD_SECURITY_TOKEN ||
|
|
81
|
+
process.env.ESA_SECURITY_TOKEN;
|
|
82
|
+
if (envAccessKeyId && envAccessKeySecret) {
|
|
83
|
+
const result = yield validateCredentials(envAccessKeyId, envAccessKeySecret, envSecurityToken);
|
|
80
84
|
if (result.valid) {
|
|
81
85
|
logger.log(t('login_get_credentials_from_environment_variables').d('Get credentials from environment variables'));
|
|
82
86
|
logger.success(t('login_success').d('Login success!'));
|
package/dist/commands/logout.js
CHANGED
|
@@ -16,9 +16,9 @@ const logout = {
|
|
|
16
16
|
builder: (yargs) => {
|
|
17
17
|
return yargs;
|
|
18
18
|
},
|
|
19
|
-
handler: () => {
|
|
20
|
-
handleLogout();
|
|
21
|
-
}
|
|
19
|
+
handler: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
|
+
yield handleLogout();
|
|
21
|
+
})
|
|
22
22
|
};
|
|
23
23
|
export default logout;
|
|
24
24
|
export function handleLogout() {
|
|
@@ -19,7 +19,7 @@ const listRoute = {
|
|
|
19
19
|
command: 'list',
|
|
20
20
|
describe: `🔍 ${t('route_list_describe').d('List all related routes')}`,
|
|
21
21
|
handler: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
|
-
handleListRoutes();
|
|
22
|
+
yield handleListRoutes();
|
|
23
23
|
})
|
|
24
24
|
};
|
|
25
25
|
export default listRoute;
|
|
@@ -20,13 +20,12 @@ const deleteCommand = {
|
|
|
20
20
|
.positional('projectName', {
|
|
21
21
|
describe: t('delete_routineName_positional_describe').d('The name of the project to delete'),
|
|
22
22
|
type: 'string',
|
|
23
|
-
array: true,
|
|
24
23
|
demandOption: true
|
|
25
24
|
})
|
|
26
25
|
.usage(`${t('common_usage').d('Usage')}: $0 delete <projectName>`);
|
|
27
26
|
},
|
|
28
27
|
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
-
handleDelete(argv);
|
|
28
|
+
yield handleDelete(argv);
|
|
30
29
|
})
|
|
31
30
|
};
|
|
32
31
|
export default deleteCommand;
|
package/dist/commands/utils.js
CHANGED
|
@@ -80,9 +80,15 @@ export function checkIsLoginSuccess() {
|
|
|
80
80
|
return __awaiter(this, void 0, void 0, function* () {
|
|
81
81
|
var _a, _b, _c;
|
|
82
82
|
const cliConfig = getCliConfig();
|
|
83
|
-
let accessKeyId = process.env.
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
let accessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID ||
|
|
84
|
+
process.env.ESA_ACCESS_KEY_ID ||
|
|
85
|
+
((_a = cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId);
|
|
86
|
+
let accessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET ||
|
|
87
|
+
process.env.ESA_ACCESS_KEY_SECRET ||
|
|
88
|
+
((_b = cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret);
|
|
89
|
+
const securityToken = process.env.ALIBABA_CLOUD_SECURITY_TOKEN ||
|
|
90
|
+
process.env.ESA_SECURITY_TOKEN ||
|
|
91
|
+
((_c = cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.auth) === null || _c === void 0 ? void 0 : _c.securityToken);
|
|
86
92
|
if (accessKeyId && accessKeySecret) {
|
|
87
93
|
const result = yield validateCredentials(accessKeyId, accessKeySecret, securityToken);
|
|
88
94
|
const server = yield ApiService.getInstance();
|
|
@@ -7,89 +7,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
11
|
-
import React, { useState } from 'react';
|
|
10
|
+
import { multiselect, isCancel, cancel } from '@clack/prompts';
|
|
12
11
|
import t from '../i18n/index.js';
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const key = `${row}:${col}`;
|
|
24
|
-
setSelectedIndexes((prevSelectedIndexes) => {
|
|
25
|
-
const newSelectedIndexes = new Set(prevSelectedIndexes);
|
|
26
|
-
if (newSelectedIndexes.has(key)) {
|
|
27
|
-
newSelectedIndexes.delete(key);
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
newSelectedIndexes.add(key);
|
|
31
|
-
}
|
|
32
|
-
return newSelectedIndexes;
|
|
33
|
-
});
|
|
34
|
-
};
|
|
35
|
-
const handleSubmission = () => {
|
|
36
|
-
const selectedItems = Array.from(selectedIndexes).map((key) => {
|
|
37
|
-
const [row, col] = key.split(':').map(Number);
|
|
38
|
-
return rows[row][col];
|
|
39
|
-
});
|
|
40
|
-
onSubmit(selectedItems);
|
|
41
|
-
};
|
|
42
|
-
useInput((input, key) => {
|
|
43
|
-
if (key.leftArrow) {
|
|
44
|
-
setCursorCol((prev) => Math.max(prev - 1, 0));
|
|
45
|
-
}
|
|
46
|
-
else if (key.rightArrow) {
|
|
47
|
-
setCursorCol((prev) => Math.min(prev + 1, itemsPerRow - 1));
|
|
48
|
-
}
|
|
49
|
-
else if (key.upArrow) {
|
|
50
|
-
setCursorRow((prev) => Math.max(prev - 1, 0));
|
|
51
|
-
}
|
|
52
|
-
else if (key.downArrow) {
|
|
53
|
-
setCursorRow((prev) => Math.min(prev + 1, totalRows - 1));
|
|
54
|
-
}
|
|
55
|
-
else if (input === ' ') {
|
|
56
|
-
toggleSelect(cursorRow, cursorCol);
|
|
57
|
-
}
|
|
58
|
-
else if (key.tab) {
|
|
59
|
-
setCursorCol((prevCol) => {
|
|
60
|
-
let newCol = prevCol + 1;
|
|
61
|
-
let newRow = cursorRow;
|
|
62
|
-
if (newCol >= itemsPerRow) {
|
|
63
|
-
newCol = 0;
|
|
64
|
-
newRow = cursorRow + 1;
|
|
65
|
-
if (newRow >= totalRows) {
|
|
66
|
-
newRow = 0;
|
|
67
|
-
}
|
|
68
|
-
setCursorRow(newRow);
|
|
69
|
-
}
|
|
70
|
-
return newCol;
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
else if (key.return) {
|
|
74
|
-
handleSubmission();
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
return (React.createElement(Box, { flexDirection: "column" },
|
|
78
|
-
rows.map((rowItems, row) => (React.createElement(Box, { key: row, flexDirection: "row" }, rowItems.map((item, col) => (React.createElement(Box, { key: `${row}:${col}`, width: boxWidth },
|
|
79
|
-
React.createElement(Text, { color: cursorRow === row && cursorCol === col ? 'green' : undefined },
|
|
80
|
-
selectedIndexes.has(`${row}:${col}`) ? '✅' : ' ',
|
|
81
|
-
item.label))))))),
|
|
82
|
-
React.createElement(Box, { flexDirection: "column" },
|
|
83
|
-
React.createElement(Text, null,
|
|
84
|
-
"\uD83D\uDD14",
|
|
85
|
-
' ',
|
|
86
|
-
t('deploy_select_table_tip').d('Use arrow keys to move, space to select, and enter to submit.')))));
|
|
87
|
-
};
|
|
88
|
-
export const displayMultiSelectTable = (items_1, ...args_1) => __awaiter(void 0, [items_1, ...args_1], void 0, function* (items, itemsPerRow = 7, boxWidth = 25) {
|
|
89
|
-
return new Promise((resolve) => {
|
|
90
|
-
const { unmount } = render(React.createElement(MultiSelectTable, { items: items, itemsPerRow: itemsPerRow, onSubmit: (selectedItems) => {
|
|
91
|
-
unmount();
|
|
92
|
-
resolve(selectedItems.map((item) => item.label));
|
|
93
|
-
}, boxWidth: boxWidth }));
|
|
12
|
+
/**
|
|
13
|
+
* Multi-select prompt based on @clack/prompts.
|
|
14
|
+
* Replaces the previous ink grid table; keeps the same signature so
|
|
15
|
+
* existing call sites stay unchanged (itemsPerRow/boxWidth are obsolete).
|
|
16
|
+
*/
|
|
17
|
+
export const displayMultiSelectTable = (items_1, ...args_1) => __awaiter(void 0, [items_1, ...args_1], void 0, function* (items, _itemsPerRow = 7, _boxWidth = 25) {
|
|
18
|
+
const value = yield multiselect({
|
|
19
|
+
message: t('deploy_select_table_tip').d('Use arrow keys to move, space to select, and enter to submit.'),
|
|
20
|
+
options: items.map((item) => ({ label: item.label, value: item.label })),
|
|
21
|
+
required: false
|
|
94
22
|
});
|
|
23
|
+
if (isCancel(value)) {
|
|
24
|
+
cancel('Operation cancelled.');
|
|
25
|
+
process.exit(130);
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
95
28
|
});
|
|
@@ -7,62 +7,38 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
11
|
-
import
|
|
12
|
-
import React, { useState } from 'react';
|
|
10
|
+
import { text, isCancel } from '@clack/prompts';
|
|
11
|
+
import chalk from 'chalk';
|
|
13
12
|
import t from '../i18n/index.js';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
// Build complete route, add dot before prefix and slash before suffix if not empty
|
|
25
|
-
const prefixWithDot = prefix ? `${prefix}.` : '';
|
|
26
|
-
const suffixWithDot = suffix ? `/${suffix}` : '';
|
|
27
|
-
const route = `${prefixWithDot}${siteName}${suffixWithDot}`;
|
|
28
|
-
onSubmit(route);
|
|
29
|
-
};
|
|
30
|
-
const handleCancel = () => {
|
|
31
|
-
onCancel();
|
|
32
|
-
};
|
|
33
|
-
const currentPrompt = currentInput === 'prefix'
|
|
34
|
-
? t('route_builder_prefix_prompt')
|
|
13
|
+
import logger from '../libs/logger.js';
|
|
14
|
+
/**
|
|
15
|
+
* Interactively build a route for the given site (prefix + suffix),
|
|
16
|
+
* based on @clack/prompts. Returns the built route, or null if cancelled.
|
|
17
|
+
*/
|
|
18
|
+
export const routeBuilder = (siteName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
19
|
+
logger.log(`Building route for site: ${chalk.cyan(siteName)}`);
|
|
20
|
+
const prefix = yield text({
|
|
21
|
+
message: t('route_builder_prefix_prompt')
|
|
35
22
|
.d(`Enter route prefix for ${siteName} (e.g., abc, def):`)
|
|
36
|
-
.replace('${siteName}', siteName)
|
|
37
|
-
:
|
|
38
|
-
|
|
39
|
-
|
|
23
|
+
.replace('${siteName}', siteName),
|
|
24
|
+
defaultValue: ''
|
|
25
|
+
});
|
|
26
|
+
if (isCancel(prefix)) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
40
29
|
const prefixWithDot = prefix ? `${prefix}.` : '';
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
React.createElement(Box, { marginTop: 1 },
|
|
48
|
-
React.createElement(Text, null, currentPrompt)),
|
|
49
|
-
React.createElement(Box, { marginTop: 1 },
|
|
50
|
-
React.createElement(TextInput, { value: currentInput === 'prefix' ? prefix : suffix, onChange: currentInput === 'prefix' ? setPrefix : setSuffix, onSubmit: handleSubmit })),
|
|
51
|
-
preview && (React.createElement(Box, { marginTop: 1 },
|
|
52
|
-
React.createElement(Text, { color: "green" }, preview))),
|
|
53
|
-
React.createElement(Box, { marginTop: 1 },
|
|
54
|
-
React.createElement(Text, { color: "gray" }, t('route_builder_instructions').d('Press Enter to continue, Ctrl+C to cancel'))),
|
|
55
|
-
error && (React.createElement(Box, { marginTop: 1 },
|
|
56
|
-
React.createElement(Text, { color: "red" }, error)))));
|
|
57
|
-
};
|
|
58
|
-
export const routeBuilder = (siteName) => __awaiter(void 0, void 0, void 0, function* () {
|
|
59
|
-
return new Promise((resolve) => {
|
|
60
|
-
const { unmount } = render(React.createElement(RouteBuilder, { siteName: siteName, onSubmit: (route) => {
|
|
61
|
-
unmount();
|
|
62
|
-
resolve(route);
|
|
63
|
-
}, onCancel: () => {
|
|
64
|
-
unmount();
|
|
65
|
-
resolve(null);
|
|
66
|
-
} }));
|
|
30
|
+
const suffix = yield text({
|
|
31
|
+
message: t('route_builder_suffix_prompt')
|
|
32
|
+
.d(`Enter route suffix for ${siteName} (e.g., *, users/*):`)
|
|
33
|
+
.replace('${siteName}', siteName),
|
|
34
|
+
placeholder: `Preview: ${prefixWithDot}${siteName}`,
|
|
35
|
+
defaultValue: ''
|
|
67
36
|
});
|
|
37
|
+
if (isCancel(suffix)) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const suffixWithSlash = suffix ? `/${suffix}` : '';
|
|
41
|
+
const route = `${prefixWithDot}${siteName}${suffixWithSlash}`;
|
|
42
|
+
logger.log(chalk.green(`Preview: ${route}`));
|
|
43
|
+
return route;
|
|
68
44
|
});
|
|
@@ -1,16 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
7
9
|
};
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
import { select, isCancel, cancel } from '@clack/prompts';
|
|
11
|
+
/**
|
|
12
|
+
* Single-choice select prompt based on @clack/prompts.
|
|
13
|
+
* Keeps the callback-style API of the previous ink implementation
|
|
14
|
+
* so existing call sites stay unchanged.
|
|
15
|
+
*/
|
|
16
|
+
const SelectItems = (_a) => __awaiter(void 0, [_a], void 0, function* ({ items, handleSelect, message = 'Please select' }) {
|
|
17
|
+
const value = yield select({
|
|
18
|
+
message,
|
|
19
|
+
options: items.map((item) => ({ label: item.label, value: item.value }))
|
|
20
|
+
});
|
|
21
|
+
if (isCancel(value)) {
|
|
22
|
+
cancel('Operation cancelled.');
|
|
23
|
+
process.exit(130);
|
|
13
24
|
}
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
const selected = items.find((item) => item.value === value);
|
|
26
|
+
if (selected) {
|
|
27
|
+
yield handleSelect(selected);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
16
30
|
export default SelectItems;
|
package/dist/docs/Commands_en.md
CHANGED
|
@@ -345,11 +345,23 @@ AccessKey ID (AK)
|
|
|
345
345
|
**--access-key-secret, --sk** _optional_
|
|
346
346
|
AccessKey Secret (SK)
|
|
347
347
|
|
|
348
|
-
**
|
|
349
|
-
|
|
348
|
+
**--sts-token** _optional_
|
|
349
|
+
|
|
350
|
+
Temporary STS credentials in `AccessKeyId,AccessKeySecret,SecurityToken` or JSON format
|
|
351
|
+
|
|
352
|
+
**Environment Variables**
|
|
353
|
+
|
|
354
|
+
The standard Alibaba Cloud variables are preferred:
|
|
355
|
+
|
|
356
|
+
- **ALIBABA_CLOUD_ACCESS_KEY_ID**
|
|
357
|
+
- **ALIBABA_CLOUD_ACCESS_KEY_SECRET**
|
|
358
|
+
- **ALIBABA_CLOUD_SECURITY_TOKEN** _(optional)_
|
|
359
|
+
|
|
360
|
+
The legacy variables remain supported as lower-priority fallbacks:
|
|
350
361
|
|
|
351
362
|
- **ESA_ACCESS_KEY_ID**
|
|
352
363
|
- **ESA_ACCESS_KEY_SECRET**
|
|
364
|
+
- **ESA_SECURITY_TOKEN** _(optional)_
|
|
353
365
|
|
|
354
366
|
---
|
|
355
367
|
|
|
@@ -357,10 +357,20 @@ esa-cli login [OPTIONS]
|
|
|
357
357
|
**--access-key-secret, --sk** _可选_
|
|
358
358
|
**AccessKey Secret (SK)**
|
|
359
359
|
|
|
360
|
-
|
|
360
|
+
**--sts-token** _可选_
|
|
361
|
+
**临时 STS 凭证,支持 `AccessKeyId,AccessKeySecret,SecurityToken` 或 JSON 格式**
|
|
362
|
+
|
|
363
|
+
**环境变量** _优先读取阿里云标准环境变量:_
|
|
364
|
+
|
|
365
|
+
- **ALIBABA_CLOUD_ACCESS_KEY_ID**
|
|
366
|
+
- **ALIBABA_CLOUD_ACCESS_KEY_SECRET**
|
|
367
|
+
- **ALIBABA_CLOUD_SECURITY_TOKEN** _可选_
|
|
368
|
+
|
|
369
|
+
**以下旧变量继续作为低优先级兼容项:**
|
|
361
370
|
|
|
362
371
|
- **ESA_ACCESS_KEY_ID**
|
|
363
372
|
- **ESA_ACCESS_KEY_SECRET**
|
|
373
|
+
- **ESA_SECURITY_TOKEN** _可选_
|
|
364
374
|
|
|
365
375
|
---
|
|
366
376
|
|
package/dist/i18n/locales.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -27,15 +27,20 @@ import t from './i18n/index.js';
|
|
|
27
27
|
import logger from './libs/logger.js';
|
|
28
28
|
import { handleCheckVersion, checkCLIVersion } from './utils/checkVersion.js';
|
|
29
29
|
import { getCliConfig } from './utils/fileUtils/index.js';
|
|
30
|
+
const cliName = process.env.ALIBABA_CLOUD_ESA_CLI_COMPAT_MODE || 'esa-cli';
|
|
30
31
|
const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
32
|
const argv = hideBin(process.argv);
|
|
32
33
|
const cliConfig = getCliConfig();
|
|
33
34
|
const esa = yargs(argv)
|
|
34
35
|
.strict()
|
|
35
36
|
.fail((msg, err) => {
|
|
36
|
-
|
|
37
|
+
if (msg)
|
|
38
|
+
console.error(msg);
|
|
39
|
+
if (err)
|
|
40
|
+
console.error(err);
|
|
41
|
+
process.exit(1);
|
|
37
42
|
})
|
|
38
|
-
.scriptName(
|
|
43
|
+
.scriptName(cliName)
|
|
39
44
|
.locale((cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.lang) || 'en')
|
|
40
45
|
.version(false)
|
|
41
46
|
.wrap(null)
|
|
@@ -78,7 +83,7 @@ const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
78
83
|
esa.command('*', false, () => { }, (args) => {
|
|
79
84
|
if (args._.length > 0) {
|
|
80
85
|
// Unknown command
|
|
81
|
-
console.error(t('common_sub_command_fail').d(
|
|
86
|
+
console.error(t('common_sub_command_fail').d(`Use ${cliName} <command> -h to see help`));
|
|
82
87
|
}
|
|
83
88
|
else {
|
|
84
89
|
if (args.v) {
|
package/dist/libs/api.js
CHANGED
|
@@ -113,14 +113,6 @@ class Client {
|
|
|
113
113
|
const request = new $ESA.DeleteRoutineCodeVersionRequest(params);
|
|
114
114
|
return this.callApi(this.client.deleteRoutineCodeVersionWithOptions.bind(this.client), request);
|
|
115
115
|
}
|
|
116
|
-
createRoutineRelatedRoute(params) {
|
|
117
|
-
const request = new $ESA.CreateRoutineRelatedRouteRequest(params);
|
|
118
|
-
return this.callApi(this.client.createRoutineRelatedRouteWithOptions.bind(this.client), request);
|
|
119
|
-
}
|
|
120
|
-
deleteRoutineRelatedRoute(params) {
|
|
121
|
-
const request = new $ESA.DeleteRoutineRelatedRouteRequest(params);
|
|
122
|
-
return this.callApi(this.client.deleteRoutineRelatedRouteWithOptions.bind(this.client), request);
|
|
123
|
-
}
|
|
124
116
|
listSites(params) {
|
|
125
117
|
const request = new $ESA.ListSitesRequest(params);
|
|
126
118
|
return this.callApi(this.client.listSitesWithOptions.bind(this.client), request);
|
package/dist/libs/logger.js
CHANGED
|
@@ -7,7 +7,10 @@ import { format, createLogger } from 'winston';
|
|
|
7
7
|
import DailyRotateFile from 'winston-daily-rotate-file';
|
|
8
8
|
import t from '../i18n/index.js';
|
|
9
9
|
import { getProjectConfig } from '../utils/fileUtils/index.js';
|
|
10
|
-
const
|
|
10
|
+
const shouldWriteLogFile = () => process.env.NODE_ENV !== 'test' &&
|
|
11
|
+
!process.env.VITEST &&
|
|
12
|
+
!process.env.VITEST_WORKER_ID;
|
|
13
|
+
const createFileTransport = () => new DailyRotateFile({
|
|
11
14
|
filename: path.join(os.homedir(), '.esa-logs/esa-debug-%DATE%.log'),
|
|
12
15
|
level: 'info',
|
|
13
16
|
datePattern: 'YYYY-MM-DD-HH',
|
|
@@ -46,10 +49,12 @@ class Logger {
|
|
|
46
49
|
}
|
|
47
50
|
return `${printTimestamp} [${chalk.green(printLabel)}] ${colorizedLevel} in ${chalk.italic(projName)}: ${message}`;
|
|
48
51
|
});
|
|
52
|
+
const transports = shouldWriteLogFile() ? [createFileTransport()] : [];
|
|
49
53
|
this.logger = createLogger({
|
|
50
54
|
level: 'info',
|
|
51
55
|
format: combine(label({ label: 'ESA' }), timestamp(), customFormat),
|
|
52
|
-
|
|
56
|
+
silent: transports.length === 0,
|
|
57
|
+
transports
|
|
53
58
|
});
|
|
54
59
|
this.spinner = ora('Loading...');
|
|
55
60
|
}
|
package/dist/utils/fileMd5.js
CHANGED
|
@@ -4,15 +4,25 @@ export function calculateFileMD5(filePath) {
|
|
|
4
4
|
return new Promise((resolve, reject) => {
|
|
5
5
|
const hash = crypto.createHash('md5');
|
|
6
6
|
const fileStream = fs.createReadStream(filePath);
|
|
7
|
+
let md5sum = '';
|
|
8
|
+
let settled = false;
|
|
7
9
|
fileStream.on('data', (data) => {
|
|
8
10
|
hash.update(data);
|
|
9
11
|
});
|
|
10
12
|
fileStream.on('end', () => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
md5sum = hash.digest('hex');
|
|
14
|
+
});
|
|
15
|
+
fileStream.on('close', () => {
|
|
16
|
+
if (!settled) {
|
|
17
|
+
settled = true;
|
|
18
|
+
resolve(md5sum);
|
|
19
|
+
}
|
|
13
20
|
});
|
|
14
21
|
fileStream.on('error', (err) => {
|
|
15
|
-
|
|
22
|
+
if (!settled) {
|
|
23
|
+
settled = true;
|
|
24
|
+
reject(err);
|
|
25
|
+
}
|
|
16
26
|
});
|
|
17
27
|
});
|
|
18
28
|
}
|