esa-cli 0.0.2-beta.16 → 0.0.2-beta.19

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.
@@ -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
+ });
@@ -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 boolean: Deploy 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
@@ -70,7 +70,7 @@ esa deploy [entry]
70
70
  - -v, --version string:指定要部署的版本(跳过交互选择)
71
71
  - -e, --environment string:部署环境。可选:staging | production
72
72
  - -n, --name string:边缘函数名称
73
- - -a, --assets boolean:是否部署静态资源
73
+ - -a, --assets string:静态资源目录(例如:./dist)
74
74
  - -d, --description string:版本描述
75
75
  - -m, --minify boolean:是否压缩代码
76
76
 
@@ -115,7 +115,7 @@ esa site list
115
115
  ```
116
116
 
117
117
  - 子命令:
118
- - list:列出所有站点
118
+ - list:列出所有已激活站点
119
119
 
120
120
  ---
121
121
 
@@ -151,6 +151,39 @@ esa route delete <routeName>
151
151
  - list:查看所有已绑定路由
152
152
  - delete `<routeName>`:删除已绑定路由
153
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
+
154
187
  ---
155
188
 
156
189
  ### esa login
@@ -164,6 +197,9 @@ esa login
164
197
  - 选项:
165
198
  - --access-key-id, --ak string:AccessKey ID (AK)
166
199
  - --access-key-secret, --sk string:AccessKey Secret (SK)
200
+ - 从环境变量中读取process.env
201
+ - ESA_ACCESS_KEY_ID
202
+ - ESA_ACCESS_KEY_SECRET
167
203
 
168
204
  ---
169
205
 
@@ -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'),
@@ -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;
@@ -175,8 +175,47 @@ class Logger {
175
175
  console.log(message);
176
176
  }
177
177
  notInProject() {
178
- const initCommand = chalk.green('esa init');
179
- this.error(t('common_not_edge_project', { initCommand }).d(`You are not in an esa project, Please run ${initCommand} to initialize a project, or enter an esa project.`));
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
+ }
@@ -36,12 +36,15 @@ const compress = (scriptEntry_1, assetsDir_1, ...args_1) => __awaiter(void 0, [s
36
36
  var _a;
37
37
  let code;
38
38
  const zip = new AdmZip();
39
+ const fileList = [];
40
+ const sourceList = [];
41
+ const dynamicSources = [];
39
42
  const projectConfig = getProjectConfig(projectPath);
40
43
  let assetsDirectory = assetsDir || ((_a = projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.assets) === null || _a === void 0 ? void 0 : _a.directory);
41
- assetsDirectory = path.resolve(projectPath !== null && projectPath !== void 0 ? projectPath : '', assetsDirectory !== null && assetsDirectory !== void 0 ? assetsDirectory : '');
42
44
  const routineType = checkEdgeRoutineType(scriptEntry, assetsDir, projectPath);
43
- if (!projectConfig) {
44
- throw new Error('Project config not found');
45
+ if (!projectConfig && !scriptEntry && !assetsDir) {
46
+ logger.error('esa.jsonc or esa.toml is not found and script entry or assets directory is not provided by command line');
47
+ exit(0);
45
48
  }
46
49
  // 参数优先:如果有参数则使用参数,否则使用配置文件中的值
47
50
  const entry = scriptEntry || (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.entry);
@@ -50,11 +53,10 @@ const compress = (scriptEntry_1, assetsDir_1, ...args_1) => __awaiter(void 0, [s
50
53
  chalk.red.bold('❌ File upload failed'),
51
54
  '',
52
55
  chalk.cyan('📋 Current configuration information:'),
53
- `${chalk.white(' 📁 Project path:')} ${chalk.yellow(projectPath || chalk.gray(t('compress_not_specified').d('Not specified')))}`,
54
- `${chalk.white(' 📄 Entry file:')} ${chalk.yellow(scriptEntry ||
56
+ `${chalk.white(` 📄 Entry file ${chalk.yellow('(dynamic)')} :`)} ${chalk.yellow(scriptEntry ||
55
57
  (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.entry) ||
56
58
  chalk.gray(t('compress_not_configured').d('Not configured')))}`,
57
- `${chalk.white(' 🗂️ Assets directory:')} ${chalk.yellow(assetsDirectory || chalk.gray(t('compress_not_configured').d('Not configured')))}`,
59
+ `${chalk.white(` 🗂️ Assets directory ${chalk.yellow('(static)')} :`)} ${chalk.yellow(assetsDirectory || chalk.gray(t('compress_not_configured').d('Not configured')))}`,
58
60
  '',
59
61
  chalk.cyan('🔍 Possible issue causes:'),
60
62
  chalk.white(' 1. Entry file path is incorrect or file does not exist'),
@@ -70,7 +72,7 @@ const compress = (scriptEntry_1, assetsDir_1, ...args_1) => __awaiter(void 0, [s
70
72
  : []),
71
73
  ...(assetsDirectory
72
74
  ? [
73
- `${chalk.white(' 🗂️ Assets directory:')} ${chalk.cyan.bold(path.resolve(projectPath !== null && projectPath !== void 0 ? projectPath : '', assetsDirectory))} ${chalk.gray(t('compress_check_directory_exists').d('(Check if directory exists)'))}`
75
+ `${chalk.white(' 🗂️ Assets directory:')} ${chalk.cyan.bold(path.resolve(projectPath !== null && projectPath !== void 0 ? projectPath : '', assetsDirectory))} ${chalk.gray(t('compress_check_directory_exists').d('(Check if directory exists)'))}`
74
76
  ]
75
77
  : []),
76
78
  ...(!scriptEntry && !(projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.entry) && !assetsDirectory
@@ -89,6 +91,13 @@ const compress = (scriptEntry_1, assetsDir_1, ...args_1) => __awaiter(void 0, [s
89
91
  yield prodBuild(minify, buildEntry, projectPath);
90
92
  code = readEdgeRoutineFile(projectPath);
91
93
  zip.addFile(`routine/index.js`, Buffer.from(code || ''));
94
+ fileList.push('routine/index.js');
95
+ const relativeEntry = path
96
+ .relative(projectPath !== null && projectPath !== void 0 ? projectPath : '', buildEntry)
97
+ .split(path.sep)
98
+ .join('/');
99
+ sourceList.push(relativeEntry);
100
+ dynamicSources.push(relativeEntry);
92
101
  }
93
102
  assetsDirectory = path.resolve(projectPath !== null && projectPath !== void 0 ? projectPath : '', assetsDirectory !== null && assetsDirectory !== void 0 ? assetsDirectory : '');
94
103
  // Add all files in the assets directory to the /assets directory
@@ -106,13 +115,22 @@ const compress = (scriptEntry_1, assetsDir_1, ...args_1) => __awaiter(void 0, [s
106
115
  }
107
116
  else {
108
117
  const fileContent = fs.readFileSync(fullPath);
109
- const relativePath = path.relative(assetsDirectory, fullPath);
118
+ const relativePath = path
119
+ .relative(assetsDirectory, fullPath)
120
+ .split(path.sep)
121
+ .join('/');
110
122
  zip.addFile(`assets/${relativePath}`, fileContent);
123
+ fileList.push(`assets/${relativePath}`);
124
+ const relativeSrcPath = path
125
+ .relative(projectPath !== null && projectPath !== void 0 ? projectPath : '', fullPath)
126
+ .split(path.sep)
127
+ .join('/');
128
+ sourceList.push(relativeSrcPath);
111
129
  }
112
130
  }
113
131
  };
114
132
  addDirectoryToZip(assetsDirectory, 'assets');
115
133
  }
116
- return zip;
134
+ return { zip, fileList, sourceList, dynamicSources };
117
135
  });
118
136
  export default compress;