esa-cli 0.0.2-beta.15 → 0.0.2-beta.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/commit/index.js +4 -4
- package/dist/commands/common/utils.js +108 -11
- package/dist/commands/deploy/helper.js +11 -11
- package/dist/commands/deploy/index.js +9 -10
- package/dist/commands/init/helper.js +106 -8
- package/dist/commands/init/index.js +3 -3
- package/dist/commands/init/template.jsonc +1 -1
- package/dist/commands/route/add.js +19 -51
- package/dist/commands/routine/list.js +38 -20
- package/dist/components/mutiLevelSelect.js +2 -1
- package/dist/components/routeBuilder.js +68 -0
- package/dist/docs/Commands_en.md +34 -1
- package/dist/docs/Commands_zh_CN.md +40 -6
- package/dist/i18n/locales.json +72 -0
- package/dist/index.js +11 -1
- package/dist/libs/apiService.js +4 -2
- package/dist/libs/logger.js +41 -2
- package/dist/utils/checkIsRoutineCreated.js +1 -8
- package/dist/utils/checkVersion.js +118 -0
- package/dist/utils/compress.js +27 -9
- package/dist/utils/fileUtils/index.js +36 -13
- package/package.json +10 -11
|
@@ -18,37 +18,55 @@ const list = {
|
|
|
18
18
|
command: 'list',
|
|
19
19
|
describe: `📋 ${t('list_describe').d('List all your routines')}`,
|
|
20
20
|
builder: (yargs) => {
|
|
21
|
-
return yargs
|
|
21
|
+
return yargs
|
|
22
|
+
.option('keyword', {
|
|
23
|
+
alias: 'k',
|
|
24
|
+
describe: t('deploy_option_keyword').d('Keyword to search for routines'),
|
|
25
|
+
type: 'string'
|
|
26
|
+
})
|
|
27
|
+
.usage(`${t('common_usage').d('Usage')}: \$0 list [--keyword <keyword>]`);
|
|
22
28
|
},
|
|
23
29
|
handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
24
30
|
handleList(argv);
|
|
25
31
|
})
|
|
26
32
|
};
|
|
27
33
|
export default list;
|
|
34
|
+
export function getAllRoutines(options) {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
var _a;
|
|
37
|
+
const server = yield ApiService.getInstance();
|
|
38
|
+
const allRoutines = [];
|
|
39
|
+
let pageNumber = 1;
|
|
40
|
+
const pageSize = (options === null || options === void 0 ? void 0 : options.PageSize) || 50;
|
|
41
|
+
while (true) {
|
|
42
|
+
const res = yield server.listUserRoutines({
|
|
43
|
+
RegionId: options === null || options === void 0 ? void 0 : options.RegionId,
|
|
44
|
+
PageNumber: pageNumber,
|
|
45
|
+
PageSize: pageSize,
|
|
46
|
+
SearchKeyWord: options === null || options === void 0 ? void 0 : options.SearchKeyWord
|
|
47
|
+
});
|
|
48
|
+
if (!((_a = res === null || res === void 0 ? void 0 : res.body) === null || _a === void 0 ? void 0 : _a.Routines)) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
allRoutines.push(...res.body.Routines);
|
|
52
|
+
const totalCount = res.body.TotalCount;
|
|
53
|
+
const currentCount = allRoutines.length;
|
|
54
|
+
if (currentCount >= totalCount) {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
pageNumber++;
|
|
58
|
+
}
|
|
59
|
+
return allRoutines;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
28
62
|
export function handleList(argv) {
|
|
29
63
|
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
-
var _a, _b;
|
|
31
|
-
const { site } = argv;
|
|
32
64
|
const isSuccess = yield checkIsLoginSuccess();
|
|
33
65
|
if (!isSuccess)
|
|
34
66
|
return;
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
SiteSearchType: 'fuzzy',
|
|
39
|
-
Status: 'active',
|
|
40
|
-
PageNumber: 1,
|
|
41
|
-
PageSize: 50
|
|
42
|
-
};
|
|
43
|
-
const res = yield server.listSites(req);
|
|
44
|
-
const siteList = (_a = res === null || res === void 0 ? void 0 : res.data.Sites) !== null && _a !== void 0 ? _a : [];
|
|
45
|
-
const siteNameList = siteList === null || siteList === void 0 ? void 0 : siteList.map((item) => item.SiteName);
|
|
46
|
-
logger.log(chalk.bold.bgGray(`📃 ${t('list_site_name_title').d('List all of site names')}:`));
|
|
47
|
-
logger.tree(siteNameList);
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
const res = yield server.listUserRoutines();
|
|
51
|
-
const routineList = (_b = res === null || res === void 0 ? void 0 : res.body) === null || _b === void 0 ? void 0 : _b.Routines;
|
|
67
|
+
const routineList = yield getAllRoutines({
|
|
68
|
+
SearchKeyWord: argv.keyword
|
|
69
|
+
});
|
|
52
70
|
if (routineList) {
|
|
53
71
|
logger.log(chalk.bold.bgGray(`📃 ${t('list_routine_name_title').d('List all of routine')}:`));
|
|
54
72
|
displayRoutineList(routineList);
|
|
@@ -26,7 +26,8 @@ export default function multiLevelSelect(items_1) {
|
|
|
26
26
|
options: [
|
|
27
27
|
...currentItems.map((item) => ({
|
|
28
28
|
label: item.label,
|
|
29
|
-
value: item.value
|
|
29
|
+
value: item.value,
|
|
30
|
+
hint: item.hint
|
|
30
31
|
})),
|
|
31
32
|
...(stack.length > 0 ? [{ label: 'Back', value: '__back__' }] : [])
|
|
32
33
|
]
|
|
@@ -0,0 +1,68 @@
|
|
|
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
|
+
import t from '../i18n/index.js';
|
|
14
|
+
export const RouteBuilder = ({ siteName, onSubmit, onCancel }) => {
|
|
15
|
+
const [prefix, setPrefix] = useState('');
|
|
16
|
+
const [suffix, setSuffix] = useState('');
|
|
17
|
+
const [currentInput, setCurrentInput] = useState('prefix');
|
|
18
|
+
const [error, setError] = useState('');
|
|
19
|
+
const handleSubmit = () => {
|
|
20
|
+
if (currentInput === 'prefix') {
|
|
21
|
+
setCurrentInput('suffix');
|
|
22
|
+
return;
|
|
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')
|
|
35
|
+
.d(`Enter route prefix for ${siteName} (e.g., abc, def):`)
|
|
36
|
+
.replace('${siteName}', siteName)
|
|
37
|
+
: t('route_builder_suffix_prompt')
|
|
38
|
+
.d(`Enter route suffix for ${siteName} (e.g., *, users/*):`)
|
|
39
|
+
.replace('${siteName}', siteName);
|
|
40
|
+
const prefixWithDot = prefix ? `${prefix}.` : '';
|
|
41
|
+
const suffixWithDot = suffix ? `/${suffix}` : '';
|
|
42
|
+
const preview = `Preview: ${prefixWithDot}${siteName}${suffixWithDot}`;
|
|
43
|
+
return (React.createElement(Box, { flexDirection: "column" },
|
|
44
|
+
React.createElement(Box, null,
|
|
45
|
+
React.createElement(Text, null, "Building route for site: "),
|
|
46
|
+
React.createElement(Text, { color: "cyan" }, siteName)),
|
|
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
|
+
} }));
|
|
67
|
+
});
|
|
68
|
+
});
|
package/dist/docs/Commands_en.md
CHANGED
|
@@ -72,7 +72,7 @@ esa deploy [entry]
|
|
|
72
72
|
- -v, --version string: Version to deploy (skip interactive selection)
|
|
73
73
|
- -e, --environment string: Environment to deploy to. Choices: staging | production
|
|
74
74
|
- -n, --name string: Name of the routine
|
|
75
|
-
- -a, --assets
|
|
75
|
+
- -a, --assets string: Assets directory (e.g., ./dist)
|
|
76
76
|
- -d, --description string: Description of the version
|
|
77
77
|
- -m, --minify boolean: Minify the code
|
|
78
78
|
|
|
@@ -153,6 +153,39 @@ esa route delete <routeName>
|
|
|
153
153
|
- list: List all related routes
|
|
154
154
|
- delete <routeName>: Delete a related route
|
|
155
155
|
|
|
156
|
+
#### esa route add
|
|
157
|
+
|
|
158
|
+
Bind a route to the current routine.
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
esa route add [route] [site] [--alias <routeName>] [--route <route>] [--site <site>]
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
- Positionals (optional):
|
|
165
|
+
- route: The route value, e.g. example.com/_ or _.example.com/\*
|
|
166
|
+
- site: The site name, e.g. example.com
|
|
167
|
+
|
|
168
|
+
- Options:
|
|
169
|
+
- -r, --route string: Route value, e.g. example.com/\*
|
|
170
|
+
- Host supports leading `*` for suffix match (e.g., `*.example.com`)
|
|
171
|
+
- Path supports trailing `*` for prefix match (e.g., `/api/*`)
|
|
172
|
+
- -s, --site string: Site name (must be an active site)
|
|
173
|
+
- -a, --alias string: Route name (alias)
|
|
174
|
+
|
|
175
|
+
- Interactive behavior:
|
|
176
|
+
- If `--alias` is missing, you will be prompted to input a route name
|
|
177
|
+
- If `--site` is missing, you will be prompted to choose from active sites
|
|
178
|
+
- If `--route` is missing, you will be prompted to input the route value
|
|
179
|
+
|
|
180
|
+
- Route matching notes:
|
|
181
|
+
- Host supports `*` prefix: `*.example.com` matches any host ending with `.example.com`
|
|
182
|
+
- Path supports `*` suffix: `/api/*` matches any path starting with `/api/`
|
|
183
|
+
- Examples: `example.com/*`, `*.example.com/`, `*.example.com/api/*`
|
|
184
|
+
|
|
185
|
+
- Examples:
|
|
186
|
+
- `esa route add -a home -s example.com -r example.com/*`
|
|
187
|
+
- `esa route add example.com/* example.com -a home`
|
|
188
|
+
|
|
156
189
|
---
|
|
157
190
|
|
|
158
191
|
### esa login
|
|
@@ -15,7 +15,7 @@ esa init [name]
|
|
|
15
15
|
- -f, --framework string:选择前端框架(react/vue/nextjs...)
|
|
16
16
|
- -l, --language string:选择语言(typescript/javascript)。可选:typescript | javascript
|
|
17
17
|
- -t, --template string:指定模板名称
|
|
18
|
-
- -y, --yes boolean:对所有交互询问选择“是”(默认 false
|
|
18
|
+
- -y, --yes boolean:对所有交互询问选择“是”(默认 false),模版采用helloworld
|
|
19
19
|
- --git boolean:在项目中初始化 git
|
|
20
20
|
- --deploy boolean:初始化完成后自动部署
|
|
21
21
|
|
|
@@ -65,14 +65,12 @@ esa commit [entry]
|
|
|
65
65
|
esa deploy [entry]
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
- 位置参数:
|
|
69
|
-
- entry:(可选的)边缘函数入口文件
|
|
70
|
-
|
|
71
68
|
- 选项:
|
|
69
|
+
- entry 可选参数,默认以`esa.jsonc`中entry配置为准
|
|
72
70
|
- -v, --version string:指定要部署的版本(跳过交互选择)
|
|
73
71
|
- -e, --environment string:部署环境。可选:staging | production
|
|
74
72
|
- -n, --name string:边缘函数名称
|
|
75
|
-
- -a, --assets
|
|
73
|
+
- -a, --assets string:静态资源目录(例如:./dist)
|
|
76
74
|
- -d, --description string:版本描述
|
|
77
75
|
- -m, --minify boolean:是否压缩代码
|
|
78
76
|
|
|
@@ -117,7 +115,7 @@ esa site list
|
|
|
117
115
|
```
|
|
118
116
|
|
|
119
117
|
- 子命令:
|
|
120
|
-
- list
|
|
118
|
+
- list:列出所有已激活站点
|
|
121
119
|
|
|
122
120
|
---
|
|
123
121
|
|
|
@@ -153,6 +151,39 @@ esa route delete <routeName>
|
|
|
153
151
|
- list:查看所有已绑定路由
|
|
154
152
|
- delete `<routeName>`:删除已绑定路由
|
|
155
153
|
|
|
154
|
+
#### esa route add
|
|
155
|
+
|
|
156
|
+
为当前边缘函数绑定一个路由。
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
esa route add [route] [site] [--alias <routeName>] [--route <route>] [--site <site>]
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
- 位置参数(可选):
|
|
163
|
+
- route:路由值,例如:example.com/_ 或 _.example.com/\*
|
|
164
|
+
- site:站点名称,例如:example.com
|
|
165
|
+
|
|
166
|
+
- 选项:
|
|
167
|
+
- -r, --route string:路由值,例如:example.com/\*
|
|
168
|
+
- 主机名支持以 `*` 开头表示后缀匹配(如:`*.example.com`)
|
|
169
|
+
- 路径支持以 `*` 结尾表示前缀匹配(如:`/api/*`)
|
|
170
|
+
- -s, --site string:站点名称(需为已激活站点)
|
|
171
|
+
- -a, --alias string:路由名称(别名)
|
|
172
|
+
|
|
173
|
+
- 交互提示:
|
|
174
|
+
- 未提供 `--alias` 时,会提示输入路由名称
|
|
175
|
+
- 未提供 `--site` 时,会列出账号下已激活站点供选择
|
|
176
|
+
- 未提供 `--route` 时,会提示输入路由值
|
|
177
|
+
|
|
178
|
+
- 路由匹配说明:
|
|
179
|
+
- host 支持前缀 `*`:`*.example.com` 表示匹配所有以 `.example.com` 结尾的域名
|
|
180
|
+
- path 支持后缀 `*`:`/api/*` 表示匹配以 `/api/` 开头的路径
|
|
181
|
+
- 示例:`example.com/*`、`*.example.com/`、`*.example.com/api/*`
|
|
182
|
+
|
|
183
|
+
- 示例:
|
|
184
|
+
- `esa route add -a home -s example.com -r example.com/*`
|
|
185
|
+
- `esa route add example.com/* example.com -a home`
|
|
186
|
+
|
|
156
187
|
---
|
|
157
188
|
|
|
158
189
|
### esa login
|
|
@@ -166,6 +197,9 @@ esa login
|
|
|
166
197
|
- 选项:
|
|
167
198
|
- --access-key-id, --ak string:AccessKey ID (AK)
|
|
168
199
|
- --access-key-secret, --sk string:AccessKey Secret (SK)
|
|
200
|
+
- 从环境变量中读取process.env
|
|
201
|
+
- ESA_ACCESS_KEY_ID
|
|
202
|
+
- ESA_ACCESS_KEY_SECRET
|
|
169
203
|
|
|
170
204
|
---
|
|
171
205
|
|
package/dist/i18n/locales.json
CHANGED
|
@@ -1234,5 +1234,77 @@
|
|
|
1234
1234
|
"step": {
|
|
1235
1235
|
"en": "Step:",
|
|
1236
1236
|
"zh_CN": ""
|
|
1237
|
+
},
|
|
1238
|
+
"version_title_update_available": {
|
|
1239
|
+
"en": "ESA CLI Update Available",
|
|
1240
|
+
"zh_CN": "ESA CLI 有新版本可用"
|
|
1241
|
+
},
|
|
1242
|
+
"version_current": {
|
|
1243
|
+
"en": "Current",
|
|
1244
|
+
"zh_CN": "当前版本"
|
|
1245
|
+
},
|
|
1246
|
+
"version_latest": {
|
|
1247
|
+
"en": "Latest",
|
|
1248
|
+
"zh_CN": "最新版本"
|
|
1249
|
+
},
|
|
1250
|
+
"version_note": {
|
|
1251
|
+
"en": "Note",
|
|
1252
|
+
"zh_CN": "提示"
|
|
1253
|
+
},
|
|
1254
|
+
"version_note_incompatible": {
|
|
1255
|
+
"en": "This version may have incompatibilities, please upgrade soon.",
|
|
1256
|
+
"zh_CN": "当前版本可能存在不兼容,建议尽快升级至最新版本。"
|
|
1257
|
+
},
|
|
1258
|
+
"version_update": {
|
|
1259
|
+
"en": "Update",
|
|
1260
|
+
"zh_CN": "升级"
|
|
1261
|
+
},
|
|
1262
|
+
"version_continue": {
|
|
1263
|
+
"en": "You can continue using the current version; commands will proceed.",
|
|
1264
|
+
"zh_CN": "你可以继续使用当前版本;命令将继续执行。"
|
|
1265
|
+
},
|
|
1266
|
+
"version_prompt_update_now": {
|
|
1267
|
+
"en": "Update now to the latest version?",
|
|
1268
|
+
"zh_CN": "是否立即更新到最新版本?"
|
|
1269
|
+
},
|
|
1270
|
+
"version_update_failed": {
|
|
1271
|
+
"en": "Global update failed. You may need elevated permissions (sudo) or use yarn/pnpm:",
|
|
1272
|
+
"zh_CN": "全局更新失败。你可能需要更高权限(sudo)或使用 yarn/pnpm:"
|
|
1273
|
+
},
|
|
1274
|
+
"deploy_option_keyword": {
|
|
1275
|
+
"en": "Keyword to search for routines",
|
|
1276
|
+
"zh_CN": ""
|
|
1277
|
+
},
|
|
1278
|
+
"route_input_method": {
|
|
1279
|
+
"en": "How would you like to input the route?",
|
|
1280
|
+
"zh_CN": "您希望如何输入路由?"
|
|
1281
|
+
},
|
|
1282
|
+
"route_input_builder": {
|
|
1283
|
+
"en": "Use route builder (prefix + suffix)",
|
|
1284
|
+
"zh_CN": "使用路由构建器(前缀 + 后缀)"
|
|
1285
|
+
},
|
|
1286
|
+
"route_input_manual": {
|
|
1287
|
+
"en": "Enter route manually",
|
|
1288
|
+
"zh_CN": "手动输入路由"
|
|
1289
|
+
},
|
|
1290
|
+
"route_build_cancelled": {
|
|
1291
|
+
"en": "Route building cancelled",
|
|
1292
|
+
"zh_CN": "路由构建已取消"
|
|
1293
|
+
},
|
|
1294
|
+
"route_builder_prefix_prompt": {
|
|
1295
|
+
"en": "Enter route prefix for ${siteName} (e.g., api, v1):",
|
|
1296
|
+
"zh_CN": "为 ${siteName} 输入路由前缀(例如:api, v1):"
|
|
1297
|
+
},
|
|
1298
|
+
"route_builder_suffix_prompt": {
|
|
1299
|
+
"en": "Enter route suffix for ${siteName} (e.g., *, users/*):",
|
|
1300
|
+
"zh_CN": "为 ${siteName} 输入路由后缀(例如:*, users/*):"
|
|
1301
|
+
},
|
|
1302
|
+
"route_builder_preview": {
|
|
1303
|
+
"en": "Preview: ${siteName}${prefix}${suffix}",
|
|
1304
|
+
"zh_CN": "预览:{route}"
|
|
1305
|
+
},
|
|
1306
|
+
"route_builder_instructions": {
|
|
1307
|
+
"en": "Press Enter to continue, Ctrl+C to cancel",
|
|
1308
|
+
"zh_CN": "按回车键继续,Ctrl+C 取消"
|
|
1237
1309
|
}
|
|
1238
1310
|
}
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ import routeCommand from './commands/route/index.js';
|
|
|
24
24
|
import routine from './commands/routine/index.js';
|
|
25
25
|
import site from './commands/site/index.js';
|
|
26
26
|
import t from './i18n/index.js';
|
|
27
|
-
import { handleCheckVersion } from './utils/checkVersion.js';
|
|
27
|
+
import { handleCheckVersion, checkCLIVersion } from './utils/checkVersion.js';
|
|
28
28
|
import { getCliConfig } from './utils/fileUtils/index.js';
|
|
29
29
|
const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
30
30
|
const argv = hideBin(process.argv);
|
|
@@ -39,6 +39,16 @@ const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
39
39
|
.version(false)
|
|
40
40
|
.wrap(null)
|
|
41
41
|
.help()
|
|
42
|
+
.middleware((argv) => __awaiter(void 0, void 0, void 0, function* () {
|
|
43
|
+
try {
|
|
44
|
+
// Pass current command (first positional) so version check can decide prompting behavior
|
|
45
|
+
yield checkCLIVersion((argv._ && argv._[0] ? String(argv._[0]) : ''));
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
console.log(e);
|
|
49
|
+
console.log('error');
|
|
50
|
+
}
|
|
51
|
+
}))
|
|
42
52
|
.epilogue(`${t('main_epilogue').d('For more information, visit ESA')}: ${chalk.underline.blue('https://www.aliyun.com/product/esa')}`)
|
|
43
53
|
.options('version', {
|
|
44
54
|
describe: t('main_version_describe').d('Show version'),
|
package/dist/libs/apiService.js
CHANGED
|
@@ -219,7 +219,7 @@ export class ApiService {
|
|
|
219
219
|
return null;
|
|
220
220
|
});
|
|
221
221
|
}
|
|
222
|
-
listUserRoutines() {
|
|
222
|
+
listUserRoutines(requestParams) {
|
|
223
223
|
return __awaiter(this, void 0, void 0, function* () {
|
|
224
224
|
try {
|
|
225
225
|
let params = {
|
|
@@ -236,7 +236,9 @@ export class ApiService {
|
|
|
236
236
|
return this;
|
|
237
237
|
}
|
|
238
238
|
};
|
|
239
|
-
let request = new $OpenApi.OpenApiRequest(
|
|
239
|
+
let request = new $OpenApi.OpenApiRequest({
|
|
240
|
+
query: requestParams || {}
|
|
241
|
+
});
|
|
240
242
|
let runtime = {
|
|
241
243
|
toMap: function () {
|
|
242
244
|
return this;
|
package/dist/libs/logger.js
CHANGED
|
@@ -175,8 +175,47 @@ class Logger {
|
|
|
175
175
|
console.log(message);
|
|
176
176
|
}
|
|
177
177
|
notInProject() {
|
|
178
|
-
|
|
179
|
-
this.error(
|
|
178
|
+
this.block();
|
|
179
|
+
this.error('Missing ESA project configuration (esa.jsonc or esa.toml)');
|
|
180
|
+
this.block();
|
|
181
|
+
this.log('If there is code to deploy, you can either:');
|
|
182
|
+
this.subLog(`- Specify an entry-point to your Routine via the command line (ex: ${chalk.green('esa deploy src/index.ts')})`);
|
|
183
|
+
this.subLog('- Or add the following to your "esa.jsonc" file:');
|
|
184
|
+
console.log('```jsonc\n' +
|
|
185
|
+
'{\n' +
|
|
186
|
+
' "name": "my-routine",\n' +
|
|
187
|
+
' "entry": "src/index.ts",\n' +
|
|
188
|
+
' "dev": { "port": 18080 }\n' +
|
|
189
|
+
'}\n' +
|
|
190
|
+
'```');
|
|
191
|
+
this.subLog('- Or, if you prefer TOML, add to your "esa.toml":');
|
|
192
|
+
console.log('```toml\n' +
|
|
193
|
+
'name = "my-routine"\n' +
|
|
194
|
+
'entry = "src/index.ts"\n' +
|
|
195
|
+
'\n' +
|
|
196
|
+
'[dev]\n' +
|
|
197
|
+
'port = 18080\n' +
|
|
198
|
+
'```\n');
|
|
199
|
+
this.log('If you are deploying a directory of static assets, you can either:');
|
|
200
|
+
this.subLog(`- Add the assets directory to your "esa.jsonc" and run ${chalk.green('esa deploy -a ./dist')}`);
|
|
201
|
+
console.log('```jsonc\n' +
|
|
202
|
+
'{\n' +
|
|
203
|
+
' "name": "my-routine",\n' +
|
|
204
|
+
' "assets": {\n' +
|
|
205
|
+
' "directory": "./dist"\n' +
|
|
206
|
+
' }\n' +
|
|
207
|
+
'}\n' +
|
|
208
|
+
'```');
|
|
209
|
+
this.subLog(`- Or add to your "esa.toml" and run ${chalk.green('esa deploy -a ./dist')}`);
|
|
210
|
+
console.log('```toml\n' +
|
|
211
|
+
'name = "my-routine"\n' +
|
|
212
|
+
'\n' +
|
|
213
|
+
'[assets]\n' +
|
|
214
|
+
'directory = "./dist"\n' +
|
|
215
|
+
'```\n');
|
|
216
|
+
this.log('Alternatively, initialize a new ESA project:');
|
|
217
|
+
this.log(chalk.green('$ esa init my-routine'));
|
|
218
|
+
this.block();
|
|
180
219
|
}
|
|
181
220
|
pathEacces(localPath) {
|
|
182
221
|
this.block();
|
|
@@ -8,11 +8,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import { exit } from 'process';
|
|
11
|
+
import { log } from '@clack/prompts';
|
|
11
12
|
import chalk from 'chalk';
|
|
12
13
|
import t from '../i18n/index.js';
|
|
13
14
|
import { ApiService } from '../libs/apiService.js';
|
|
14
15
|
import logger from '../libs/logger.js';
|
|
15
|
-
import { log } from '@clack/prompts';
|
|
16
16
|
export function isRoutineExist(name) {
|
|
17
17
|
return __awaiter(this, void 0, void 0, function* () {
|
|
18
18
|
const server = yield ApiService.getInstance();
|
|
@@ -48,17 +48,10 @@ export function ensureRoutineExists(name) {
|
|
|
48
48
|
});
|
|
49
49
|
const isSuccess = (createRes === null || createRes === void 0 ? void 0 : createRes.data.Status) === 'OK';
|
|
50
50
|
if (isSuccess) {
|
|
51
|
-
// logger.endSubStep(
|
|
52
|
-
// t('routine_create_success').d('Routine created successfully.')
|
|
53
|
-
// );
|
|
54
51
|
logger.endSubStep('Routine created successfully');
|
|
55
|
-
// tlog.success(
|
|
56
|
-
// t('routine_create_success').d('Routine created successfully.')
|
|
57
|
-
// );
|
|
58
52
|
}
|
|
59
53
|
else {
|
|
60
54
|
logger.endSubStep('Routine created failed');
|
|
61
|
-
// tlog.error(t('routine_create_fail').d('Routine created failed.'));
|
|
62
55
|
exit();
|
|
63
56
|
}
|
|
64
57
|
}
|
|
@@ -9,6 +9,12 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import { promises as fs } from 'fs';
|
|
11
11
|
import path from 'path';
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
import inquirer from 'inquirer';
|
|
14
|
+
import fetch from 'node-fetch';
|
|
15
|
+
import t from '../i18n/index.js';
|
|
16
|
+
import logger from '../libs/logger.js';
|
|
17
|
+
import execCommand from '../utils/command.js';
|
|
12
18
|
import { getDirName } from '../utils/fileUtils/base.js';
|
|
13
19
|
export function handleCheckVersion() {
|
|
14
20
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -24,3 +30,115 @@ export function handleCheckVersion() {
|
|
|
24
30
|
}
|
|
25
31
|
});
|
|
26
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* 检查CLI是否为最新版本,如果不是则提示用户更新
|
|
35
|
+
* @returns 是否为最新版本
|
|
36
|
+
*/
|
|
37
|
+
export function checkCLIVersion(currentCommand) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
try {
|
|
40
|
+
const __dirname = getDirName(import.meta.url);
|
|
41
|
+
const packageJsonPath = path.join(__dirname, '..', '..', 'package.json');
|
|
42
|
+
const jsonString = yield fs.readFile(packageJsonPath, 'utf-8');
|
|
43
|
+
const packageJson = JSON.parse(jsonString);
|
|
44
|
+
const currentVersion = packageJson.version;
|
|
45
|
+
const response = yield fetch('https://registry.npmjs.org/esa-cli/latest');
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
const data = (yield response.json());
|
|
50
|
+
const latestVersion = data.version;
|
|
51
|
+
if (currentVersion !== latestVersion) {
|
|
52
|
+
const accent = chalk.hex('#7C3AED').bold;
|
|
53
|
+
const labelColor = chalk.hex('#22c55e');
|
|
54
|
+
const currentLabelRaw = t('version_current').d('Current');
|
|
55
|
+
const latestLabelRaw = t('version_latest').d('Latest');
|
|
56
|
+
const noteLabelRaw = t('version_note').d('Note');
|
|
57
|
+
const updateLabelRaw = t('version_update').d('Update');
|
|
58
|
+
const labelsRaw = [
|
|
59
|
+
currentLabelRaw,
|
|
60
|
+
latestLabelRaw,
|
|
61
|
+
noteLabelRaw,
|
|
62
|
+
updateLabelRaw
|
|
63
|
+
];
|
|
64
|
+
const labelWidth = Math.max(...labelsRaw.map((l) => l.length));
|
|
65
|
+
const gap = ' ';
|
|
66
|
+
const padLabel = (raw, colored) => `${colored}${' '.repeat(labelWidth - raw.length)}`;
|
|
67
|
+
const lines = [
|
|
68
|
+
`${accent('🚀 ' + t('version_title_update_available').d('ESA CLI Update Available'))}`,
|
|
69
|
+
'',
|
|
70
|
+
`${padLabel(currentLabelRaw, labelColor(currentLabelRaw))}${gap}${chalk.yellowBright('v' + currentVersion)}`,
|
|
71
|
+
`${padLabel(latestLabelRaw, labelColor(latestLabelRaw))}${gap}${chalk.greenBright('v' + latestVersion)}`,
|
|
72
|
+
'',
|
|
73
|
+
`${padLabel(noteLabelRaw, chalk.yellowBright.bold(noteLabelRaw))}${gap}${chalk.yellowBright(t('version_note_incompatible').d('This version may have incompatibilities, please upgrade soon.'))}`,
|
|
74
|
+
'',
|
|
75
|
+
`${padLabel(updateLabelRaw, labelColor(updateLabelRaw))}${gap}${chalk.cyanBright('npm i -g esa-cli@latest')}`,
|
|
76
|
+
`${' '.repeat(labelWidth)}${gap}${chalk.cyanBright('yarn global add esa-cli@latest')}`,
|
|
77
|
+
`${' '.repeat(labelWidth)}${gap}${chalk.cyanBright('pnpm add -g esa-cli@latest')}`,
|
|
78
|
+
'',
|
|
79
|
+
`${chalk.gray(t('version_continue').d('You can continue using the current version; commands will proceed.'))}`
|
|
80
|
+
];
|
|
81
|
+
// Render with deploy-success-style box (cyan double border)
|
|
82
|
+
const stripAnsi = (s) => s.replace(/\x1B\[[0-?]*[ -\/]*[@-~]/g, '');
|
|
83
|
+
const contentWidth = Math.max(...lines.map((l) => stripAnsi(l).length));
|
|
84
|
+
const borderColor = chalk.hex('#00D4FF').bold;
|
|
85
|
+
const top = `${borderColor('╔')}${borderColor('═'.repeat(contentWidth + 2))}${borderColor('╗')}`;
|
|
86
|
+
const bottom = `${borderColor('╚')}${borderColor('═'.repeat(contentWidth + 2))}${borderColor('╝')}`;
|
|
87
|
+
const box = [
|
|
88
|
+
top,
|
|
89
|
+
...lines.map((l) => {
|
|
90
|
+
const pad = ' '.repeat(contentWidth - stripAnsi(l).length);
|
|
91
|
+
const left = borderColor('║');
|
|
92
|
+
const right = borderColor('║');
|
|
93
|
+
return `${left} ${l}${pad} ${right}`;
|
|
94
|
+
}),
|
|
95
|
+
bottom
|
|
96
|
+
];
|
|
97
|
+
logger.block();
|
|
98
|
+
box.forEach((l) => logger.log(l));
|
|
99
|
+
logger.block();
|
|
100
|
+
// Only prompt interactively on init command; others just display notice
|
|
101
|
+
if (currentCommand === 'init') {
|
|
102
|
+
const { updateNow } = yield inquirer.prompt([
|
|
103
|
+
{
|
|
104
|
+
type: 'confirm',
|
|
105
|
+
name: 'updateNow',
|
|
106
|
+
message: chalk.bold(t('version_prompt_update_now').d('Update now to the latest version?')),
|
|
107
|
+
default: true
|
|
108
|
+
}
|
|
109
|
+
]);
|
|
110
|
+
if (updateNow) {
|
|
111
|
+
const startText = 'Updating ESA CLI to latest (npm i -g esa-cli@latest)';
|
|
112
|
+
const doneText = 'ESA CLI update finished';
|
|
113
|
+
try {
|
|
114
|
+
const res = yield execCommand(['npm', 'i', '-g', 'esa-cli@latest'], {
|
|
115
|
+
startText,
|
|
116
|
+
doneText,
|
|
117
|
+
useSpinner: true,
|
|
118
|
+
interactive: false
|
|
119
|
+
});
|
|
120
|
+
if (!res.success) {
|
|
121
|
+
logger.warn(t('version_update_failed').d('Global update failed. You may need elevated permissions (sudo) or use yarn/pnpm:'));
|
|
122
|
+
logger.subLog('sudo npm i -g esa-cli@latest');
|
|
123
|
+
logger.subLog('yarn global add esa-cli@latest');
|
|
124
|
+
logger.subLog('pnpm add -g esa-cli@latest');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
catch (e) {
|
|
128
|
+
logger.warn(t('version_update_failed').d('Global update failed. You may need elevated permissions (sudo) or use yarn/pnpm:'));
|
|
129
|
+
logger.subLog('sudo npm i -g esa-cli@latest');
|
|
130
|
+
logger.subLog('yarn global add esa-cli@latest');
|
|
131
|
+
logger.subLog('pnpm add -g esa-cli@latest');
|
|
132
|
+
}
|
|
133
|
+
logger.divider();
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|