esa-cli 0.0.2-beta.10 → 0.0.2-beta.13

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 (75) hide show
  1. package/dist/commands/commit/index.js +26 -115
  2. package/dist/commands/commit/prodBuild.js +2 -3
  3. package/dist/commands/common/routineUtils.js +276 -0
  4. package/dist/commands/config.js +1 -1
  5. package/dist/commands/deploy/helper.js +40 -61
  6. package/dist/commands/deploy/index.js +90 -188
  7. package/dist/commands/deployments/delete.js +32 -22
  8. package/dist/commands/deployments/index.js +2 -2
  9. package/dist/commands/deployments/list.js +22 -38
  10. package/dist/commands/dev/build.js +3 -3
  11. package/dist/commands/dev/doProcess.js +5 -5
  12. package/dist/commands/dev/ew2/cacheService.js +33 -0
  13. package/dist/commands/dev/ew2/devEntry.js +2 -1
  14. package/dist/commands/dev/ew2/devPack.js +22 -11
  15. package/dist/commands/dev/ew2/kvService.js +27 -0
  16. package/dist/commands/dev/ew2/mock/cache.js +99 -15
  17. package/dist/commands/dev/ew2/mock/kv.js +142 -21
  18. package/dist/commands/dev/ew2/server.js +162 -27
  19. package/dist/commands/dev/index.js +14 -15
  20. package/dist/commands/dev/mockWorker/devPack.js +16 -7
  21. package/dist/commands/dev/mockWorker/server.js +7 -6
  22. package/dist/commands/domain/add.js +2 -2
  23. package/dist/commands/domain/delete.js +7 -7
  24. package/dist/commands/domain/index.js +2 -2
  25. package/dist/commands/domain/list.js +10 -10
  26. package/dist/commands/init/helper.js +87 -13
  27. package/dist/commands/init/index.js +461 -57
  28. package/dist/commands/init/template.jsonc +34 -0
  29. package/dist/commands/lang.js +2 -2
  30. package/dist/commands/login/index.js +57 -7
  31. package/dist/commands/logout.js +5 -5
  32. package/dist/commands/route/add.js +138 -49
  33. package/dist/commands/route/delete.js +33 -27
  34. package/dist/commands/route/helper.js +124 -0
  35. package/dist/commands/route/index.js +2 -2
  36. package/dist/commands/route/list.js +56 -17
  37. package/dist/commands/routine/delete.js +2 -2
  38. package/dist/commands/routine/index.js +2 -2
  39. package/dist/commands/routine/list.js +9 -21
  40. package/dist/commands/site/index.js +1 -1
  41. package/dist/commands/site/list.js +6 -7
  42. package/dist/commands/utils.js +55 -19
  43. package/dist/components/descriptionInput.js +1 -1
  44. package/dist/components/mutiSelectTable.js +1 -1
  45. package/dist/components/selectInput.js +2 -3
  46. package/dist/components/selectItem.js +1 -1
  47. package/dist/docs/Commands_en.md +25 -15
  48. package/dist/docs/Commands_zh_CN.md +12 -2
  49. package/dist/docs/eslint-config-en.md +1 -0
  50. package/dist/docs/eslint-config.md +73 -0
  51. package/dist/docs/init-command-quick-test.md +208 -0
  52. package/dist/docs/init-command-test-guide.md +598 -0
  53. package/dist/i18n/index.js +2 -2
  54. package/dist/i18n/locales.json +261 -17
  55. package/dist/index.js +17 -12
  56. package/dist/libs/api.js +32 -9
  57. package/dist/libs/apiService.js +258 -85
  58. package/dist/libs/git/index.js +8 -4
  59. package/dist/libs/interface.js +0 -1
  60. package/dist/libs/logger.js +63 -7
  61. package/dist/libs/service.js +2 -2
  62. package/dist/libs/templates/index.js +1 -1
  63. package/dist/utils/checkAssetsExist.js +80 -0
  64. package/dist/utils/checkDevPort.js +3 -17
  65. package/dist/utils/checkEntryFileExist.js +10 -0
  66. package/dist/utils/checkIsRoutineCreated.js +16 -31
  67. package/dist/utils/checkVersion.js +1 -1
  68. package/dist/utils/compress.js +80 -0
  69. package/dist/utils/download.js +5 -5
  70. package/dist/utils/fileMd5.js +1 -1
  71. package/dist/utils/fileUtils/index.js +71 -22
  72. package/dist/utils/installDeno.js +3 -3
  73. package/dist/utils/installEw2.js +7 -7
  74. package/dist/utils/openInBrowser.js +1 -1
  75. package/package.json +11 -6
