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.
Files changed (42) hide show
  1. package/README.md +206 -22
  2. package/bin/enter.cjs +45 -12
  3. package/dist/bin/enter.cjs +45 -12
  4. package/dist/commands/commit/index.js +5 -4
  5. package/dist/commands/deployments/delete.js +1 -1
  6. package/dist/commands/deployments/list.js +1 -1
  7. package/dist/commands/dev/build.js +4 -1
  8. package/dist/commands/dev/doProcess.js +94 -36
  9. package/dist/commands/domain/add.js +1 -1
  10. package/dist/commands/domain/delete.js +2 -3
  11. package/dist/commands/domain/list.js +1 -1
  12. package/dist/commands/init/helper.js +12 -8
  13. package/dist/commands/init/index.js +3 -4
  14. package/dist/commands/login/index.js +108 -5
  15. package/dist/commands/logout.js +11 -4
  16. package/dist/commands/route/add.js +1 -1
  17. package/dist/commands/route/delete.js +1 -1
  18. package/dist/commands/route/list.js +1 -1
  19. package/dist/commands/routine/delete.js +1 -2
  20. package/dist/commands/routine/list.js +1 -1
  21. package/dist/commands/site/list.js +1 -1
  22. package/dist/commands/utils.js +21 -19
  23. package/dist/components/mutiSelectTable.js +16 -83
  24. package/dist/components/routeBuilder.js +30 -54
  25. package/dist/components/selectInput.js +27 -13
  26. package/dist/docs/Commands_en.md +14 -2
  27. package/dist/docs/Commands_zh_CN.md +11 -1
  28. package/dist/i18n/locales.json +25 -1
  29. package/dist/index.js +8 -3
  30. package/dist/libs/api.js +4 -15
  31. package/dist/libs/apiService.js +8 -14
  32. package/dist/libs/logger.js +7 -2
  33. package/dist/utils/fileMd5.js +13 -3
  34. package/dist/utils/fileUtils/base.js +14 -18
  35. package/dist/utils/fileUtils/index.js +25 -3
  36. package/dist/utils/validateCredentials.js +12 -16
  37. package/package.json +18 -20
  38. package/zh_CN.md +2 -2
  39. package/dist/components/descriptionInput.js +0 -38
  40. package/dist/components/filterSelector.js +0 -132
  41. package/dist/components/selectItem.js +0 -6
  42. package/dist/components/yesNoPrompt.js +0 -9
@@ -1,16 +1,30 @@
1
- import { render, Text } from 'ink';
2
- import SelectInput from 'ink-select-input';
3
- import React from 'react';
4
- import Item from './selectItem.js';
5
- const Indicator = ({ isSelected }) => {
6
- return React.createElement(Text, null, isSelected ? '👉 ' : ' ');
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
- const SelectItems = ({ items, handleSelect }) => {
9
- const { unmount } = render(React.createElement(SelectInput, { items: items, onSelect: onSelect, itemComponent: Item, indicatorComponent: Indicator }));
10
- function onSelect(item) {
11
- unmount();
12
- handleSelect(item);
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
- return unmount;
15
- };
25
+ const selected = items.find((item) => item.value === value);
26
+ if (selected) {
27
+ yield handleSelect(selected);
28
+ }
29
+ });
16
30
  export default SelectItems;
@@ -345,11 +345,23 @@ AccessKey ID (AK)
345
345
  **--access-key-secret, --sk** _optional_
346
346
  AccessKey Secret (SK)
347
347
 
348
- **Environment Variables**
349
- Read from environment variables:
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
 
@@ -164,7 +164,7 @@
164
164
  "zh_CN": "帮助"
165
165
  },
166
166
  "common_sub_command_fail": {
167
- "en": "Use esa-cli <command> -h to see help",
167
+ "en": "Use ${cliName} <command> -h to see help",
168
168
  "zh_CN": "使用 esa-cli <command> -h 查看帮助"
169
169
  },
170
170
  "deployments_delete_describe": {
@@ -1075,6 +1075,30 @@
1075
1075
  "en": "AccessKey Secret (SK)",
1076
1076
  "zh_CN": "AccessKey Secret (SK)"
1077
1077
  },
