esa-cli 0.0.2-beta.9 → 0.0.5

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.
@@ -32,11 +32,14 @@ export function yesNoPromptAndExecute(message, execute) {
32
32
  }
33
33
  export function promptSelectVersion(versionList) {
34
34
  const items = versionList
35
- .filter((version) => version.CodeVersion !== 'unstable')
36
- .map((version, index) => ({
37
- label: version.CodeVersion,
38
- value: String(index)
39
- }));
35
+ .filter((version) => version.codeVersion !== 'unstable')
36
+ .map((version, index) => {
37
+ var _a;
38
+ return ({
39
+ label: (_a = version.codeVersion) !== null && _a !== void 0 ? _a : '',
40
+ value: String(index)
41
+ });
42
+ });
40
43
  return new Promise((resolve) => {
41
44
  const handleSelection = (item) => __awaiter(this, void 0, void 0, function* () {
42
45
  resolve(item.label);
@@ -13,7 +13,6 @@ import { Environment, PublishType } from '../../libs/interface.js';
13
13
  import logger from '../../libs/logger.js';
14
14
  import { checkDirectory, checkIsLoginSuccess, getRoutineVersionList } from '../utils.js';
15
15
  import { displayMultiSelectTable } from '../../components/mutiSelectTable.js';
16
- import { Base64 } from 'js-base64';
17
16
  import { ApiService } from '../../libs/apiService.js';
18
17
  import { createAndDeployVersion, displaySelectDeployType, promptSelectVersion, yesNoPromptAndExecute } from './helper.js';
19
18
  import t from '../../i18n/index.js';
@@ -64,7 +63,7 @@ export function quickDeploy(entry, projectConfig) {
64
63
  }
65
64
  export function handleDeploy(argv) {
66
65
  return __awaiter(this, void 0, void 0, function* () {
67
- var _a, _b, _c, _d, _e;
66
+ var _a, _b, _c, _d;
68
67
  if (!checkDirectory()) {
69
68
  return;
70
69
  }
@@ -79,10 +78,10 @@ export function handleDeploy(argv) {
79
78
  yield checkRoutineExist(projectConfig.name, entry);
80
79
  const req = { Name: projectConfig.name };
81
80
  const routineDetail = yield server.getRoutine(req, false);
82
- const versionList = ((_a = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _a === void 0 ? void 0 : _a.CodeVersions) || [];
81
+ const versionList = yield getRoutineVersionList(projectConfig.name);
83
82
  const customEntry = argv.entry;
84
- const stagingVersion = (_c = (_b = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _b === void 0 ? void 0 : _b.Envs[1]) === null || _c === void 0 ? void 0 : _c.CodeVersion;
85
- const productionVersion = (_e = (_d = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _d === void 0 ? void 0 : _d.Envs[0]) === null || _e === void 0 ? void 0 : _e.CodeVersion;
83
+ const stagingVersion = (_b = (_a = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _a === void 0 ? void 0 : _a.Envs[1]) === null || _b === void 0 ? void 0 : _b.CodeVersion;
84
+ const productionVersion = (_d = (_c = routineDetail === null || routineDetail === void 0 ? void 0 : routineDetail.data) === null || _c === void 0 ? void 0 : _c.Envs[0]) === null || _d === void 0 ? void 0 : _d.CodeVersion;
86
85
  if (argv.quick) {
87
86
  yield quickDeploy(customEntry, projectConfig);
88
87
  exit(0);
@@ -179,6 +178,7 @@ export function deploySelectedCodeVersion(name, selectedType, version) {
179
178
  }
180
179
  export function displayVersionList(versionList_1) {
181
180
  return __awaiter(this, arguments, void 0, function* (versionList, stagingVersion = 'unstable', productionVersion = 'unstable') {
181
+ var _a;
182
182
  logger.log(`${chalk.bgYellow('Active')} ${t('deploy_env_staging').d('Staging')}`);
183
183
  logger.log(`${chalk.bgGreen('Active')} ${t('deploy_env_production').d('Production')}`);
184
184
  const data = [];
@@ -186,13 +186,13 @@ export function displayVersionList(versionList_1) {
186
186
  const version = versionList[i];
187
187
  const createTime = moment(version.CreateTime).format('YYYY/MM/DD HH:mm:ss');
188
188
  const tags = [
189
- version.CodeVersion === stagingVersion ? chalk.bgYellow('Active') : '',
190
- version.CodeVersion === productionVersion ? chalk.bgGreen('Active') : ''
189
+ version.codeVersion === stagingVersion ? chalk.bgYellow('Active') : '',
190
+ version.codeVersion === productionVersion ? chalk.bgGreen('Active') : ''
191
191
  ];
192
192
  data.push([
193
- `${version.CodeVersion} ${tags.join(' ')}`,
193
+ `${version.codeVersion} ${tags.join(' ')}`,
194
194
  createTime,
195
- Base64.decode(version.CodeDescription)
195
+ (_a = version.codeDescription) !== null && _a !== void 0 ? _a : ''
196
196
  ]);
197
197
  }
198
198
  logger.table([
@@ -128,7 +128,6 @@ class Ew2Server {
128
128
  }
129
129
  createServer() {
130
130
  this.server = http.createServer((req, res) => __awaiter(this, void 0, void 0, function* () {
131
- var _a;
132
131
  try {
133
132
  const host = req.headers.host;
134
133
  const url = req.url;
@@ -148,18 +147,20 @@ class Ew2Server {
148
147
  // 解决 gzip 兼容性问题,防止net::ERR_CONTENT_DECODING_FAILED
149
148
  workerHeaders['content-encoding'] = 'identity';
150
149
  if (workerRes.body) {
151
- if ((_a = workerRes.headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.includes('text/')) {
152
- const text = yield workerRes.text();
153
- // 出现换行符之类会导致 content-length 不一致
154
- workerHeaders['content-length'] =
155
- Buffer.byteLength(text).toString();
156
- res.writeHead(workerRes.status, workerHeaders);
157
- res.end(text);
158
- }
159
- else {
160
- res.writeHead(workerRes.status, workerHeaders);
161
- workerRes.body.pipe(res);
162
- }
150
+ // if (workerRes.headers.get('content-type')?.includes('text/')) {
151
+ // const text = await workerRes.text();
152
+ // // 出现换行符之类会导致 content-length 不一致
153
+ // workerHeaders['content-length'] =
154
+ // Buffer.byteLength(text).toString();
155
+ // console.log(workerHeaders['content-length']);
156
+ // res.writeHead(workerRes.status, workerHeaders);
157
+ // res.end(text);
158
+ // } else {
159
+ // res.writeHead(workerRes.status, workerHeaders);
160
+ // workerRes.body.pipe(res);
161
+ // }
162
+ res.writeHead(workerRes.status, workerHeaders);
163
+ workerRes.body.pipe(res);
163
164
  logger.log(`[ESA Dev] ${req.method} ${url} ${getColorForStatusCode(workerRes.status, workerRes.statusText)}`);
164
165
  }
165
166
  else {
@@ -31,7 +31,7 @@ const deleteDomain = {
31
31
  export default deleteDomain;
32
32
  export function handleDeleteDomain(argv) {
33
33
  return __awaiter(this, void 0, void 0, function* () {
34
- var _a, _b;
34
+ var _a;
35
35
  if (!checkDirectory()) {
36
36
  return;
37
37
  }
@@ -44,10 +44,10 @@ export function handleDeleteDomain(argv) {
44
44
  yield validRoutine(projectConfig.name);
45
45
  const server = yield ApiService.getInstance();
46
46
  const req = { Name: projectConfig.name || '' };
47
- const routineDetail = yield server.getRoutine(req);
48
- if (!routineDetail)
47
+ const listRoutineRelatedRecordRes = yield server.listRoutineRelatedRecords(req);
48
+ if (!listRoutineRelatedRecordRes)
49
49
  return;
50
- const relatedRecords = (_b = (_a = routineDetail.data) === null || _a === void 0 ? void 0 : _a.RelatedRecords) !== null && _b !== void 0 ? _b : [];
50
+ const relatedRecords = ((_a = listRoutineRelatedRecordRes.data) === null || _a === void 0 ? void 0 : _a.RelatedRecords) || [];
51
51
  const relatedDomain = argv.domain;
52
52
  const matchedSite = relatedRecords.find((item) => {
53
53
  return String(item.RecordName) === relatedDomain;
@@ -36,10 +36,10 @@ export function handleListDomains(argv) {
36
36
  yield validRoutine(projectConfig.name);
37
37
  const server = yield ApiService.getInstance();
38
38
  const req = { Name: projectConfig.name };
39
- const routineDetail = yield server.getRoutine(req);
40
- if (!routineDetail)
39
+ const res = yield server.listRoutineRelatedRecords(req);
40
+ if (!res)
41
41
  return;
42
- const relatedRecords = (_b = (_a = routineDetail.data) === null || _a === void 0 ? void 0 : _a.RelatedRecords) !== null && _b !== void 0 ? _b : [];
42
+ const relatedRecords = (_b = (_a = res.data) === null || _a === void 0 ? void 0 : _a.RelatedRecords) !== null && _b !== void 0 ? _b : [];
43
43
  if (relatedRecords.length === 0) {
44
44
  logger.log(`🙅 ${t('domain_list_empty').d('No related domains found')}`);
45
45
  return;
@@ -15,8 +15,8 @@ import logger from '../../libs/logger.js';
15
15
  import { execSync } from 'child_process';
16
16
  import t from '../../i18n/index.js';
17
17
  import chalk from 'chalk';
18
- import { getDirName } from '../../utils/fileUtils/base.js';
19
18
  import inquirer from 'inquirer';
19
+ import { getDirName } from '../../utils/fileUtils/base.js';
20
20
  export const getTemplateInstances = (templateHubPath) => {
21
21
  return fs
22
22
  .readdirSync(templateHubPath)
@@ -73,6 +73,7 @@ export function checkAndUpdatePackage(packageName) {
73
73
  try {
74
74
  // 获取当前安装的版本
75
75
  const __dirname = getDirName(import.meta.url);
76
+ console.log(__dirname);
76
77
  const packageJsonPath = path.join(__dirname, '../../../');
77
78
  const versionInfo = execSync(`npm list ${packageName}`, {
78
79
  cwd: packageJsonPath
@@ -7,15 +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 chalk from 'chalk';
11
10
  import logger from '../../libs/logger.js';
12
- import { checkDirectory, checkIsLoginSuccess, isValidRouteForDomain } from '../utils.js';
11
+ import { checkDirectory, checkIsLoginSuccess } from '../utils.js';
13
12
  import { getProjectConfig } from '../../utils/fileUtils/index.js';
14
13
  import { ApiService } from '../../libs/apiService.js';
15
14
  import t from '../../i18n/index.js';
16
- import { descriptionInput } from '../../components/descriptionInput.js';
17
- import { promptFilterSelector } from '../../components/filterSelector.js';
18
15
  import { validRoutine } from '../../utils/checkIsRoutineCreated.js';
16
+ import inquirer from 'inquirer';
17
+ import { transferRouteToRuleString } from './helper.js';
19
18
  const addRoute = {
20
19
  command: 'add [route] [site]',
21
20
  describe: `📥 ${t('route_add_describe').d('Bind a Route to a routine')}`,
@@ -36,7 +35,6 @@ const addRoute = {
36
35
  };
37
36
  export function handlerAddRoute(argv) {
38
37
  return __awaiter(this, void 0, void 0, function* () {
39
- var _a, _b, _c;
40
38
  if (!checkDirectory()) {
41
39
  return;
42
40
  }
@@ -47,8 +45,6 @@ export function handlerAddRoute(argv) {
47
45
  if (!isSuccess)
48
46
  return;
49
47
  yield validRoutine(projectConfig.name);
50
- // input route and site
51
- const { route, site } = argv;
52
48
  const listSitesReq = {
53
49
  SiteSearchType: 'fuzzy',
54
50
  Status: 'active',
@@ -58,57 +54,59 @@ export function handlerAddRoute(argv) {
58
54
  const server = yield ApiService.getInstance();
59
55
  const ListSitesRes = yield server.listSites(listSitesReq);
60
56
  const siteList = ((ListSitesRes === null || ListSitesRes === void 0 ? void 0 : ListSitesRes.data.Sites) || []).map((i) => ({
61
- label: i.SiteName,
57
+ name: i.SiteName,
62
58
  value: i.SiteId
63
59
  }));
64
- if (route && site) {
65
- const siteId = (_a = siteList.find((item) => item.label === site)) === null || _a === void 0 ? void 0 : _a.value;
66
- const req = {
67
- Name: projectConfig.name,
68
- SiteId: Number(siteId),
69
- SiteName: String(site),
70
- Route: String(route)
71
- };
72
- const res = yield server.createRoutineRelatedRoute(req);
73
- const addSuccess = ((_b = res === null || res === void 0 ? void 0 : res.data) === null || _b === void 0 ? void 0 : _b.Status) === 'OK';
74
- if (addSuccess) {
75
- logger.success(t('route_add_success').d('Add route success!'));
60
+ const { routeName } = yield inquirer.prompt([
61
+ {
62
+ type: 'input',
63
+ name: 'routeName',
64
+ message: t('create_route_route_name').d('Enter a Route Name (Aliases):'),
65
+ validate: (input) => {
66
+ if (!input) {
67
+ return t('route_name_input_required').d('Route name is required');
68
+ }
69
+ return true;
70
+ }
76
71
  }
77
- else {
78
- logger.error(t('route_add_fail').d('Add route fail!'));
72
+ ]);
73
+ const { routeSite } = yield inquirer.prompt([
74
+ {
75
+ type: 'list',
76
+ name: 'routeSite',
77
+ message: t('create_route_site').d('Select a site that is active in your account:'),
78
+ choices: siteList
79
79
  }
80
- return;
81
- }
82
- logger.warn(t('interactive_mode').d('Interactive mode'));
83
- // not input route and site, enter interactive mode
84
- logger.log(`🖊️ ${t('domain_input').d('Enter the name of domain (Support fuzzy matching on tab press):')}`);
85
- const domain = yield promptFilterSelector(siteList);
86
- const inputRoute = yield descriptionInput(`🖊️ ${t('route_input').d('Enter a Route:')} (${chalk.green(t('route_validate').d('You can add an asterisk (*) as the prefix or suffix to match more URLs, such as "*.example.com/*".'))})`, true);
87
- const ROUTE_PATTERN = /^(?:\*\.)?([a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*\.[a-zA-Z]{2,})(\/\*|\/[^?#]*)?$/;
88
- if (!ROUTE_PATTERN.test(inputRoute)) {
89
- return logger.error(t('route_add_invalid_route').d('Invalid route'));
90
- }
91
- if (!isValidRouteForDomain(inputRoute, domain.label)) {
92
- return logger.error(t('route_site_not_match').d('The route does not correspond to the domain.'));
93
- }
94
- if (domain.value !== '') {
95
- const req = {
96
- Name: projectConfig.name,
97
- SiteId: Number(domain.value),
98
- SiteName: domain.label,
99
- Route: inputRoute
100
- };
101
- const res = yield server.createRoutineRelatedRoute(req);
102
- const addSuccess = ((_c = res === null || res === void 0 ? void 0 : res.data) === null || _c === void 0 ? void 0 : _c.Status) === 'OK';
103
- if (addSuccess) {
104
- logger.success(t('route_add_success').d('Add route success!'));
105
- }
106
- else {
107
- logger.error(t('route_add_fail').d('Add route fail!'));
80
+ ]);
81
+ const { inputRoute } = yield inquirer.prompt([
82
+ {
83
+ type: 'input',
84
+ name: 'inputRoute',
85
+ message: t('create_route_route').d('Enter a Route:'),
86
+ validate: (input) => {
87
+ if (!input) {
88
+ return t('route_input_required').d('Route is required');
89
+ }
90
+ return true;
91
+ }
108
92
  }
93
+ ]);
94
+ const rule = transferRouteToRuleString(inputRoute);
95
+ const req = {
96
+ RoutineName: projectConfig.name,
97
+ RouteName: routeName,
98
+ SiteId: routeSite,
99
+ RouteEnable: 'on',
100
+ Bypass: 'off',
101
+ Rule: rule
102
+ };
103
+ const res = yield server.createRoutineRoute(req);
104
+ const addSuccess = (res === null || res === void 0 ? void 0 : res.code) === 200;
105
+ if (addSuccess) {
106
+ logger.success(t('route_add_success').d('Add route success!'));
109
107
  }
110
108
  else {
111
- logger.error(t('invalid_domain').d('Input domain is invalid'));
109
+ logger.error(t('route_add_fail').d('Add route fail!'));
112
110
  }
113
111
  });
114
112
  }
@@ -9,18 +9,28 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { getProjectConfig } from '../../utils/fileUtils/index.js';
11
11
  import { checkDirectory, checkIsLoginSuccess } from '../utils.js';
12
- import { ApiService } from '../../libs/apiService.js';
13
12
  import logger from '../../libs/logger.js';
14
13
  import t from '../../i18n/index.js';
15
14
  import { validRoutine } from '../../utils/checkIsRoutineCreated.js';
15
+ import api from '../../libs/api.js';
16
16
  const deleteRoute = {
17
17
  command: 'delete <route>',
18
18
  describe: `🗑 ${t('route_delete_describe').d('Delete a related route')}`,
19
19
  builder: (yargs) => {
20
- return yargs.positional('route', {
20
+ return yargs
21
+ .positional('route', {
21
22
  describe: t('route_delete_positional_describe').d('The name of the routes to delete'),
22
23
  type: 'string',
23
24
  demandOption: true
25
+ })
26
+ .fail((msg, err, yargsIns) => {
27
+ console.log(msg, err);
28
+ if (err)
29
+ throw err;
30
+ if (msg) {
31
+ yargsIns.showHelp('log');
32
+ }
33
+ process.exit(1);
24
34
  });
25
35
  },
26
36
  handler: (argv) => __awaiter(void 0, void 0, void 0, function* () {
@@ -30,7 +40,7 @@ const deleteRoute = {
30
40
  export default deleteRoute;
31
41
  export function handleDeleteRoute(argv) {
32
42
  return __awaiter(this, void 0, void 0, function* () {
33
- var _a, _b;
43
+ var _a;
34
44
  if (!checkDirectory()) {
35
45
  return;
36
46
  }
@@ -41,29 +51,25 @@ export function handleDeleteRoute(argv) {
41
51
  if (!isSuccess)
42
52
  return;
43
53
  yield validRoutine(projectConfig.name);
44
- const server = yield ApiService.getInstance();
45
- const req = { Name: projectConfig.name };
46
- const routineDetail = yield server.getRoutine(req);
47
- if (!routineDetail)
48
- return;
49
- const relatedRoutes = (_b = (_a = routineDetail.data) === null || _a === void 0 ? void 0 : _a.RelatedRoutes) !== null && _b !== void 0 ? _b : [];
50
- const deleteDomain = argv.route;
51
- const matchedSite = relatedRoutes.find((item) => {
52
- return String(item.Route) === deleteDomain;
53
- });
54
- if (matchedSite === undefined) {
55
- logger.error(t('route_not_exist').d('Route not exist!'));
54
+ const req = {
55
+ routineName: projectConfig.name
56
+ };
57
+ const res = yield api.listRoutineRoutes(req);
58
+ const configs = ((_a = res.body) === null || _a === void 0 ? void 0 : _a.configs) || [];
59
+ const deleteRouteName = argv.routeName;
60
+ const matchedRoute = configs.find((config) => config.routeName === deleteRouteName);
61
+ if (!matchedRoute) {
62
+ logger.error(t('no_route_found').d('No route found! Please check the route name.'));
56
63
  return;
57
64
  }
58
- const request = {
59
- Name: projectConfig.name,
60
- SiteId: matchedSite.SiteId,
61
- SiteName: matchedSite.SiteName,
62
- Route: matchedSite.Route,
63
- RouteId: matchedSite.RouteId
65
+ const siteId = matchedRoute === null || matchedRoute === void 0 ? void 0 : matchedRoute.siteId;
66
+ const configId = matchedRoute === null || matchedRoute === void 0 ? void 0 : matchedRoute.configId;
67
+ const deleteRouteReq = {
68
+ siteId: siteId,
69
+ configId: configId
64
70
  };
65
- const res = yield server.deleteRoutineRelatedRoute(request);
66
- const isDeleteSuccess = (res === null || res === void 0 ? void 0 : res.data.Status) === 'OK';
71
+ const deleteRouteRes = yield api.deleteRoutineRoute(deleteRouteReq);
72
+ const isDeleteSuccess = deleteRouteRes.statusCode === 200;
67
73
  if (isDeleteSuccess) {
68
74
  logger.success(t('route_delete_success').d('Delete route success!'));
69
75
  }
@@ -0,0 +1,124 @@
1
+ /* 操作符号枚举 */
2
+ export var OPERATOR_ENUM;
3
+ (function (OPERATOR_ENUM) {
4
+ OPERATOR_ENUM["Eq"] = "eq";
5
+ OPERATOR_ENUM["Ne"] = "ne";
6
+ OPERATOR_ENUM["Contains"] = "contains";
7
+ OPERATOR_ENUM["Negate_Contains"] = "negate_contains";
8
+ OPERATOR_ENUM["StartsWith"] = "starts_with";
9
+ OPERATOR_ENUM["Negate_StartsWith"] = "negate_starts_with";
10
+ OPERATOR_ENUM["EndsWith"] = "ends_with";
11
+ OPERATOR_ENUM["Negate_EndsWith"] = "negate_ends_with";
12
+ OPERATOR_ENUM["Matches"] = "matches";
13
+ OPERATOR_ENUM["Negate_Matches"] = "negate_matches";
14
+ OPERATOR_ENUM["In"] = "in";
15
+ OPERATOR_ENUM["Negate_In"] = "negate_in";
16
+ OPERATOR_ENUM["Gt"] = "gt";
17
+ OPERATOR_ENUM["Lt"] = "lt";
18
+ OPERATOR_ENUM["Ge"] = "ge";
19
+ OPERATOR_ENUM["Le"] = "le";
20
+ OPERATOR_ENUM["InList"] = "in_list";
21
+ OPERATOR_ENUM["Negate_InList"] = "negate_in_list";
22
+ })(OPERATOR_ENUM || (OPERATOR_ENUM = {}));
23
+ const RuleMatchTypeHost = 'http.host';
24
+ const RuleMatchTypeUriPath = 'http.request.uri.path';
25
+ const RuleMatchOperatorEq = OPERATOR_ENUM.Eq;
26
+ const RuleMatchOperatorStartsWith = OPERATOR_ENUM.StartsWith;
27
+ const RuleMatchOperatorEndsWith = OPERATOR_ENUM.EndsWith;
28
+ export const transferRouteToRuleString = (routePath) => {
29
+ if (!routePath) {
30
+ return '';
31
+ }
32
+ const index = routePath.indexOf('/');
33
+ let host = '';
34
+ let uriPath = '';
35
+ if (index < 0) {
36
+ host = routePath;
37
+ uriPath = '/';
38
+ }
39
+ else {
40
+ host = routePath.substring(0, index);
41
+ uriPath = routePath.substring(index);
42
+ }
43
+ let hostOperator = RuleMatchOperatorEq;
44
+ if (host.startsWith('*')) {
45
+ hostOperator = RuleMatchOperatorEndsWith;
46
+ host = host.replace(/\*/g, '');
47
+ }
48
+ let uriPathOperator = RuleMatchOperatorEq;
49
+ if (uriPath.endsWith('*')) {
50
+ uriPathOperator = RuleMatchOperatorStartsWith;
51
+ uriPath = uriPath.replace(/\*$/, '');
52
+ }
53
+ let ruleStr = '';
54
+ if (hostOperator === RuleMatchOperatorEq) {
55
+ if (uriPathOperator === RuleMatchOperatorEq) {
56
+ ruleStr = `(${RuleMatchTypeHost} ${hostOperator} "${host}" and ${RuleMatchTypeUriPath} ${uriPathOperator} "${uriPath}")`;
57
+ }
58
+ else if (uriPathOperator === RuleMatchOperatorStartsWith) {
59
+ ruleStr = `(${RuleMatchTypeHost} ${hostOperator} "${host}" and ${RuleMatchOperatorStartsWith}(${RuleMatchTypeUriPath}, "${uriPath}"))`;
60
+ }
61
+ }
62
+ else if (hostOperator === RuleMatchOperatorEndsWith) {
63
+ if (uriPathOperator === RuleMatchOperatorEq) {
64
+ ruleStr = `(${RuleMatchOperatorEndsWith}(${RuleMatchTypeHost}, "${host}") and ${RuleMatchTypeUriPath} ${uriPathOperator} "${uriPath}")`;
65
+ }
66
+ else if (uriPathOperator === RuleMatchOperatorStartsWith) {
67
+ ruleStr = `(${RuleMatchOperatorEndsWith}(${RuleMatchTypeHost}, "${host}") and ${RuleMatchOperatorStartsWith}(${RuleMatchTypeUriPath}, "${uriPath}"))`;
68
+ }
69
+ }
70
+ return ruleStr;
71
+ };
72
+ export const transferRuleStringToRoute = (ruleStr) => {
73
+ if (!ruleStr) {
74
+ return '';
75
+ }
76
+ // 去掉外层括号并按 " and " 分割
77
+ const cleanedRule = ruleStr.replace(/^\(|\)$/g, '');
78
+ const parts = cleanedRule.split(' and ');
79
+ if (parts.length !== 2) {
80
+ return '';
81
+ }
82
+ let host = '';
83
+ let uriPath = '';
84
+ // 处理host部分
85
+ const hostPart = parts[0].trim();
86
+ if (hostPart.startsWith(`${RuleMatchOperatorEndsWith}(${RuleMatchTypeHost},`)) {
87
+ // host匹配eq时的逻辑
88
+ // ends_with(http.host, "value")
89
+ const match = hostPart.match(/ends_with\(http\.host,\s*"([^"]+)"\)/);
90
+ if (match) {
91
+ host = `*${match[1]}`; // 加前缀 *
92
+ }
93
+ }
94
+ else if (hostPart.startsWith(`${RuleMatchTypeHost} ${RuleMatchOperatorEq}`)) {
95
+ // host匹配eq时的逻辑
96
+ // http.host eq "value"
97
+ const match = hostPart.match(/http\.host eq "([^"]+)"/);
98
+ if (match) {
99
+ host = match[1];
100
+ }
101
+ }
102
+ // 处理uriPath 部分
103
+ const uriPathPart = parts[1].trim();
104
+ if (uriPathPart.startsWith(`${RuleMatchOperatorStartsWith}(${RuleMatchTypeUriPath},`)) {
105
+ // uriPath匹配startsWith时的逻辑
106
+ // starts_with(http.request.uri.path, "value")
107
+ const match = uriPathPart.match(/starts_with\(http\.request\.uri\.path,\s*"([^"]+)"\)/);
108
+ if (match) {
109
+ uriPath = `${match[1]}*`; // 加后缀 *
110
+ }
111
+ }
112
+ else if (uriPathPart.startsWith(`${RuleMatchTypeUriPath} ${RuleMatchOperatorEq}`)) {
113
+ // uriPath匹配eq时的逻辑
114
+ // http.request.uri.path eq "value"
115
+ const match = uriPathPart.match(/http\.request\.uri\.path eq "([^"]+)"/);
116
+ if (match) {
117
+ uriPath = match[1];
118
+ }
119
+ }
120
+ if (!host || !uriPath) {
121
+ return '';
122
+ }
123
+ return `${host}${uriPath}`;
124
+ };
@@ -10,10 +10,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import { getProjectConfig } from '../../utils/fileUtils/index.js';
11
11
  import Table from 'cli-table3';
12
12
  import { checkDirectory, checkIsLoginSuccess } from '../utils.js';
13
- import { ApiService } from '../../libs/apiService.js';
14
13
  import logger from '../../libs/logger.js';
15
14
  import t from '../../i18n/index.js';
16
15
  import { validRoutine } from '../../utils/checkIsRoutineCreated.js';
16
+ import api from '../../libs/api.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
  });
@@ -16,6 +16,7 @@ import chalk from 'chalk';
16
16
  import t from '../i18n/index.js';
17
17
  import { ApiService } from '../libs/apiService.js';
18
18
  import logger from '../libs/logger.js';
19
+ import api from '../libs/api.js';
19
20
  export const checkDirectory = (isCheckGit = false) => {
20
21
  const root = getRoot();
21
22
  if (fs.existsSync(projectConfigPath)) {
@@ -67,11 +68,10 @@ export const bindRoutineWithDomain = (name, domain) => __awaiter(void 0, void 0,
67
68
  }
68
69
  });
69
70
  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) || [];
71
+ var _a, _b;
72
+ const req = { name };
73
+ const res = yield api.listRoutineCodeVersions(req);
74
+ return (_b = (_a = res.body) === null || _a === void 0 ? void 0 : _a.codeVersions) !== null && _b !== void 0 ? _b : [];
75
75
  });
76
76
  export function validName(name) {
77
77
  return /^[a-zA-Z0-9-_]+$/.test(name);
@@ -934,5 +934,49 @@
934
934
  "routine_create_fail": {
935
935
  "en": "Routine created failed.",
936
936
  "zh_CN": "边缘函数创建失败"
937
+ },
938
+ "create_route_route": {
939
+ "en": "Enter a Route:",
940
+ "zh_CN": ""
941
+ },
942
+ "route_name_input_required": {
943
+ "en": "Route name is required",
944
+ "zh_CN": ""
945
+ },
946
+ "create_route_mode": {
947
+ "en": "Which mode of route do you want to use?",
948
+ "zh_CN": ""
949
+ },
950
+ "create_route_site": {
951
+ "en": "Select a site that is active in your account:",
952
+ "zh_CN": ""
953
+ },
954
+ "route_input_required": {
955
+ "en": "Route is required",
956
+ "zh_CN": ""
957
+ },
958
+ "create_route_rule": {
959
+ "en": "Enter a Rule Expression:",
960
+ "zh_CN": ""
961
+ },
962
+ "rule_input_required": {
963
+ "en": "Rule is required",
964
+ "zh_CN": ""
965
+ },
966
+ "route_list_simple_title": {
967
+ "en": "Related simple mode routes",
968
+ "zh_CN": ""
969
+ },
970
+ "route_list_custom_title": {
971
+ "en": "Related custom mode routes",
972
+ "zh_CN": ""
973
+ },
974
+ "create_route_route_name": {
975
+ "en": "Enter a Route Name (Aliases):",
976
+ "zh_CN": ""
977
+ },
978
+ "no_route_found": {
979
+ "en": "No route found! Please check the route name.",
980
+ "zh_CN": ""
937
981
  }
938
982
  }
package/dist/libs/api.js CHANGED
@@ -140,9 +140,6 @@ class Client {
140
140
  const request = new $ESA.CreateRoutineRequest(params);
141
141
  return this.callApi(this.client.createRoutineWithOptions.bind(this.client), request);
142
142
  }
143
- listRoutineOptionalSpecs() {
144
- return this.callApi(this.client.listRoutineOptionalSpecsWithOptions.bind(this.client));
145
- }
146
143
  createRoutineRelatedRecord(params) {
147
144
  const request = new $ESA.CreateRoutineRelatedRecordRequest(params);
148
145
  return this.callApi(this.client.createRoutineRelatedRecordWithOptions.bind(this.client), request);
@@ -151,5 +148,34 @@ class Client {
151
148
  const request = new $ESA.DeleteRoutineRelatedRecordRequest(params);
152
149
  return this.callApi(this.client.deleteRoutineRelatedRecordWithOptions.bind(this.client), request);
153
150
  }
151
+ createRoutineRoute(params) {
152
+ const request = new $ESA.CreateRoutineRouteRequest(params);
153
+ const newRequest = Object.assign(request, { mode: 'simple' });
154
+ return this.callApi(this.client.createRoutineRouteWithOptions.bind(this.client), newRequest);
155
+ }
156
+ deleteRoutineRoute(params) {
157
+ const request = new $ESA.DeleteRoutineRouteRequest(params);
158
+ return this.callApi(this.client.deleteRoutineRouteWithOptions.bind(this.client), request);
159
+ }
160
+ getRoutineRoute(params) {
161
+ const request = new $ESA.GetRoutineRouteRequest(params);
162
+ return this.callApi(this.client.getRoutineRouteWithOptions.bind(this.client), request);
163
+ }
164
+ listSiteRoutes(params) {
165
+ const request = new $ESA.ListSiteRoutesRequest(params);
166
+ return this.callApi(this.client.listSiteRoutes.bind(this.client), request);
167
+ }
168
+ listRoutineRoutes(params) {
169
+ const request = new $ESA.ListRoutineRoutesRequest(params);
170
+ return this.callApi(this.client.listRoutineRoutes.bind(this.client), request);
171
+ }
172
+ updateRoutineRoute(params) {
173
+ const request = new $ESA.UpdateRoutineRouteRequest(params);
174
+ return this.callApi(this.client.updateRoutineRoute.bind(this.client), request);
175
+ }
176
+ listRoutineCodeVersions(params) {
177
+ const request = new $ESA.ListRoutineCodeVersionsRequest(params);
178
+ return this.callApi(this.client.listRoutineCodeVersions.bind(this.client), request);
179
+ }
154
180
  }
155
181
  export default new Client();
@@ -12,7 +12,6 @@ import FormData from 'form-data';
12
12
  import fetch from 'node-fetch';
13
13
  import { Environment } from './interface.js';
14
14
  import { getApiConfig } from '../utils/fileUtils/index.js';
15
- import chain from 'lodash';
16
15
  import t from '../i18n/index.js';
17
16
  export class ApiService {
18
17
  constructor(cliConfig) {
@@ -569,7 +568,7 @@ export class ApiService {
569
568
  }
570
569
  getRoutine(requestParams_1) {
571
570
  return __awaiter(this, arguments, void 0, function* (requestParams, isShowError = true) {
572
- var _a, _b, _c, _d, _e, _f, _g, _h;
571
+ var _a, _b, _c, _d, _e, _f;
573
572
  try {
574
573
  let params = {
575
574
  action: 'GetRoutine',
@@ -602,12 +601,10 @@ export class ApiService {
602
601
  data: {
603
602
  RequestId: (_a = res.body) === null || _a === void 0 ? void 0 : _a.RequestId,
604
603
  CodeVersions: ((_b = res.body) === null || _b === void 0 ? void 0 : _b.CodeVersions) || [],
605
- RelatedRecords: ((_c = res.body) === null || _c === void 0 ? void 0 : _c.RelatedRecords) || [],
606
- Envs: ((_d = res.body) === null || _d === void 0 ? void 0 : _d.Envs) || [],
607
- CreateTime: (_e = res.body) === null || _e === void 0 ? void 0 : _e.CreateTime,
608
- Description: (_f = res.body) === null || _f === void 0 ? void 0 : _f.Description,
609
- RelatedRoutes: ((_g = res.body) === null || _g === void 0 ? void 0 : _g.RelatedRoutes) || [],
610
- DefaultRelatedRecord: (_h = res.body) === null || _h === void 0 ? void 0 : _h.DefaultRelatedRecord
604
+ Envs: ((_c = res.body) === null || _c === void 0 ? void 0 : _c.Envs) || [],
605
+ CreateTime: (_d = res.body) === null || _d === void 0 ? void 0 : _d.CreateTime,
606
+ Description: (_e = res.body) === null || _e === void 0 ? void 0 : _e.Description,
607
+ DefaultRelatedRecord: (_f = res.body) === null || _f === void 0 ? void 0 : _f.DefaultRelatedRecord
611
608
  }
612
609
  };
613
610
  return routineResponse;
@@ -695,7 +692,7 @@ export class ApiService {
695
692
  }
696
693
  };
697
694
  const uploadResult = yield this.client.callApi(params, request, runtime);
698
- const ossConfig = chain(uploadResult).get('body.OssPostConfig');
695
+ const ossConfig = uploadResult.body.OssPostConfig;
699
696
  if (uploadResult.statusCode !== 200 || !ossConfig) {
700
697
  return false;
701
698
  }
@@ -708,12 +705,12 @@ export class ApiService {
708
705
  formData.append('policy', policy);
709
706
  formData.append('key', key);
710
707
  formData.append('file', edgeRoutine.code);
711
- // TODO: 检查oss结果;
712
708
  const ossRes = yield fetch(Url, {
713
709
  method: 'POST',
714
710
  body: formData,
715
711
  headers: formData.getHeaders()
716
712
  });
713
+ // console.log('oss result', oss);
717
714
  if (ossRes && ossRes.status === 200) {
718
715
  return true;
719
716
  }
@@ -868,5 +865,106 @@ export class ApiService {
868
865
  return null;
869
866
  });
870
867
  }
868
+ listRoutineRelatedRecords(requestParams) {
869
+ return __awaiter(this, void 0, void 0, function* () {
870
+ try {
871
+ let params = {
872
+ action: 'ListRoutineRelatedRecords',
873
+ version: '2024-09-10',
874
+ protocol: 'https',
875
+ method: 'GET',
876
+ authType: 'AK',
877
+ bodyType: 'json',
878
+ reqBodyType: 'json',
879
+ style: 'RPC',
880
+ pathname: '/',
881
+ toMap: function () {
882
+ return this;
883
+ }
884
+ };
885
+ let request = new $OpenApi.OpenApiRequest({
886
+ query: {
887
+ Name: requestParams.Name,
888
+ PageNumber: requestParams.PageNumber,
889
+ PageSize: requestParams.PageSize,
890
+ SearchKeyWord: requestParams.SearchKeyWord
891
+ }
892
+ });
893
+ let runtime = {
894
+ toMap: function () {
895
+ return this;
896
+ }
897
+ };
898
+ const res = yield this.client.callApi(params, request, runtime);
899
+ if (res.statusCode === 200 && res.body) {
900
+ const ret = {
901
+ code: res.statusCode,
902
+ data: {
903
+ PageNumber: res.body.PageNumber,
904
+ PageSize: res.body.PageSize,
905
+ TotalCount: res.body.TotalCount,
906
+ RelatedRecords: res.body.RelatedRecords
907
+ }
908
+ };
909
+ return ret;
910
+ }
911
+ }
912
+ catch (error) {
913
+ console.log(error);
914
+ }
915
+ return null;
916
+ });
917
+ }
918
+ createRoutineRoute(requestParams) {
919
+ return __awaiter(this, void 0, void 0, function* () {
920
+ try {
921
+ let params = {
922
+ action: 'CreateRoutineRoute',
923
+ version: '2024-09-10',
924
+ protocol: 'https',
925
+ method: 'POST',
926
+ authType: 'AK',
927
+ bodyType: 'json',
928
+ reqBodyType: 'json',
929
+ style: 'RPC',
930
+ pathname: '/',
931
+ toMap: function () {
932
+ return this;
933
+ }
934
+ };
935
+ let request = new $OpenApi.OpenApiRequest({
936
+ query: {
937
+ SiteId: requestParams.SiteId,
938
+ RoutineName: requestParams.RoutineName,
939
+ RouteName: requestParams.RouteName,
940
+ RouteEnable: 'on',
941
+ Rule: requestParams.Rule,
942
+ Bypass: requestParams.Bypass,
943
+ Mode: 'simple'
944
+ }
945
+ });
946
+ let runtime = {
947
+ toMap: function () {
948
+ return this;
949
+ }
950
+ };
951
+ const res = yield this.client.callApi(params, request, runtime);
952
+ if (res.statusCode === 200 && res.body) {
953
+ const ret = {
954
+ code: res.statusCode,
955
+ data: {
956
+ RequestId: res.body.RequestId,
957
+ ConfigId: res.body.ConfigId
958
+ }
959
+ };
960
+ return ret;
961
+ }
962
+ }
963
+ catch (error) {
964
+ console.log(error);
965
+ }
966
+ return null;
967
+ });
968
+ }
871
969
  }
872
970
  ApiService.instance = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "esa-cli",
3
- "version": "0.0.2-beta.9",
3
+ "version": "0.0.5",
4
4
  "description": "A CLI for operating Alibaba Cloud ESA EdgeRoutine (Edge Functions).",
5
5
  "main": "bin/enter.cjs",
6
6
  "type": "module",
@@ -67,7 +67,7 @@
67
67
  "vitest": "^2.0.4"
68
68
  },
69
69
  "dependencies": {
70
- "@alicloud/esa20240910": "2.8.1",
70
+ "@alicloud/esa20240910": "2.25.0",
71
71
  "@alicloud/openapi-client": "^0.4.7",
72
72
  "@babel/generator": "^7.26.3",
73
73
  "@babel/parser": "^7.24.4",
@@ -80,7 +80,7 @@
80
80
  "chokidar": "^3.5.3",
81
81
  "cli-table3": "^0.6.5",
82
82
  "cross-spawn": "^7.0.3",
83
- "esa-template": "0.0.4-beta.1",
83
+ "esa-template": "^0.0.3",
84
84
  "esbuild": "^0.21.1",
85
85
  "esbuild-plugin-less": "^1.3.8",
86
86
  "form-data": "^4.0.0",