@@ -7,13 +7,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { getProjectConfig } from '../../utils/fileUtils/index.js';
11
10
  import Table from 'cli-table3';
12
- import { checkDirectory, checkIsLoginSuccess } from '../utils.js';
13
- import { ApiService } from '../../libs/apiService.js';
14
- import logger from '../../libs/logger.js';
15
11
  import t from '../../i18n/index.js';
12
+ import api from '../../libs/api.js';
13
+ import logger from '../../libs/logger.js';
16
14
  import { validRoutine } from '../../utils/checkIsRoutineCreated.js';
15
+ import { getProjectConfig } from '../../utils/fileUtils/index.js';
16
+ import { checkDirectory, checkIsLoginSuccess } from '../utils.js';
17
+ import { transferRuleStringToRoute } from './helper.js';
17
18
  const listRoute = {
18
19
  command: 'list',
19
20
  describe: `🔍 ${t('route_list_describe').d('List all related routes')}`,
@@ -24,7 +25,7 @@ const listRoute = {
24
25
  export default listRoute;
25
26
  export function handleListRoutes() {
26
27
  return __awaiter(this, void 0, void 0, function* () {
27
- var _a, _b;
28
+ var _a;
28
29
  if (!checkDirectory()) {
29
30
  return;
30
31
  }
@@ -35,29 +36,67 @@ export function handleListRoutes() {
35
36
  if (!isSuccess)
36
37
  return;
37
38
  yield validRoutine(projectConfig.name);
38
- const server = yield ApiService.getInstance();
39
- const req = { Name: projectConfig.name };
40
- const routineDetail = yield server.getRoutine(req);
41
- if (!routineDetail)
42
- return;
43
- const relatedRoutes = (_b = (_a = routineDetail.data) === null || _a === void 0 ? void 0 : _a.RelatedRoutes) !== null && _b !== void 0 ? _b : [];
44
- if (relatedRoutes.length === 0) {
39
+ const req = {
40
+ routineName: projectConfig.name
41
+ };
42
+ const res = yield api.listRoutineRoutes(req);
43
+ const configs = ((_a = res.body) === null || _a === void 0 ? void 0 : _a.configs) || [];
44
+ if (configs.length === 0) {
45
45
  logger.warn(`🙅 ${t('route_list_empty').d('No related routes found')}`);
46
46
  return;
47
47
  }
48
- logger.log(`📃 ${t('route_list_title').d('Related routes')}:`);
49
- displayRelatedRouteList(relatedRoutes);
48
+ const simpleRoutes = configs
49
+ .filter((item) => item.mode !== 'custom')
50
+ .map((config) => {
51
+ var _a, _b, _c;
52
+ return {
53
+ RouteName: (_a = config.routeName) !== null && _a !== void 0 ? _a : '',
54
+ Route: transferRuleStringToRoute((_b = config.rule) !== null && _b !== void 0 ? _b : ''),
55
+ SiteName: (_c = config.siteName) !== null && _c !== void 0 ? _c : ''
56
+ };
57
+ });
58
+ if (simpleRoutes.length > 0) {
59
+ logger.log(`📃 ${t('route_list_simple_title').d('Related simple mode routes')}:`);
60
+ displayRelatedRouteList(simpleRoutes);
61
+ }
62
+ const customRoutes = configs
63
+ .filter((item) => item.mode === 'custom')
64
+ .map((config) => {
65
+ var _a, _b, _c;
66
+ return {
67
+ RouteName: (_a = config.routeName) !== null && _a !== void 0 ? _a : '',
68
+ Route: (_b = config.rule) !== null && _b !== void 0 ? _b : '',
69
+ SiteName: (_c = config.siteName) !== null && _c !== void 0 ? _c : ''
70
+ };
71
+ });
72
+ if (customRoutes.length > 0) {
73
+ logger.log(`📃 ${t('route_list_custom_title').d('Related custom mode routes')}:`);
74
+ displayRelatedRouteRuleList(customRoutes);
75
+ }
50
76
  });
51
77
  }
52
78
  export function displayRelatedRouteList(routeList) {
53
79
  return __awaiter(this, void 0, void 0, function* () {
54
80
  const table = new Table({
55
- head: ['Route', 'Site'],
56
- colWidths: [30, 30]
81
+ head: ['Route Name', 'Route', 'Site'],
82
+ colWidths: [20]
83
+ });
84
+ for (let i = 0; i < routeList.length; i++) {
85
+ const route = routeList[i];
86
+ table.push([route.RouteName, route.Route, route.SiteName]);
87
+ }
88
+ console.log(table.toString());
89
+ });
90
+ }
91
+ export function displayRelatedRouteRuleList(routeList) {
92
+ return __awaiter(this, void 0, void 0, function* () {
93
+ const table = new Table({
94
+ head: ['Route Name', 'Rule', 'Site'],
95
+ colWidths: [20]
57
96
  });
58
97
  for (let i = 0; i < routeList.length; i++) {
59
98
  const route = routeList[i];
60
- table.push([route.Route, route.SiteName]);
99
+ table.push([route.RouteName, route.Route, route.SiteName]);
61
100
  }
62
101
  console.log(table.toString());
63
102
  });
@@ -7,10 +7,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import { checkIsLoginSuccess } from '../utils.js';
11
- import { ApiService } from '../../libs/apiService.js';
12
10
  import t from '../../i18n/index.js';
11
+ import { ApiService } from '../../libs/apiService.js';
13
12
  import logger from '../../libs/logger.js';
13
+ import { checkIsLoginSuccess } from '../utils.js';
14
14
  const deleteCommand = {
15
15
  command: 'delete <routineName>',
16
16
  describe: `🗑 ${t('delete_describe').d('Delete a routine')}`,
@@ -1,6 +1,6 @@
1
- import routineList from './list.js';
2
- import routineDelete from './delete.js';
3
1
  import t from '../../i18n/index.js';
2
+ import routineDelete from './delete.js';
3
+ import routineList from './list.js';
4
4
  let yargsIns;
5
5
  const routineCommand = {
6
6
  command: 'routine [script]',
@@ -7,25 +7,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- var __rest = (this && this.__rest) || function (s, e) {
11
- var t = {};
12
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
13
- t[p] = s[p];
14
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
15
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
16
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
17
- t[p[i]] = s[p[i]];
18
- }
19
- return t;
20
- };
10
+ import chalk from 'chalk';
21
11
  import Table from 'cli-table3';
12
+ import moment from 'moment';
13
+ import t from '../../i18n/index.js';
14
+ import { ApiService } from '../../libs/apiService.js';
22
15
  import logger from '../../libs/logger.js';
23
- import { Base64 } from 'js-base64';
24
16
  import { checkIsLoginSuccess } from '../utils.js';
25
- import chalk from 'chalk';
26
- import { ApiService } from '../../libs/apiService.js';
27
- import t from '../../i18n/index.js';
28
- import moment from 'moment';
29
17
  const list = {
30
18
  command: 'list',
31
19
  describe: `📋 ${t('list_describe').d('List all your routines')}`,
@@ -39,8 +27,8 @@ const list = {
39
27
  export default list;
40
28
  export function handleList(argv) {
41
29
  return __awaiter(this, void 0, void 0, function* () {
42
- var _a;
43
- const { site } = argv, args = __rest(argv, ["site"]);
30
+ var _a, _b;
31
+ const { site } = argv;
44
32
  const isSuccess = yield checkIsLoginSuccess();
45
33
  if (!isSuccess)
46
34
  return;
@@ -59,8 +47,8 @@ export function handleList(argv) {
59
47
  logger.tree(siteNameList);
60
48
  return;
61
49
  }
62
- const res = yield server.getRoutineUserInfo();
63
- const routineList = res === null || res === void 0 ? void 0 : res.Routines;
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;
64
52
  if (routineList) {
65
53
  logger.log(chalk.bold.bgGray(`📃 ${t('list_routine_name_title').d('List all of routine')}:`));
66
54
  displayRoutineList(routineList);
@@ -77,7 +65,7 @@ export function displayRoutineList(versionList) {
77
65
  table.push([
78
66
  version.RoutineName,
79
67
  moment(version.CreateTime).format('YYYY/MM/DD HH:mm:ss'),
80
- Base64.decode(version.Description)
68
+ version.Description
81
69
  ]);
82
70
  });
83
71
  console.table(table.toString());
@@ -1,5 +1,5 @@
1
- import siteList from './list.js';
2
1
  import t from '../../i18n/index.js';
2
+ import siteList from './list.js';
3
3
  let yargsIns;
4
4
  const siteCommand = {
5
5
  command: 'site [script]',
@@ -7,25 +7,24 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import logger from '../../libs/logger.js';
11
- import { checkIsLoginSuccess } from '../utils.js';
12
10
  import chalk from 'chalk';
13
- import { ApiService } from '../../libs/apiService.js';
14
11
  import t from '../../i18n/index.js';
12
+ import { ApiService } from '../../libs/apiService.js';
13
+ import logger from '../../libs/logger.js';
14
+ import { checkIsLoginSuccess } from '../utils.js';
15
15
  const list = {
16
16
  command: 'list',
17
17
  describe: `📋 ${t('site_describe_list').d('List all your sites')}`,
18
18
  builder: (yargs) => {
19
19
  return yargs.usage(`${t('common_usage').d('Usage')}: \$0 list []`);
20
20
  },
21
- handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
22
- handleList(argv);
21
+ handler: () => __awaiter(void 0, void 0, void 0, function* () {
22
+ handleList();
23
23
  })
24
24
  };
25
25
  export default list;
26
- export function handleList(argv) {
26
+ export function handleList() {
27
27
  return __awaiter(this, void 0, void 0, function* () {
28
- // const { site, ...args } = argv;
29
28
  var _a;
30
29
  const isSuccess = yield checkIsLoginSuccess();
31
30
  if (!isSuccess)
@@ -7,15 +7,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import fs from 'fs';
11
10
  import { execSync } from 'child_process';
12
- import { isInstalledGit } from '../libs/git/index.js';
13
- import { getCliConfig, projectConfigPath } from '../utils/fileUtils/index.js';
14
- import { getRoot } from '../utils/fileUtils/base.js';
11
+ import fs from 'fs';
15
12
  import chalk from 'chalk';
16
13
  import t from '../i18n/index.js';
14
+ import api from '../libs/api.js';
17
15
  import { ApiService } from '../libs/apiService.js';
16
+ import { isInstalledGit } from '../libs/git/index.js';
18
17
  import logger from '../libs/logger.js';
18
+ import { getRoot } from '../utils/fileUtils/base.js';
19
+ import { getCliConfig, projectConfigPath } from '../utils/fileUtils/index.js';
20
+ import { getRoutineDetails } from './common/routineUtils.js';
19
21
  export const checkDirectory = (isCheckGit = false) => {
20
22
  const root = getRoot();
21
23
  if (fs.existsSync(projectConfigPath)) {
@@ -66,13 +68,6 @@ export const bindRoutineWithDomain = (name, domain) => __awaiter(void 0, void 0,
66
68
  logger.error(t('utils_domain_error').d('Domain is not active'));
67
69
  }
68
70
  });
69
- export const getRoutineVersionList = (name) => __awaiter(void 0, void 0, void 0, function* () {
70
- var _a;
71
- const server = yield ApiService.getInstance();
72
- const req = { Name: name };
73
- const res = yield server.getRoutine(req);
74
- return ((_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.CodeVersions) || [];
75
- });
76
71
  export function validName(name) {
77
72
  return /^[a-zA-Z0-9-_]+$/.test(name);
78
73
  }
@@ -82,25 +77,56 @@ export function validDomain(domain) {
82
77
  }
83
78
  export function checkIsLoginSuccess() {
84
79
  return __awaiter(this, void 0, void 0, function* () {
80
+ var _a, _b;
81
+ let accessKeyId = process.env.ESA_ACCESS_KEY_ID;
82
+ let accessKeySecret = process.env.ESA_ACCESS_KEY_SECRET;
83
+ let endpoint = process.env.ESA_ENDPOINT;
85
84
  const cliConfig = getCliConfig();
86
- const namedCommand = chalk.green('esa login');
87
- if (!cliConfig || !cliConfig.auth) {
88
- return false;
85
+ if (!accessKeyId || !accessKeySecret) {
86
+ accessKeyId = (_a = cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.auth) === null || _a === void 0 ? void 0 : _a.accessKeyId;
87
+ accessKeySecret = (_b = cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.auth) === null || _b === void 0 ? void 0 : _b.accessKeySecret;
88
+ }
89
+ if (!endpoint) {
90
+ endpoint = cliConfig === null || cliConfig === void 0 ? void 0 : cliConfig.endpoint;
89
91
  }
90
- if (!cliConfig.auth.accessKeyId || !cliConfig.auth.accessKeySecret) {
92
+ const namedCommand = chalk.green('esa login');
93
+ if (!accessKeyId || !accessKeySecret) {
91
94
  logger.log(`❌ ${t('utils_login_error').d('Maybe you are not logged in yet.')}`);
92
95
  logger.log(`🔔 ${t('utils_login_error_config', { namedCommand }).d(`Please run command to login: ${namedCommand}`)}`);
93
96
  return false;
94
97
  }
98
+ return yield validateLoginCredentials(accessKeyId, accessKeySecret, endpoint, namedCommand);
99
+ });
100
+ }
101
+ /**
102
+ * 验证登录凭据的公共函数
103
+ * @param accessKeyId AccessKey ID
104
+ * @param accessKeySecret AccessKey Secret
105
+ * @param namedCommand 命令名称(用于错误提示)
106
+ * @param showError 是否显示错误信息
107
+ * @returns 登录是否成功
108
+ */
109
+ export function validateLoginCredentials(accessKeyId_1, accessKeySecret_1, endpoint_1, namedCommand_1) {
110
+ return __awaiter(this, arguments, void 0, function* (accessKeyId, accessKeySecret, endpoint, namedCommand, showError = true) {
95
111
  const server = yield ApiService.getInstance();
96
- server.updateConfig(cliConfig);
112
+ server.updateConfig({
113
+ auth: {
114
+ accessKeyId,
115
+ accessKeySecret
116
+ },
117
+ endpoint: endpoint
118
+ });
97
119
  const res = yield server.checkLogin();
98
120
  if (res.success) {
99
121
  return true;
100
122
  }
101
- logger.log(res.message || '');
102
- logger.log(`❌ ${t('utils_login_error').d('Maybe you are not logged in yet.')}`);
103
- logger.log(`🔔 ${t('utils_login_error_config', { namedCommand }).d(`Please run command to login: ${namedCommand}`)}`);
123
+ if (showError) {
124
+ logger.log(res.message || '');
125
+ logger.log(`❌ ${t('utils_login_error').d('Maybe you are not logged in yet.')}`);
126
+ if (namedCommand) {
127
+ logger.log(`🔔 ${t('utils_login_error_config', { namedCommand }).d(`Please run command to login: ${namedCommand}`)}`);
128
+ }
129
+ }
104
130
  return false;
105
131
  });
106
132
  }
@@ -138,3 +164,13 @@ export const getAllSites = () => __awaiter(void 0, void 0, void 0, function* ()
138
164
  };
139
165
  });
140
166
  });
167
+ export const getRoutineCodeVersions = (projectName) => __awaiter(void 0, void 0, void 0, function* () {
168
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
169
+ const routineDetail = yield getRoutineDetails(projectName);
170
+ const req = { name: projectName };
171
+ const res = yield api.listRoutineCodeVersions(req);
172
+ const allVersions = (_b = (_a = res.body) === null || _a === void 0 ? void 0 : _a.codeVersions) !== null && _b !== void 0 ? _b : [];
173
+ const stagingVersions = ((_g = (_f = (_e = (_d = (_c = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _c === void 0 ? void 0 : _c.Envs) === null || _d === void 0 ? void 0 : _d.find((item) => item.Env === 'staging')) === null || _e === void 0 ? void 0 : _e.CodeDeploy) === null || _f === void 0 ? void 0 : _f.CodeVersions) === null || _g === void 0 ? void 0 : _g.map((item) => item.CodeVersion)) || [];
174
+ const productionVersions = ((_m = (_l = (_k = (_j = (_h = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _h === void 0 ? void 0 : _h.Envs) === null || _j === void 0 ? void 0 : _j.find((item) => item.Env === 'production')) === null || _k === void 0 ? void 0 : _k.CodeDeploy) === null || _l === void 0 ? void 0 : _l.CodeVersions) === null || _m === void 0 ? void 0 : _m.map((item) => item.CodeVersion)) || [];
175
+ return { allVersions, stagingVersions, productionVersions };
176
+ });
@@ -7,9 +7,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import React, { useState } from 'react';
11
10
  import { Box, render, Text } from 'ink';
12
11
  import TextInput from 'ink-text-input';
12
+ import React, { useState } from 'react';
13
13
  export const DescriptionInput = ({ prompt, onSubmit, required }) => {
14
14
  const [input, setInput] = useState('');
15
15
  const [error, setError] = useState('');
@@ -7,8 +7,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import React, { useState } from 'react';
11
10
  import { Box, render, Text, useInput } from 'ink';
11
+ import React, { useState } from 'react';
12
12
  import t from '../i18n/index.js';
13
13
  export const MultiSelectTable = ({ items, itemsPerRow, onSubmit, boxWidth = 25 }) => {
14
14
  const [selectedIndexes, setSelectedIndexes] = useState(new Set());
@@ -1,7 +1,6 @@
1
- import React from 'react';
2
- import { render } from 'ink';
1
+ import { render, Text } from 'ink';
3
2
  import SelectInput from 'ink-select-input';
4
- import { Text } from 'ink';
3
+ import React from 'react';
5
4
  import Item from './selectItem.js';
6
5
  const Indicator = ({ isSelected }) => {
7
6
  return React.createElement(Text, null, isSelected ? '👉 ' : ' ');
@@ -1,5 +1,5 @@
1
- import * as React from 'react';
2
1
  import { Text } from 'ink';
2
+ import * as React from 'react';
3
3
  function Item({ isSelected = false, label }) {
4
4
  return React.createElement(Text, { color: isSelected ? 'green' : undefined }, label);
5
5
  }
@@ -2,19 +2,29 @@
2
2
 
3
3
  ### init
4
4
 
5
- Initialize a routine with a template.
6
-
5
+ Initialize a project using a framework or a template.
6
+
7
7
  ```bash
8
8
  $ esa init [OPTIONS]
9
9
  ```
10
10
 
11
+ - -f, --framework `string` `optional`
12
+ - Choose a frontend framework: `react` | `vue` | `next`.
13
+
14
+ - -t, --template `string` `optional`
15
+ - Use an ESA template by name.
16
+
11
17
  - -c, --config `boolean` `optional`
12
- - Generate a config file for your project.
18
+ - Generate an `esa.toml` config file in your project.
19
+
20
+ Notes:
21
+ - If neither `--framework` nor `--template` is provided and `--yes` is not used, you will be prompted to choose between “Framework” or “Template”.
22
+ - When a framework is chosen, the official scaffolding tool will be used to create the project, and `esa.toml` will be auto-generated in the project root. The entry file is auto-detected among: `src/index.js`, `src/index.jsx`, `src/index.tsx`, `src/main.js`, `src/main.ts`, `src/main.tsx`, `pages/index.js`, `pages/index.tsx`, `app/page.js`, `app/page.tsx`. The static assets directory is set to the framework’s common build output if available: CRA `build/`, Vite usually `dist/`, Next static export `out/`.
13
23
 
14
24
  ### routine [script]
15
25
 
16
26
  Manage your routine.
17
-
27
+
18
28
  #### delete <routineName>
19
29
 
20
30
  Delete a routine.
@@ -37,7 +47,7 @@ $ esa routine list
37
47
  ### route [script]
38
48
 
39
49
  Manage the routes bound to your routine.
40
-
50
+
41
51
  #### add [route] [site]
42
52
 
43
53
  Bind a Route to a routine.
@@ -68,7 +78,7 @@ $ esa route list
68
78
  ### login
69
79
 
70
80
  Login to the server.
71
-
81
+
72
82
  ```bash
73
83
  $ esa login
74
84
  ```
@@ -76,7 +86,7 @@ $ esa login
76
86
  ### dev [entry]
77
87
 
78
88
  Start a local server for developing your routine.
79
-
89
+
80
90
  ```bash
81
91
  $ esa dev [entry] [OPTIONS]
82
92
  ```
@@ -102,7 +112,7 @@ $ esa dev [entry] [OPTIONS]
102
112
  ### deployments [script]
103
113
 
104
114
  Manage your deployments.
105
-
115
+
106
116
  #### delete <deploymentId>
107
117
 
108
118
  Delete one or more deployment versions.
@@ -125,7 +135,7 @@ $ esa deployments list
125
135
  ### deploy [entry]
126
136
 
127
137
  Deploy your project.
128
-
138
+
129
139
  ```bash
130
140
  $ esa deploy [entry]
131
141
  ```
@@ -136,7 +146,7 @@ $ esa deploy [entry]
136
146
  ### domain [script]
137
147
 
138
148
  Manage the domain names bound to your routine.
139
-
149
+
140
150
  #### add <domain>
141
151
 
142
152
  Bind a domain to a routine.
@@ -170,7 +180,7 @@ $ esa domain list
170
180
  ### commit [entry]
171
181
 
172
182
  Commit your code, save as a new version.
173
-
183
+
174
184
  ```bash
175
185
  $ esa commit [entry] [OPTIONS]
176
186
  ```
@@ -184,7 +194,7 @@ $ esa commit [entry] [OPTIONS]
184
194
  ### logout
185
195
 
186
196
  Logout.
187
-
197
+
188
198
  ```bash
189
199
  $ esa logout
190
200
  ```
@@ -192,7 +202,7 @@ $ esa logout
192
202
  ### config
193
203
 
194
204
  Modify your local or global configuration using -l, -g.
195
-
205
+
196
206
  ```bash
197
207
  $ esa config [OPTIONS]
198
208
  ```
@@ -206,7 +216,7 @@ $ esa config [OPTIONS]
206
216
  ### lang
207
217
 
208
218
  Set the language of the CLI.
209
-
219
+
210
220
  ```bash
211
221
  $ esa lang
212
222
  ```
@@ -214,7 +224,7 @@ $ esa lang
214
224
  ### site [script]
215
225
 
216
226
  Manage your sites.
217
-
227
+
218
228
  #### list
219
229
 
220
230
  List all your sites.
@@ -2,14 +2,24 @@
2
2
 
3
3
  ### init
4
4
 
5
- 选择模版初始化项目。
5
+ 选择框架或模版初始化项目。
6
6
 
7
7
  ```bash
8
8
  $ esa init [OPTIONS]
9
9
  ```
10
10
 
11
+ - -f, --framework `string` `optional`
12
+ - 选择前端框架初始化项目,支持:`react` | `vue` | `next`。
13
+
14
+ - -t, --template `string` `optional`
15
+ - 指定 ESA 模版名称初始化项目。
16
+
11
17
  - -c, --config `boolean` `optional`
12
- - 在您的项目中生成一个esa.toml配置文件。
18
+ - 在您的项目中生成一个 `esa.toml` 配置文件。
19
+
20
+ 说明:
21
+ - 未指定 `--framework` 与 `--template` 且未使用 `--yes` 时,会先询问选择“框架初始化”或“模版初始化”。
22
+ - 选择框架后将调用对应官方脚手架创建项目,并在新项目根目录自动生成 `esa.toml`。入口文件会自动探测,候选包括:`src/index.js`、`src/index.jsx`、`src/index.tsx`、`src/main.js`、`src/main.ts`、`src/main.tsx`、`pages/index.js`、`pages/index.tsx`、`app/page.js`、`app/page.tsx`。静态资源目录会根据框架常规构建输出自动设置,例如 CRA 为 `build/`、Vite 通常为 `dist/`(若存在),Next 静态导出使用 `out/`(若存在)。
13
23
 
14
24
  ### routine [script]
15
25
 
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,73 @@
1
+ # ESLint 配置说明
2
+
3
+ 本项目已配置ESLint来检查代码质量,包括以下功能:
4
+
5
+ ## 已配置的检查规则
6
+
7
+ ### 1. Import 排序检查
8
+
9
+ - **规则**: `import/order`
10
+ - **功能**: 自动排序import语句,按照以下顺序:
11
+ 1. Node.js 内置模块 (如 `fs`, `path`)
12
+ 2. 第三方模块 (如 `react`, `lodash`)
13
+ 3. 内部模块 (项目内部文件)
14
+ 4. 父级模块 (`../`)
15
+ 5. 同级模块 (`./`)
16
+ 6. 当前目录的 index 文件
17
+ - **格式**: 每组之间用空行分隔,按字母顺序排列
18
+
19
+ ### 2. 引号检查
20
+
21
+ - **规则**: `quotes`, `@typescript-eslint/quotes`
22
+ - **功能**: 强制使用单引号
23
+ - **例外**: 允许在需要转义的情况下使用双引号,支持模板字符串
24
+
25
+ ### 3. 多余变量检查
26
+
27
+ - **规则**: `@typescript-eslint/no-unused-vars`
28
+ - **功能**: 检查未使用的变量、参数和导入
29
+ - **例外**: 以 `_` 开头的变量会被忽略(如 `_unusedVariable`)
30
+
31
+ ### 4. 其他检查
32
+
33
+ - **重复导入检查**: `import/no-duplicates`
34
+ - **未使用表达式检查**: `no-unused-expressions`
35
+ - **TypeScript类型检查**: 警告使用 `any` 类型
36
+
37
+ ## 使用方法
38
+
39
+ ### 检查代码
40
+
41
+ ```bash
42
+ npm run eslint
43
+ ```
44
+
45
+ ### 自动修复
46
+
47
+ ```bash
48
+ npm run eslint -- --fix
49
+ ```
50
+
51
+ ### 检查特定文件
52
+
53
+ ```bash
54
+ npx eslint src/commands/example.ts
55
+ ```
56
+
57
+ ## 配置说明
58
+
59
+ 配置文件位于 `.eslintrc.cjs`,主要包含:
60
+
61
+ - **解析器**: `@typescript-eslint/parser` 用于解析TypeScript代码
62
+ - **插件**:
63
+ - `react` 和 `react-hooks` 用于React相关检查
64
+ - `import` 用于import相关检查
65
+ - `@typescript-eslint` 用于TypeScript特定检查
66
+ - **规则**: 详细的代码质量规则配置
67
+ - **设置**: TypeScript import解析器配置
68
+
69
+ ## 注意事项
70
+
71
+ 1. 如果遇到TypeScript版本警告,这是正常的,不影响功能
72
+ 2. 未使用的变量请以 `_` 开头命名,这样ESLint会忽略它们
73
+ 3. 自动修复功能可以解决大部分格式问题,但逻辑问题需要手动修复