1078
+ "login_option_sts_token": {
1079
+ "en": "STS token: AccessKeyId,AccessKeySecret,SecurityToken (comma-separated, one-shot)",
1080
+ "zh_CN": "STS 临时凭证:AccessKeyId,AccessKeySecret,SecurityToken(逗号分隔,一次性输入)"
1081
+ },
1082
+ "login_sts_token_prompt": {
1083
+ "en": "Enter STS token (AccessKeyId,AccessKeySecret,SecurityToken):",
1084
+ "zh_CN": "请输入 STS 凭证(AccessKeyId,AccessKeySecret,SecurityToken):"
1085
+ },
1086
+ "login_sts_token_format_invalid": {
1087
+ "en": "Invalid STS token format. Use: AccessKeyId,AccessKeySecret,SecurityToken",
1088
+ "zh_CN": "STS 凭证格式错误,请使用:AccessKeyId,AccessKeySecret,SecurityToken"
1089
+ },
1090
+ "login_method_select": {
1091
+ "en": "Choose login method",
1092
+ "zh_CN": "选择登录方式"
1093
+ },
1094
+ "login_method_aksk": {
1095
+ "en": "AK/SK (AccessKey ID + AccessKey Secret)",
1096
+ "zh_CN": "AK/SK(AccessKey ID + AccessKey Secret)"
1097
+ },
1098
+ "login_method_sts": {
1099
+ "en": "STS Token (one-shot: AccessKeyId,AccessKeySecret,SecurityToken)",
1100
+ "zh_CN": "STS 临时凭证(一次性输入:AccessKeyId,AccessKeySecret,SecurityToken)"
1101
+ },
1078
1102
  "login_option_skip_login": {
1079
1103
  "en": "Skip login",
1080
1104
  "zh_CN": "跳过登录"
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
- console.error(msg, err);
37
+ if (msg)
38
+ console.error(msg);
39
+ if (err)
40
+ console.error(err);
41
+ process.exit(1);
37
42
  })
38
- .scriptName('esa-cli')
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('Use esa-cli <command> -h to see help'));
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
@@ -74,13 +74,10 @@ class Client {
74
74
  this.client = Client.createClient(config);
75
75
  }
