esa-cli 0.0.2-beta.20 → 0.0.2-beta.21

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.
@@ -72,7 +72,8 @@ export const transferRouteToRuleString = (routePath) => {
72
72
  export const transferRuleStringToRoute = (ruleStr) => {
73
73
  if (!ruleStr) {
74
74
  return '';
75
- } // Remove outer brackets and split by " and "
75
+ }
76
+ // 去掉外层括号并按 " and " 分割
76
77
  const cleanedRule = ruleStr.replace(/^\(|\)$/g, '');
77
78
  const parts = cleanedRule.split(' and ');
78
79
  if (parts.length !== 2) {
@@ -80,36 +81,36 @@ export const transferRuleStringToRoute = (ruleStr) => {
80
81
  }
81
82
  let host = '';
82
83
  let uriPath = '';
83
- // Process host part
84
+ // 处理host部分
84
85
  const hostPart = parts[0].trim();
85
86
  if (hostPart.startsWith(`${RuleMatchOperatorEndsWith}(${RuleMatchTypeHost},`)) {
86
- // Logic when host matches eq
87
+ // host匹配eq时的逻辑
87
88
  // ends_with(http.host, "value")
88
89
  const match = hostPart.match(/ends_with\(http\.host,\s*"([^"]+)"\)/);
89
90
  if (match) {
90
- host = `*${match[1]}`; // Add prefix *
91
+ host = `*${match[1]}`; // 加前缀 *
91
92
  }
92
93
  }
93
94
  else if (hostPart.startsWith(`${RuleMatchTypeHost} ${RuleMatchOperatorEq}`)) {
94
- // Logic when host matches eq
95
+ // host匹配eq时的逻辑
95
96
  // http.host eq "value"
96
97
  const match = hostPart.match(/http\.host eq "([^"]+)"/);
97
98
  if (match) {
98
99
  host = match[1];
99
100
  }
100
101
  }
101
- // Process uriPath part
102
+ // 处理uriPath 部分
102
103
  const uriPathPart = parts[1].trim();
103
104
  if (uriPathPart.startsWith(`${RuleMatchOperatorStartsWith}(${RuleMatchTypeUriPath},`)) {
104
- // Logic when uriPath matches startsWith
105
+ // uriPath匹配startsWith时的逻辑
105
106
  // starts_with(http.request.uri.path, "value")
106
107
  const match = uriPathPart.match(/starts_with\(http\.request\.uri\.path,\s*"([^"]+)"\)/);
107
108
  if (match) {
108
- uriPath = `${match[1]}*`; // Add suffix *
109
+ uriPath = `${match[1]}*`; // 加后缀 *
109
110
  }
110
111
  }
111
112
  else if (uriPathPart.startsWith(`${RuleMatchTypeUriPath} ${RuleMatchOperatorEq}`)) {
112
- // Logic when uriPath matches eq
113
+ // uriPath匹配eq时的逻辑
113
114
  // http.request.uri.path eq "value"
114
115
  const match = uriPathPart.match(/http\.request\.uri\.path eq "([^"]+)"/);
115
116
  if (match) {
@@ -5,7 +5,7 @@ import listRoute from './list.js';
5
5
  let yargsIns;
6
6
  const routeCommand = {
7
7
  command: 'route [script]',
8
- describe: `🚀 ${t('route_describe').d('Manage the routes bound to your routine')}`,
8
+ describe: `🚄 ${t('route_describe').d('Manage the routes bound to your routine')}`,
9
9
  builder: (yargs) => {
10
10
  yargsIns = yargs;
11
11
  return yargs
@@ -4,7 +4,7 @@ import routineList from './list.js';
4
4
  let yargsIns;
5
5
  const routineCommand = {
6
6
  command: 'routine [script]',
7
- describe: `🚀 ${t('routine_describe').d('Manage your routine')}`,
7
+ describe: `🧭 ${t('routine_describe').d('Manage your routine')}`,
8
8
  builder: (yargs) => {
9
9
  yargsIns = yargs;
10
10
  return yargs
@@ -18,55 +18,37 @@ const list = {
18
18
  command: 'list',
19
19
  describe: `📋 ${t('list_describe').d('List all your routines')}`,
20
20
  builder: (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>]`);
21
+ return yargs.usage(`${t('common_usage').d('Usage')}: \$0 list []`);
28
22
  },
29
23
  handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
30
24
  handleList(argv);
31
25
  })
32
26
  };
33
27
  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
- }
62
28
  export function handleList(argv) {
63
29
  return __awaiter(this, void 0, void 0, function* () {
30
+ var _a, _b;
31
+ const { site } = argv;
64
32
  const isSuccess = yield checkIsLoginSuccess();
65
33
  if (!isSuccess)
66
34
  return;
67
- const routineList = yield getAllRoutines({
68
- SearchKeyWord: argv.keyword
69
- });
35
+ const server = yield ApiService.getInstance();
36
+ if (site) {
37
+ const req = {
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;
70
52
  if (routineList) {
71
53
  logger.log(chalk.bold.bgGray(`📃 ${t('list_routine_name_title').d('List all of routine')}:`));
72
54
  displayRoutineList(routineList);
@@ -3,7 +3,7 @@ import siteList from './list.js';
3
3
  let yargsIns;
4
4
  const siteCommand = {
5
5
  command: 'site [script]',
6
- describe: `🚀 ${t('site_describe').d('Manage your sites')}`,
6
+ describe: `📈 ${t('site_describe').d('Manage your sites')}`,
7
7
  builder: (yargs) => {
8
8
  yargsIns = yargs;
9
9
  return yargs
@@ -71,7 +71,7 @@ export const bindRoutineWithDomain = (name, domain) => __awaiter(void 0, void 0,
71
71
  export function validName(name) {
72
72
  return /^[a-zA-Z0-9-_]+$/.test(name);
73
73
  }
74
- // Validate if domain is valid
74
+ // 校验域名是否有效
75
75
  export function validDomain(domain) {
76
76
  return /^(?:[a-z0-9-](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/.test(domain);
77
77
  }
@@ -131,12 +131,12 @@ export function validateLoginCredentials(accessKeyId_1, accessKeySecret_1, endpo
131
131
  });
132
132
  }
133
133
  export function isValidRouteForDomain(route, domain) {
134
- // Build a regex that allows subdomains and arbitrary paths
135
- // For example, match URLs like *.example.com/*
134
+ // 构建一个允许子域和任意路径的正则表达式
135
+ // 例如,匹配形式如 *.example.com/* 的URL
136
136
  return route.includes(domain);
137
137
  }
138
138
  export function escapeRegExp(string) {
139
- return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& represents the entire matched string
139
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& 表示整个被匹配的字符串
140
140
  }
141
141
  export const getAllSites = () => __awaiter(void 0, void 0, void 0, function* () {
142
142
  var _a;
@@ -51,7 +51,7 @@ export const FilterSelector = ({ data, onSubmit, hideCount = 20 }) => {
51
51
  else if (tabPressCount === 1) {
52
52
  const filteredDataInner = data.filter((site) => site.label.includes(inputValue));
53
53
  setFilteredData(filteredDataInner);
54
- // Enter selection mode when match results >= 1
54
+ // 匹配结果大于等于1个时,进入选择模式
55
55
  if ((filteredDataInner.length >= 1 &&
56
56
  showAll &&
57
57
  filteredDataInner.length > hideCount) ||
@@ -204,8 +204,8 @@
204
204
  "zh_CN": "读取 CLI 配置错误"
205
205
  },
206
206
  "dev_error_no_project_config": {
207
- "en": "Error reading project configuration esa.jsonc (recommended) or esa.toml file.",
208
- "zh_CN": "读取项目配置 esa.jsonc (推荐) 或 esa.toml 文件错误"
207
+ "en": "Error reading project configuration esa.toml file.",
208
+ "zh_CN": "读取项目配置 esa.toml 文件错误"
209
209
  },
210
210
  "dev_build_start": {
211
211
  "en": "Starting build process",
@@ -1271,40 +1271,8 @@
1271
1271
  "en": "Global update failed. You may need elevated permissions (sudo) or use yarn/pnpm:",
1272
1272
  "zh_CN": "全局更新失败。你可能需要更高权限(sudo)或使用 yarn/pnpm:"
1273
1273
  },
1274
- "deploy_option_keyword": {
1275
- "en": "Keyword to search for routines",
1274
+ "kv_parse_failed": {
1275
+ "en": "kv.json parse failed, use empty local kv store.",
1276
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 取消"
1309
1277
  }
1310
1278
  }
@@ -90,6 +90,7 @@ export class ApiService {
90
90
  }
91
91
  }
92
92
  catch (error) {
93
+ console.log('error', error);
93
94
  return {
94
95
  success: false,
95
96
  message: t('login_failed').d('An error occurred while trying to log in.')
@@ -100,15 +101,15 @@ export class ApiService {
100
101
  quickDeployRoutine(edgeRoutine) {
101
102
  return __awaiter(this, void 0, void 0, function* () {
102
103
  try {
103
- // Upload code to unstable version
104
+ // 上传代码到unstable版本
104
105
  const stagingRes = yield this.getRoutineStagingCodeUploadInfo(edgeRoutine);
105
106
  if (stagingRes) {
106
- // Production version
107
+ // 生产版本
107
108
  const commitRes = yield this.commitRoutineStagingCode({
108
109
  Name: edgeRoutine.name,
109
110
  CodeDescription: edgeRoutine.description
110
111
  });
111
- // Deploy to production environment
112
+ // 发布到生产环境
112
113
  if (commitRes) {
113
114
  const deployRes = yield this.publishRoutineCodeVersion({
114
115
  Name: edgeRoutine.name,
@@ -218,7 +219,7 @@ export class ApiService {
218
219
  return null;
219
220
  });
220
221
  }
221
- listUserRoutines(requestParams) {
222
+ listUserRoutines() {
222
223
  return __awaiter(this, void 0, void 0, function* () {
223
224
  try {
224
225
  let params = {
@@ -235,9 +236,7 @@ export class ApiService {
235
236
  return this;
236
237
  }
237
238
  };
238
- let request = new $OpenApi.OpenApiRequest({
239
- query: requestParams || {}
240
- });
239
+ let request = new $OpenApi.OpenApiRequest();
241
240
  let runtime = {
242
241
  toMap: function () {
243
242
  return this;
@@ -180,7 +180,7 @@ class Logger {
180
180
  this.block();
181
181
  this.log('If there is code to deploy, you can either:');
182
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 create an "esa.jsonc" file (recommended):');
183
+ this.subLog('- Or add the following to your "esa.jsonc" file:');
184
184
  console.log('```jsonc\n' +
185
185
  '{\n' +
186
186
  ' "name": "my-routine",\n' +
@@ -188,7 +188,7 @@ class Logger {
188
188
  ' "dev": { "port": 18080 }\n' +
189
189
  '}\n' +
190
190
  '```');
191
- this.subLog('- Or, if you prefer TOML, create an "esa.toml" file:');
191
+ this.subLog('- Or, if you prefer TOML, add to your "esa.toml":');
192
192
  console.log('```toml\n' +
193
193
  'name = "my-routine"\n' +
194
194
  'entry = "src/index.ts"\n' +
@@ -197,7 +197,7 @@ class Logger {
197
197
  'port = 18080\n' +
198
198
  '```\n');
199
199
  this.log('If you are deploying a directory of static assets, you can either:');
200
- this.subLog(`- Create an "esa.jsonc" file (recommended) and run ${chalk.green('esa deploy -a ./dist')}`);
200
+ this.subLog(`- Add the assets directory to your "esa.jsonc" and run ${chalk.green('esa deploy -a ./dist')}`);
201
201
  console.log('```jsonc\n' +
202
202
  '{\n' +
203
203
  ' "name": "my-routine",\n' +
@@ -206,7 +206,7 @@ class Logger {
206
206
  ' }\n' +
207
207
  '}\n' +
208
208
  '```');
209
- this.subLog(`- Or create an "esa.toml" file and run ${chalk.green('esa deploy -a ./dist')}`);
209
+ this.subLog(`- Or add to your "esa.toml" and run ${chalk.green('esa deploy -a ./dist')}`);
210
210
  console.log('```toml\n' +
211
211
  'name = "my-routine"\n' +
212
212
  '\n' +
@@ -26,7 +26,7 @@ export function validRoutine(name) {
26
26
  const isCreatedRoutine = yield isRoutineExist(name);
27
27
  if (!isCreatedRoutine) {
28
28
  logger.warn(`${t('routine_not_exist').d('Routine does not exist, please create a new one. Run command:')} ${chalk.greenBright('esa deploy')}`);
29
- exit(1);
29
+ exit(0);
30
30
  }
31
31
  });
32
32
  }
@@ -43,10 +43,10 @@ const compress = (scriptEntry_1, assetsDir_1, ...args_1) => __awaiter(void 0, [s
43
43
  let assetsDirectory = assetsDir || ((_a = projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.assets) === null || _a === void 0 ? void 0 : _a.directory);
44
44
  const routineType = checkEdgeRoutineType(scriptEntry, assetsDir, projectPath);
45
45
  if (!projectConfig && !scriptEntry && !assetsDir) {
46
- logger.error('esa.jsonc (recommended) or esa.toml is not found and script entry or assets directory is not provided by command line');
47
- exit(1);
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);
48
48
  }
49
- // Parameter priority: use parameters if available, otherwise use values from config file
49
+ // 参数优先:如果有参数则使用参数,否则使用配置文件中的值
50
50
  const entry = scriptEntry || (projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.entry);
51
51
  if (routineType === EDGE_ROUTINE_TYPE.NOT_EXIST) {
52
52
  const errorMessage = [
@@ -61,7 +61,7 @@ const compress = (scriptEntry_1, assetsDir_1, ...args_1) => __awaiter(void 0, [s
61
61
  chalk.cyan('🔍 Possible issue causes:'),
62
62
  chalk.white(' 1. Entry file path is incorrect or file does not exist'),
63
63
  chalk.white(' 2. Assets directory path is incorrect or directory does not exist'),
64
- chalk.white(` 3. Project configuration file ${chalk.yellow('esa.jsonc')} (recommended) or ${chalk.yellow('esa.toml')} format error`),
64
+ chalk.white(` 3. Project configuration file ${chalk.yellow('esa.jsonc')} or ${chalk.yellow('esa.toml')} format error`),
65
65
  chalk.white(` 4. Relative path format error, please use ${chalk.yellow('./xxx')} format`),
66
66
  '',
67
67
  chalk.yellow.bold(`📍 Please check if the following ${chalk.red('absolute paths')} are correct:`),
@@ -83,7 +83,7 @@ const compress = (scriptEntry_1, assetsDir_1, ...args_1) => __awaiter(void 0, [s
83
83
  ''
84
84
  ].join('\n');
85
85
  logger.error(errorMessage);
86
- exit(1);
86
+ exit(0);
87
87
  }
88
88
  if (routineType === EDGE_ROUTINE_TYPE.JS_ONLY ||
89
89
  routineType === EDGE_ROUTINE_TYPE.JS_AND_ASSETS) {
@@ -92,8 +92,8 @@ function isBinDirInPath(binDir) {
92
92
  */
93
93
  function addBinDirToPath(binDir) {
94
94
  return __awaiter(this, void 0, void 0, function* () {
95
- // Use setx to add to PATH
96
- // setx has a 2047 character limit for PATH
95
+ // 使用 setx 添加到 PATH
96
+ // setx PATH 的长度有2047字符的限制
97
97
  const command = `setx Path "%Path%;${binDir}"`;
98
98
  try {
99
99
  yield execAsync(command);
@@ -17,31 +17,8 @@ import { getDirName, getRoot } from './base.js';
17
17
  const projectConfigFile = 'esa.toml';
18
18
  const __dirname = getDirName(import.meta.url);
19
19
  const root = getRoot();
20
- // Function to get the actual project config file path (supports both .jsonc and .toml)
21
- export const getProjectConfigPath = (filePath = root) => {
22
- const configFormats = ['esa.jsonc', 'esa.toml'];
23
- for (const format of configFormats) {
24
- const configPath = path.join(filePath, format);
25
- if (fs.existsSync(configPath)) {
26
- return configPath;
27
- }
28
- }
29
- // Default to .jsonc if no config file exists
30
- return path.join(filePath, 'esa.jsonc');
31
- };
32
- export const projectConfigPath = getProjectConfigPath();
20
+ export const projectConfigPath = path.join(root, projectConfigFile);
33
21
  export const cliConfigPath = path.join(os.homedir(), '.esa/config/default.toml');
34
- // Function to get the actual config file path (supports both .toml and .jsonc)
35
- export const getCliConfigPath = () => {
36
- const configDir = path.join(os.homedir(), '.esa/config');
37
- const jsoncPath = path.join(configDir, 'default.jsonc');
38
- const tomlPath = path.join(configDir, 'default.toml');
39
- // Check if JSONC file exists first, then fallback to TOML
40
- if (fs.existsSync(jsoncPath)) {
41
- return jsoncPath;
42
- }
43
- return tomlPath;
44
- };
45
22
  export const hiddenConfigDir = path.join(os.homedir(), '.esa/config');
46
23
  export const generateHiddenConfigDir = () => {
47
24
  if (!fs.existsSync(hiddenConfigDir)) {
@@ -51,7 +28,7 @@ export const generateHiddenConfigDir = () => {
51
28
  export const generateToml = (path) => {
52
29
  if (!fs.existsSync(path)) {
53
30
  fs.writeFileSync(path, '', 'utf-8');
54
- // Add default endpoint
31
+ // 添加默认的endpoint
55
32
  const defaultConfig = {
56
33
  endpoint: 'esa.cn-hangzhou.aliyuncs.com'
57
34
  };
@@ -60,34 +37,20 @@ export const generateToml = (path) => {
60
37
  };
61
38
  export const generateDefaultConfig = () => {
62
39
  generateHiddenConfigDir();
63
- const configPath = getCliConfigPath();
64
- generateToml(configPath);
40
+ generateToml(cliConfigPath);
65
41
  };
66
42
  export function updateProjectConfigFile(configUpdate_1) {
67
43
  return __awaiter(this, arguments, void 0, function* (configUpdate, filePath = root) {
68
- const configPath = getProjectConfigPath(filePath);
44
+ const configPath = path.join(filePath, projectConfigFile);
69
45
  try {
70
46
  let configFileContent = yield fsPromises.readFile(configPath, 'utf8');
71
- let config;
72
- let updatedConfigString;
73
- // Detect file format based on file extension
74
- if (configPath.endsWith('.jsonc') || configPath.endsWith('.json')) {
75
- // Handle JSONC format
76
- const jsonContent = configFileContent.replace(/\/\*[\s\S]*?\*\/|\/\/.*$/gm, '');
77
- config = JSON.parse(jsonContent);
78
- config = Object.assign(Object.assign({}, config), configUpdate);
79
- updatedConfigString = JSON.stringify(config, null, 2) + '\n';
80
- }
81
- else {
82
- // Handle TOML format (default)
83
- config = toml.parse(configFileContent);
84
- config = Object.assign(Object.assign({}, config), configUpdate);
85
- updatedConfigString = toml.stringify(config);
86
- }
47
+ let config = toml.parse(configFileContent);
48
+ config = Object.assign(Object.assign({}, config), configUpdate);
49
+ const updatedConfigString = toml.stringify(config);
87
50
  yield fsPromises.writeFile(configPath, updatedConfigString);
88
51
  }
89
52
  catch (error) {
90
- logger.error(`Error updating config file: ${error}`);
53
+ logger.error(`Error updating TOML file: ${error}`);
91
54
  logger.pathEacces(__dirname);
92
55
  }
93
56
  });
@@ -95,30 +58,16 @@ export function updateProjectConfigFile(configUpdate_1) {
95
58
  export function updateCliConfigFile(configUpdate) {
96
59
  return __awaiter(this, void 0, void 0, function* () {
97
60
  try {
98
- const configPath = getCliConfigPath();
99
- let configFileContent = yield fsPromises.readFile(configPath, 'utf8');
100
- let config;
101
- let updatedConfigString;
102
- // Detect file format based on file extension
103
- if (configPath.endsWith('.jsonc') || configPath.endsWith('.json')) {
104
- // Handle JSONC format
105
- const jsonContent = configFileContent.replace(/\/\*[\s\S]*?\*\/|\/\/.*$/gm, '');
106
- config = JSON.parse(jsonContent);
107
- config = Object.assign(Object.assign({}, config), configUpdate);
108
- updatedConfigString = JSON.stringify(config, null, 2) + '\n';
109
- }
110
- else {
111
- // Handle TOML format (default)
112
- config = toml.parse(configFileContent);
113
- config = Object.assign(Object.assign({}, config), configUpdate);
114
- updatedConfigString = toml.stringify(config);
115
- }
116
- yield fsPromises.writeFile(configPath, updatedConfigString);
61
+ let configFileContent = yield fsPromises.readFile(cliConfigPath, 'utf8');
62
+ let config = toml.parse(configFileContent);
63
+ config = Object.assign(Object.assign({}, config), configUpdate);
64
+ const updatedConfigString = toml.stringify(config);
65
+ yield fsPromises.writeFile(cliConfigPath, updatedConfigString);
117
66
  }
118
67
  catch (error) {
119
- logger.error(`Error updating config file: ${error}`);
68
+ logger.error(`Error updating TOML file: ${error}`);
120
69
  logger.pathEacces(__dirname);
121
- throw new Error('Config update error');
70
+ throw new Error('Login error');
122
71
  }
123
72
  });
124
73
  }
@@ -139,6 +88,7 @@ export function readConfigFile(configPath) {
139
88
  }
140
89
  }
141
90
  catch (error) {
91
+ console.log(error);
142
92
  logger.error(`Error parsing config file: ${error}`);
143
93
  return null;
144
94
  }
@@ -146,8 +96,7 @@ export function readConfigFile(configPath) {
146
96
  return null;
147
97
  }
148
98
  export function getCliConfig() {
149
- const configPath = getCliConfigPath();
150
- const res = readConfigFile(configPath);
99
+ const res = readConfigFile(cliConfigPath);
151
100
  if (!res) {
152
101
  return null;
153
102
  }
@@ -184,7 +133,7 @@ export function getConfigurations() {
184
133
  }
185
134
  }
186
135
  export function generateConfigFile(projectName_1, initConfigs_1, targetDir_1) {
187
- return __awaiter(this, arguments, void 0, function* (projectName, initConfigs, targetDir, configFormat = 'jsonc', notFoundStrategy) {
136
+ return __awaiter(this, arguments, void 0, function* (projectName, initConfigs, targetDir, configFormat = 'toml', notFoundStrategy) {
188
137
  var _a, _b;
189
138
  const outputDir = targetDir !== null && targetDir !== void 0 ? targetDir : process.cwd();
190
139
  const currentDirName = path.basename(outputDir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esa-cli",
3
- "version": "0.0.2-beta.20",
3
+ "version": "0.0.2-beta.21",
4
4
  "description": "A CLI for operating Alibaba Cloud ESA EdgeRoutine (Edge Functions).",
5
5
  "main": "bin/enter.cjs",
6
6
  "type": "module",
@@ -54,6 +54,7 @@
54
54
  "@types/yargs": "^17.0.32",
55
55
  "@typescript-eslint/eslint-plugin": "^6.21.0",
56
56
  "@typescript-eslint/parser": "^6.9.1",
57
+ "eslint-plugin-react": "latest",
57
58
  "husky": "^8.0.3",
58
59
  "jsdom": "^25.0.1",
59
60
  "lint-staged": "^15.0.2",
@@ -1,68 +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
- 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
- });