esa-cli 1.0.9 → 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 +108 -5
- package/dist/commands/logout.js +11 -4
- 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 +21 -19
- 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 +25 -1
- package/dist/index.js +8 -3
- package/dist/libs/api.js +4 -15
- package/dist/libs/apiService.js +8 -14
- 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 +25 -3
- package/dist/utils/validateCredentials.js +12 -16
- 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?'),
|
|
@@ -13,11 +13,42 @@ import t from '../../i18n/index.js';
|
|
|
13
13
|
import logger from '../../libs/logger.js';
|
|
14
14
|
import { getCliConfig, updateCliConfigFile, generateDefaultConfig } from '../../utils/fileUtils/index.js';
|
|
15
15
|
import { validateCredentials } from '../../utils/validateCredentials.js';
|
|
16
|
+
/** Parse STS token string: "AccessKeyId,AccessKeySecret,SecurityToken" or JSON */
|
|
17
|
+
function parseStsToken(raw) {
|
|
18
|
+
var _a, _b, _c;
|
|
19
|
+
const s = raw.trim();
|
|
20
|
+
if (!s)
|
|
21
|
+
return null;
|
|
22
|
+
if (s.startsWith('{')) {
|
|
23
|
+
try {
|
|
24
|
+
const o = JSON.parse(s);
|
|
25
|
+
const accessKeyId = (_a = o.AccessKeyId) !== null && _a !== void 0 ? _a : o.accessKeyId;
|
|
26
|
+
const accessKeySecret = (_b = o.AccessKeySecret) !== null && _b !== void 0 ? _b : o.accessKeySecret;
|
|
27
|
+
const securityToken = (_c = o.SecurityToken) !== null && _c !== void 0 ? _c : o.securityToken;
|
|
28
|
+
if (accessKeyId && accessKeySecret && securityToken) {
|
|
29
|
+
return { accessKeyId, accessKeySecret, securityToken };
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (_d) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const parts = s.split(',').map((p) => p.trim());
|
|
38
|
+
if (parts.length >= 3) {
|
|
39
|
+
return {
|
|
40
|
+
accessKeyId: parts[0],
|
|
41
|
+
accessKeySecret: parts[1],
|
|
42
|
+
securityToken: parts.slice(2).join(',').trim()
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
16
47
|
const login = {
|
|
17
48
|
command: 'login',
|
|
18
49
|
describe: `🔑 ${t('login_describe').d('Login to the server')}`,
|
|
19
50
|
builder: (yargs) => {
|
|
20
|
-
var _a, _b;
|
|
51
|
+
var _a, _b, _c;
|
|
21
52
|
return yargs
|
|
22
53
|
.option('access-key-id', {
|
|
23
54
|
alias: 'ak',
|
|
@@ -28,18 +59,28 @@ const login = {
|
|
|
28
59
|
alias: 'sk',
|
|
29
60
|
describe: (_b = t('login_option_access_key_secret')) === null || _b === void 0 ? void 0 : _b.d('AccessKey Secret'),
|
|
30
61
|
type: 'string'
|
|
62
|
+
})
|
|
63
|
+
.option('sts-token', {
|
|
64
|
+
describe: (_c = t('login_option_sts_token')) === null || _c === void 0 ? void 0 : _c.d('STS token: AccessKeyId,AccessKeySecret,SecurityToken (comma-separated, one-shot)'),
|
|
65
|
+
type: 'string'
|
|
31
66
|
});
|
|
32
67
|
},
|
|
33
68
|
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
|
-
handleLogin(argv);
|
|
69
|
+
yield handleLogin(argv);
|
|
35
70
|
})
|
|
36
71
|
};
|
|
37
72
|
export default login;
|
|
38
73
|
export function handleLogin(argv) {
|
|
39
74
|
return __awaiter(this, void 0, void 0, function* () {
|
|
40
75
|
generateDefaultConfig();
|
|
41
|
-
|
|
42
|
-
|
|
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);
|
|
43
84
|
if (result.valid) {
|
|
44
85
|
logger.log(t('login_get_credentials_from_environment_variables').d('Get credentials from environment variables'));
|
|
45
86
|
logger.success(t('login_success').d('Login success!'));
|
|
@@ -49,6 +90,27 @@ export function handleLogin(argv) {
|
|
|
49
90
|
}
|
|
50
91
|
return;
|
|
51
92
|
}
|
|
93
|
+
const stsTokenRaw = argv === null || argv === void 0 ? void 0 : argv['sts-token'];
|
|
94
|
+
if (stsTokenRaw) {
|
|
95
|
+
const parsed = parseStsToken(stsTokenRaw);
|
|
96
|
+
if (!parsed) {
|
|
97
|
+
logger.error(t('login_sts_token_format_invalid').d('Invalid STS token format. Use: AccessKeyId,AccessKeySecret,SecurityToken'));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const result = yield validateCredentials(parsed.accessKeyId, parsed.accessKeySecret, parsed.securityToken);
|
|
101
|
+
if (result.valid) {
|
|
102
|
+
logger.success(t('login_success').d('Login success!'));
|
|
103
|
+
updateCliConfigFile(Object.assign({ auth: {
|
|
104
|
+
accessKeyId: parsed.accessKeyId,
|
|
105
|
+
accessKeySecret: parsed.accessKeySecret,
|
|
106
|
+
securityToken: parsed.securityToken
|
|
107
|
+
} }, (result.endpoint ? { endpoint: result.endpoint } : {})));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
logger.error(result.message || 'Login failed');
|
|
111
|
+
}
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
52
114
|
const accessKeyId = argv === null || argv === void 0 ? void 0 : argv['access-key-id'];
|
|
53
115
|
const accessKeySecret = argv === null || argv === void 0 ? void 0 : argv['access-key-secret'];
|
|
54
116
|
if (accessKeyId && accessKeySecret) {
|
|
@@ -73,7 +135,7 @@ export function handleLogin(argv) {
|
|
|
73
135
|
cliConfig.auth &&
|
|
74
136
|
cliConfig.auth.accessKeyId &&
|
|
75
137
|
cliConfig.auth.accessKeySecret) {
|
|
76
|
-
const loginStatus = yield validateCredentials(cliConfig.auth.accessKeyId, cliConfig.auth.accessKeySecret);
|
|
138
|
+
const loginStatus = yield validateCredentials(cliConfig.auth.accessKeyId, cliConfig.auth.accessKeySecret, cliConfig.auth.securityToken);
|
|
77
139
|
if (loginStatus.valid) {
|
|
78
140
|
logger.warn(t('login_already').d('You are already logged in.'));
|
|
79
141
|
const selected = (yield clackSelect({
|
|
@@ -99,6 +161,47 @@ export function handleLogin(argv) {
|
|
|
99
161
|
}
|
|
100
162
|
export function interactiveLogin() {
|
|
101
163
|
return __awaiter(this, void 0, void 0, function* () {
|
|
164
|
+
const loginMethod = (yield clackSelect({
|
|
165
|
+
message: t('login_method_select').d('Choose login method'),
|
|
166
|
+
options: [
|
|
167
|
+
{
|
|
168
|
+
label: t('login_method_aksk').d('AK/SK (AccessKey ID + AccessKey Secret)'),
|
|
169
|
+
value: 'aksk'
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
label: t('login_method_sts').d('STS Token (one-shot: AccessKeyId,AccessKeySecret,SecurityToken)'),
|
|
173
|
+
value: 'sts'
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
}));
|
|
177
|
+
if (isCancel(loginMethod)) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (loginMethod === 'sts') {
|
|
181
|
+
const stsInput = (yield clackText({
|
|
182
|
+
message: t('login_sts_token_prompt').d('Enter STS token (AccessKeyId,AccessKeySecret,SecurityToken):')
|
|
183
|
+
}));
|
|
184
|
+
if (isCancel(stsInput))
|
|
185
|
+
return;
|
|
186
|
+
const parsed = parseStsToken(stsInput);
|
|
187
|
+
if (!parsed) {
|
|
188
|
+
logger.error(t('login_sts_token_format_invalid').d('Invalid STS token format. Use: AccessKeyId,AccessKeySecret,SecurityToken'));
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const loginStatus = yield validateCredentials(parsed.accessKeyId, parsed.accessKeySecret, parsed.securityToken);
|
|
192
|
+
if (loginStatus.valid) {
|
|
193
|
+
yield updateCliConfigFile(Object.assign({ auth: {
|
|
194
|
+
accessKeyId: parsed.accessKeyId,
|
|
195
|
+
accessKeySecret: parsed.accessKeySecret,
|
|
196
|
+
securityToken: parsed.securityToken
|
|
197
|
+
} }, (loginStatus.endpoint ? { endpoint: loginStatus.endpoint } : {})));
|
|
198
|
+
logger.success(t('login_success').d('Login success!'));
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
logger.error(loginStatus.message || 'Login failed');
|
|
202
|
+
}
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
102
205
|
const styledUrl = chalk.underline.blue('https://ram.console.aliyun.com/manage/ak');
|
|
103
206
|
logger.log(`🔑 ${chalk.underline(t('login_get_ak_sk').d(`Please go to the following link to get your account's AccessKey ID and AccessKey Secret`))}`);
|
|
104
207
|
logger.log(`👉 ${styledUrl}`);
|
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() {
|
|
@@ -28,11 +28,18 @@ export function handleLogout() {
|
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
if (!cliConfig.auth) {
|
|
31
|
-
cliConfig.auth = {
|
|
31
|
+
cliConfig.auth = {
|
|
32
|
+
accessKeyId: '',
|
|
33
|
+
accessKeySecret: '',
|
|
34
|
+
securityToken: ''
|
|
35
|
+
};
|
|
32
36
|
}
|
|
33
37
|
else {
|
|
34
38
|
cliConfig.auth.accessKeyId = '';
|
|
35
39
|
cliConfig.auth.accessKeySecret = '';
|
|
40
|
+
if ('securityToken' in cliConfig.auth) {
|
|
41
|
+
cliConfig.auth.securityToken = '';
|
|
42
|
+
}
|
|
36
43
|
}
|
|
37
44
|
yield updateCliConfigFile(cliConfig);
|
|
38
45
|
logger.success(t('logout_success').d('Logout successfully'));
|
|
@@ -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
|
@@ -16,7 +16,7 @@ import { ApiService } from '../libs/apiService.js';
|
|
|
16
16
|
import { isInstalledGit } from '../libs/git/index.js';
|
|
17
17
|
import logger from '../libs/logger.js';
|
|
18
18
|
import { getRoot } from '../utils/fileUtils/base.js';
|
|
19
|
-
import { getCliConfig, projectConfigPath } from '../utils/fileUtils/index.js';
|
|
19
|
+
import { getApiConfig, getCliConfig, projectConfigPath } from '../utils/fileUtils/index.js';
|
|
20
20
|
import { validateCredentials } from '../utils/validateCredentials.js';
|
|
21
21
|
import { getRoutineDetails } from './common/utils.js';
|
|
22
22
|
export const checkDirectory = (isCheckGit = false) => {
|
|
@@ -78,28 +78,30 @@ export function validDomain(domain) {
|
|
|
78
78
|
}
|
|
79
79
|
export function checkIsLoginSuccess() {
|
|
80
80
|
return __awaiter(this, void 0, void 0, function* () {
|
|
81
|
-
var _a, _b;
|
|
81
|
+
var _a, _b, _c;
|
|
82
82
|
const cliConfig = getCliConfig();
|
|
83
|
-
let accessKeyId = process.env.
|
|
84
|
-
|
|
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);
|
|
85
92
|
if (accessKeyId && accessKeySecret) {
|
|
86
|
-
const result = yield validateCredentials(accessKeyId, accessKeySecret);
|
|
93
|
+
const result = yield validateCredentials(accessKeyId, accessKeySecret, securityToken);
|
|
87
94
|
const server = yield ApiService.getInstance();
|
|
88
95
|
if (result.valid) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
accessKeyId,
|
|
99
|
-
accessKeySecret
|
|
100
|
-
},
|
|
101
|
-
endpoint: result.endpoint
|
|
102
|
-
});
|
|
96
|
+
const auth = {
|
|
97
|
+
accessKeyId,
|
|
98
|
+
accessKeySecret
|
|
99
|
+
};
|
|
100
|
+
if (securityToken)
|
|
101
|
+
auth.securityToken = securityToken;
|
|
102
|
+
const fileConfig = getApiConfig();
|
|
103
|
+
server.updateConfig(Object.assign(Object.assign({}, fileConfig), { auth }));
|
|
104
|
+
api.updateConfig(Object.assign(Object.assign({}, fileConfig), { auth }));
|
|
103
105
|
return true;
|
|
104
106
|
}
|
|
105
107
|
}
|
|
@@ -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
|
});
|