76
76
  static createClient(config) {
77
- var _a, _b;
78
- const apiConfig = new $OpenApi.Config({
79
- accessKeyId: (_a = config.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId,
80
- accessKeySecret: (_b = config.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret,
81
- endpoint: config.endpoint,
82
- userAgent: CLI_USER_AGENT
83
- });
77
+ var _a, _b, _c;
78
+ const apiConfig = new $OpenApi.Config(Object.assign({ accessKeyId: (_a = config.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId, accessKeySecret: (_b = config.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret, endpoint: config.endpoint, userAgent: CLI_USER_AGENT }, (((_c = config.auth) === null || _c === void 0 ? void 0 : _c.securityToken)
79
+ ? { securityToken: config.auth.securityToken }
80
+ : {})));
84
81
  return new ESA.default(apiConfig);
85
82
  }
86
83
  updateConfig(config) {
@@ -116,14 +113,6 @@ class Client {
116
113
  const request = new $ESA.DeleteRoutineCodeVersionRequest(params);
117
114
  return this.callApi(this.client.deleteRoutineCodeVersionWithOptions.bind(this.client), request);
118
115
  }
119
- createRoutineRelatedRoute(params) {
120
- const request = new $ESA.CreateRoutineRelatedRouteRequest(params);
121
- return this.callApi(this.client.createRoutineRelatedRouteWithOptions.bind(this.client), request);
122
- }
123
- deleteRoutineRelatedRoute(params) {
124
- const request = new $ESA.DeleteRoutineRelatedRouteRequest(params);
125
- return this.callApi(this.client.deleteRoutineRelatedRouteWithOptions.bind(this.client), request);
126
- }
127
116
  listSites(params) {
128
117
  const request = new $ESA.ListSitesRequest(params);
129
118
  return this.callApi(this.client.listSitesWithOptions.bind(this.client), request);
@@ -16,13 +16,10 @@ import { CLI_USER_AGENT } from './constants.js';
16
16
  import { Environment } from './interface.js';
17
17
  export class ApiService {
18
18
  constructor(cliConfig) {
19
- var _a, _b;
20
- let apiConfig = new $OpenApi.Config({
21
- accessKeyId: (_a = cliConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId,
22
- accessKeySecret: (_b = cliConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret,
23
- endpoint: cliConfig.endpoint,
24
- userAgent: CLI_USER_AGENT
25
- });
19
+ var _a, _b, _c;
20
+ let apiConfig = new $OpenApi.Config(Object.assign({ accessKeyId: (_a = cliConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId, accessKeySecret: (_b = cliConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret, endpoint: cliConfig.endpoint, userAgent: CLI_USER_AGENT }, (((_c = cliConfig.auth) === null || _c === void 0 ? void 0 : _c.securityToken)
21
+ ? { securityToken: cliConfig.auth.securityToken }
22
+ : {})));
26
23
  this.client = new $OpenApi.default.default(apiConfig);
27
24
  }
28
25
  static getInstance() {
@@ -35,13 +32,10 @@ export class ApiService {
35
32
  });
36
33
  }
37
34
  updateConfig(newConfig) {
38
- var _a, _b;
39
- let apiConfig = new $OpenApi.Config({
40
- accessKeyId: (_a = newConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId,
41
- accessKeySecret: (_b = newConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret,
42
- endpoint: newConfig.endpoint,
43
- userAgent: CLI_USER_AGENT
44
- });
35
+ var _a, _b, _c;
36
+ let apiConfig = new $OpenApi.Config(Object.assign({ accessKeyId: (_a = newConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId, accessKeySecret: (_b = newConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret, endpoint: newConfig.endpoint, userAgent: CLI_USER_AGENT }, (((_c = newConfig.auth) === null || _c === void 0 ? void 0 : _c.securityToken)
37
+ ? { securityToken: newConfig.auth.securityToken }
38
+ : {})));
45
39
  this.client = new $OpenApi.default.default(apiConfig);
46
40
  }
47
41
  /**
@@ -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 transport = new DailyRotateFile({
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
- transports: [transport]
56
+ silent: transports.length === 0,
57
+ transports
53
58
  });
54
59
  this.spinner = ora('Loading...');
55
60
  }
@@ -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
- const md5sum = hash.digest('hex');
12
- resolve(md5sum);
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
- reject(err);
22
+ if (!settled) {
23
+ settled = true;
24
+ reject(err);
25
+ }
16
26
  });
17
27
  });
18
28
  }
@@ -1,31 +1,27 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { fileURLToPath } from 'url';
4
- const cliConfigFile = 'cliconfig.toml';
4
+ const projectConfigFiles = ['esa.jsonc', 'esa.toml'];
5
5
  export const getDirName = (metaUrl) => {
6
6
  const __filename = fileURLToPath(metaUrl);
7
7
  const __dirname = path.dirname(__filename);
8
8
  return __dirname;
9
9
  };
10
10
  export const getRoot = (root) => {
11
- if (typeof root === 'undefined') {
12
- root = process.cwd();
13
- }
14
- if (path.parse(root).root === root) {
15
- return process.cwd();
16
- }
17
- const file = path.join(root, cliConfigFile);
18
- const prev = path.resolve(root, '../');
19
- try {
20
- const hasToml = fs.existsSync(file);
21
- if (hasToml) {
22
- return root;
11
+ const start = path.resolve(root !== null && root !== void 0 ? root : process.cwd());
12
+ let current = start;
13
+ while (true) {
14
+ try {
15
+ const hasProjectConfig = projectConfigFiles.some((fileName) => fs.existsSync(path.join(current, fileName)));
16
+ if (hasProjectConfig) {
17
+ return current;
18
+ }
23
19
  }
24
- else {
25
- return getRoot(prev);
20
+ catch (_a) { }
21
+ const parent = path.dirname(current);
22
+ if (parent === current) {
23
+ return process.cwd();
26
24
  }
27
- }
28
- catch (err) {
29
- return getRoot(prev);
25
+ current = parent;
30
26
  }
31
27
  };
@@ -268,12 +268,33 @@ export function getDevOpenBrowserUrl() {
268
268
  return `http://localhost:${port}`;
269
269
  }
270
270
  export const getApiConfig = () => {
271
- var _a, _b;
271
+ var _a, _b, _c;
272
+ const envAccessKeyId = process.env.ALIBABA_CLOUD_ACCESS_KEY_ID ||
273
+ process.env.ESA_ACCESS_KEY_ID;
274
+ const envAccessKeySecret = process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET ||
275
+ process.env.ESA_ACCESS_KEY_SECRET;
276
+ const envSecurityToken = process.env.ALIBABA_CLOUD_SECURITY_TOKEN ||
277
+ process.env.ESA_SECURITY_TOKEN;
278
+ if (envAccessKeyId && envAccessKeySecret) {
279
+ const [cliConfig, projectConfig] = getConfigurations();
280
+ const endpoint = (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.endpoint) ||
281
+ (cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.endpoint) ||
282
+ 'esa.cn-hangzhou.aliyuncs.com';
283
+ return {
284
+ auth: {
285
+ accessKeyId: envAccessKeyId,
286
+ accessKeySecret: envAccessKeySecret,
287
+ securityToken: envSecurityToken
288
+ },
289
+ endpoint
290
+ };
291
+ }
272
292
  const [cliConfig, projectConfig] = getConfigurations();
273
293
  let defaultConfig = {
274
294
  auth: {
275
295
  accessKeyId: '',
276
- accessKeySecret: ''
296
+ accessKeySecret: '',
297
+ securityToken: undefined
277
298
  },
278
299
  endpoint: `esa.cn-hangzhou.aliyuncs.com`
279
300
  };
@@ -281,7 +302,8 @@ export const getApiConfig = () => {
281
302
  const config = {
282
303
  auth: {
283
304
  accessKeyId: (_a = combinedConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId,
284
- accessKeySecret: (_b = combinedConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret
305
+ accessKeySecret: (_b = combinedConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret,
306
+ securityToken: (_c = combinedConfig.auth) === null || _c === void 0 ? void 0 : _c.securityToken
285
307
  },
286
308
  endpoint: combinedConfig.endpoint
287
309
  };
@@ -14,15 +14,14 @@ const DOMESTIC_ENDPOINT = 'esa.cn-hangzhou.aliyuncs.com';
14
14
  const INTERNATIONAL_ENDPOINT = 'esa.ap-southeast-1.aliyuncs.com';
15
15
  /**
16
16
  * Validate credentials for a single endpoint
17
+ * @param securityToken - Optional STS SecurityToken; when provided, uses STS auth
17
18
  */
18
- function validateEndpoint(accessKeyId, accessKeySecret, endpoint) {
19
+ function validateEndpoint(accessKeyId, accessKeySecret, endpoint, securityToken) {
19
20
  return __awaiter(this, void 0, void 0, function* () {
20
21
  try {
21
- const apiConfig = new $OpenApi.Config({
22
- accessKeyId,
22
+ const apiConfig = new $OpenApi.Config(Object.assign({ accessKeyId,
23
23
  accessKeySecret,
24
- endpoint
25
- });
24
+ endpoint }, (securityToken ? { securityToken } : {})));
26
25
  const client = new $OpenApi.default.default(apiConfig);
27
26
  const params = {
28
27
  action: 'GetErService',
@@ -80,25 +79,24 @@ function validateEndpoint(accessKeyId, accessKeySecret, endpoint) {
80
79
  });
81
80
  }
82
81
  /**
83
- * Validate if AK/SK/endpoint are valid
82
+ * Validate if AK/SK/endpoint are valid (supports STS when securityToken is provided)
84
83
  *
85
84
  * @param accessKeyId - AccessKey ID
86
85
  * @param accessKeySecret - AccessKey Secret
86
+ * @param securityToken - Optional STS SecurityToken for temporary credentials
87
87
  * @returns Validation result, including whether valid, site type and endpoint
88
88
  */
89
- export function validateCredentials(accessKeyId, accessKeySecret) {
89
+ export function validateCredentials(accessKeyId, accessKeySecret, securityToken) {
90
90
  return __awaiter(this, void 0, void 0, function* () {
91
+ const withToken = (ep) => validateEndpoint(accessKeyId, accessKeySecret, ep, securityToken);
91
92
  if (process.env.CUSTOM_ENDPOINT) {
92
- const result = yield validateEndpoint(accessKeyId, accessKeySecret, process.env.CUSTOM_ENDPOINT);
93
+ const result = yield withToken(process.env.CUSTOM_ENDPOINT);
93
94
  if (result.valid) {
94
95
  return { valid: true, endpoint: process.env.CUSTOM_ENDPOINT };
95
96
  }
96
- else {
97
- return { valid: false, message: result.message };
98
- }
97
+ return { valid: false, message: result.message };
99
98
  }
100
- // First validate domestic site
101
- const domesticResult = yield validateEndpoint(accessKeyId, accessKeySecret, DOMESTIC_ENDPOINT);
99
+ const domesticResult = yield withToken(DOMESTIC_ENDPOINT);
102
100
  if (domesticResult.valid) {
103
101
  return {
104
102
  valid: true,
@@ -106,8 +104,7 @@ export function validateCredentials(accessKeyId, accessKeySecret) {
106
104
  endpoint: DOMESTIC_ENDPOINT
107
105
  };
108
106
  }
109
- // If domestic site validation fails, validate international site
110
- const internationalResult = yield validateEndpoint(accessKeyId, accessKeySecret, INTERNATIONAL_ENDPOINT);
107
+ const internationalResult = yield withToken(INTERNATIONAL_ENDPOINT);
111
108
  if (internationalResult.valid) {
112
109
  return {
113
110
  valid: true,
@@ -115,7 +112,6 @@ export function validateCredentials(accessKeyId, accessKeySecret) {
115
112
  endpoint: INTERNATIONAL_ENDPOINT
116
113
  };
117
114
  }
118
- // Both failed, return failure result
119
115
  return {
120
116
  valid: false,
121
117
  message: domesticResult.message ||
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esa-cli",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "A CLI for operating Alibaba Cloud ESA Functions and Pages.",
5
5
  "main": "bin/enter.cjs",
6
6
  "type": "module",
@@ -36,11 +36,13 @@
36
36
  ],
37
37
  "author": "Kinice, Shengyuan Ma",
38
38
  "license": "MIT",
39
+ "engines": {
40
+ "node": ">=18"
41
+ },
39
42
  "devDependencies": {
40
43
  "@babel/plugin-syntax-import-attributes": "^7.24.7",
41
44
  "@testing-library/dom": "^10.4.0",
42
45
  "@testing-library/jest-dom": "^6.5.0",
43
- "@testing-library/react": "^16.0.1",
44
46
  "@types/adm-zip": "^0.5.7",
45
47
  "@types/babel__generator": "^7.6.8",
46
48
  "@types/babel__traverse": "^7.20.6",
@@ -48,53 +50,52 @@
48
50
  "@types/cross-spawn": "^6.0.6",
49
51
  "@types/fs-extra": "^11.0.4",
50
52
  "@types/jest": "^29.5.12",
53
+ "@types/inquirer": "^9.0.7",
51
54
  "@types/lodash": "^4.14.202",
52
55
  "@types/node": "^20.8.10",
53
56
  "@types/node-fetch": "^2.6.9",
54
57
  "@types/portscanner": "^2.1.4",
55
- "@types/react": "^18.2.47",
56
58
  "@types/yargs": "^17.0.32",
57
- "@typescript-eslint/eslint-plugin": "^6.21.0",
58
- "@typescript-eslint/parser": "^6.9.1",
59
+ "@typescript-eslint/eslint-plugin": "8.46.1",
60
+ "@typescript-eslint/parser": "8.46.1",
59
61
  "eslint": "^8.57.0",
60
62
  "eslint-plugin-import": "^2.32.0",
61
- "eslint-plugin-react": "latest",
62
- "eslint-plugin-react-hooks": "^5.2.0",
63
+ "rimraf": "5.0.10",
63
64
  "husky": "^8.0.3",
64
65
  "jsdom": "^25.0.1",
65
66
  "lint-staged": "^15.0.2",
66
67
  "prettier": "^3.0.3",
67
68
  "tsc-files": "^1.1.4",
68
69
  "typescript": "^5.2.2",
69
- "vitest": "^2.0.4"
70
+ "@vitest/coverage-istanbul": "^3.2.6",
71
+ "vite": "6.4.3",
72
+ "vitest": "^3.2.6"
70
73
  },
71
74
  "dependencies": {
72
- "@alicloud/esa20240910": "2.25.0",
75
+ "@alicloud/esa20240910": "2.29.0",
73
76
  "@alicloud/openapi-client": "^0.4.7",
77
+ "@alicloud/tea-util": "^1.4.9",
74
78
  "@babel/generator": "^7.26.3",
75
79
  "@babel/parser": "^7.24.4",
76
80
  "@babel/traverse": "^7.24.1",
77
81
  "@clack/prompts": "1.0.0-alpha.4",
78
82
  "@iarna/toml": "^2.2.5",
79
- "@types/inquirer": "^9.0.7",
80
- "@vitest/coverage-istanbul": "^2.0.4",
81
- "adm-zip": "^0.5.16",
83
+ "adm-zip": "^0.6.0",
82
84
  "chalk": "^5.3.0",
83
85
  "chokidar": "^3.5.3",
84
86
  "cli-table3": "^0.6.5",
85
87
  "cross-spawn": "^7.0.3",
88
+ "debug": "^4.4.3",
86
89
  "esa-template": "^0.0.10",
87
- "esbuild": "^0.21.1",
90
+ "esbuild": "^0.25.12",
88
91
  "esbuild-plugin-less": "^1.3.8",
89
92
  "form-data": "^4.0.0",
90
93
  "fs-extra": "^11.2.0",
91
94
  "haikunator": "^2.1.2",
92
95
  "http-proxy-agent": "^7.0.2",
93
- "ink": "^5.0.1",
94
- "ink-select-input": "^6.0.0",
95
- "ink-text-input": "^6.0.0",
96
96
  "inquirer": "^9.2.15",
97
97
  "js-base64": "^3.7.7",
98
+ "lodash": "^4.17.21",
98
99
  "moment": "^2.30.1",
99
100
  "node-fetch": "^3.3.2",
100
101
  "open": "^9.1.0",
@@ -103,10 +104,7 @@
103
104
  "portscanner": "^2.2.0",
104
105
  "winston": "^3.11.0",
105
106
  "winston-daily-rotate-file": "^5.0.0",
106
- "yargs": "^17.7.2",
107
- "react": "^18.2.0",
108
- "react-dom": "^18.2.0",
109
- "rimraf": "^6.0.1"
107
+ "yargs": "^17.7.2"
110
108
  },
111
109
  "lint-staged": {
112
110
  "src/**/*.{ts,tsx,js,jsx}": [
package/zh_CN.md CHANGED
@@ -51,7 +51,7 @@ npm i -D esa-cli@latest
51
51
 
52
52
  ## 相关文档
53
53
 
54
- - [esa-cli 命令](./docs/Commands_zh_CN.md)
55
- - [ESA 配置文件说明](./docs/Config_zh_CN.md)
54
+ - [esa-cli 命令](https://github.com/aliyun/alibabacloud-esa-cli/blob/master/docs/Commands_zh_CN.md)
55
+ - [ESA 配置文件说明](https://github.com/aliyun/alibabacloud-esa-cli/blob/master/docs/Config_zh_CN.md)
56
56
  - [阿里云 ESA 文档](https://help.aliyun.com/document_detail/2710021.html)
57
57
  - [Functions 和 Pages API 参考](https://help.aliyun.com/document_detail/2710024.html)
@@ -1,38 +0,0 @@
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
- });
9
- };
10
- import { Box, render, Text } from 'ink';
11
- import TextInput from 'ink-text-input';
12
- import React, { useState } from 'react';
13
- export const DescriptionInput = ({ prompt, onSubmit, required }) => {
14
- const [input, setInput] = useState('');
15
- const [error, setError] = useState('');
16
- const handleSubmit = () => {
17
- if (required && !input.trim()) {
18
- setError('This field is required');
19
- }
20
- else {
21
- onSubmit(input);
22
- }
23
- };
24
- return (React.createElement(Box, { flexDirection: "column" },
25
- React.createElement(Box, null,
26
- React.createElement(Text, null, prompt)),
27
- React.createElement(TextInput, { value: input, onChange: setInput, onSubmit: handleSubmit }),
28
- error && (React.createElement(Box, null,
29
- React.createElement(Text, { color: "red" }, error)))));
30
- };
31
- export const descriptionInput = (prompt_1, ...args_1) => __awaiter(void 0, [prompt_1, ...args_1], void 0, function* (prompt, required = false) {
32
- return new Promise((resolve) => {
33
- const { unmount } = render(React.createElement(DescriptionInput, { prompt: prompt, required: required, onSubmit: (input) => {
34
- unmount();
35
- resolve(input);
36
- } }));
37
- });
38
- });