esa-cli 0.0.1-beta.1

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 (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +175 -0
  3. package/bin/enter.cjs +52 -0
  4. package/dist/README.md +175 -0
  5. package/dist/bin/enter.cjs +52 -0
  6. package/dist/cliconfig.toml +6 -0
  7. package/dist/commands/commit/index.js +147 -0
  8. package/dist/commands/commit/prodBuild.js +50 -0
  9. package/dist/commands/common/constant.js +54 -0
  10. package/dist/commands/config.js +51 -0
  11. package/dist/commands/deploy/helper.js +108 -0
  12. package/dist/commands/deploy/index.js +217 -0
  13. package/dist/commands/deployments/delete.js +92 -0
  14. package/dist/commands/deployments/index.js +27 -0
  15. package/dist/commands/deployments/list.js +89 -0
  16. package/dist/commands/dev/config/devBuild.js +26 -0
  17. package/dist/commands/dev/config/devEntry.js +71 -0
  18. package/dist/commands/dev/config/mock/cache.js +31 -0
  19. package/dist/commands/dev/config/mock/kv.js +87 -0
  20. package/dist/commands/dev/devPack.js +113 -0
  21. package/dist/commands/dev/doProcess.js +73 -0
  22. package/dist/commands/dev/index.js +240 -0
  23. package/dist/commands/dev/server.js +100 -0
  24. package/dist/commands/domain/add.js +72 -0
  25. package/dist/commands/domain/delete.js +74 -0
  26. package/dist/commands/domain/index.js +29 -0
  27. package/dist/commands/domain/list.js +51 -0
  28. package/dist/commands/init/index.js +149 -0
  29. package/dist/commands/lang.js +32 -0
  30. package/dist/commands/login/index.js +108 -0
  31. package/dist/commands/logout.js +44 -0
  32. package/dist/commands/route/add.js +115 -0
  33. package/dist/commands/route/delete.js +74 -0
  34. package/dist/commands/route/index.js +29 -0
  35. package/dist/commands/route/list.js +63 -0
  36. package/dist/commands/routine/delete.js +54 -0
  37. package/dist/commands/routine/index.js +27 -0
  38. package/dist/commands/routine/list.js +101 -0
  39. package/dist/commands/site/index.js +25 -0
  40. package/dist/commands/site/list.js +47 -0
  41. package/dist/commands/utils.js +139 -0
  42. package/dist/components/descriptionInput.js +38 -0
  43. package/dist/components/filterSelector.js +132 -0
  44. package/dist/components/mutiSelectTable.js +95 -0
  45. package/dist/components/selectInput.js +17 -0
  46. package/dist/components/selectItem.js +6 -0
  47. package/dist/components/yesNoPrompt.js +9 -0
  48. package/dist/docs/Commands_en.md +224 -0
  49. package/dist/docs/Commands_zh_CN.md +224 -0
  50. package/dist/docs/dev.png +0 -0
  51. package/dist/i18n/index.js +27 -0
  52. package/dist/i18n/locales.json +766 -0
  53. package/dist/index.js +80 -0
  54. package/dist/libs/apiService.js +914 -0
  55. package/dist/libs/git/index.js +52 -0
  56. package/dist/libs/interface.js +21 -0
  57. package/dist/libs/logger.js +149 -0
  58. package/dist/libs/request.js +98 -0
  59. package/dist/libs/templates/index.js +16 -0
  60. package/dist/package.json +93 -0
  61. package/dist/utils/checkDevPort.js +113 -0
  62. package/dist/utils/checkIsRoutineCreated.js +56 -0
  63. package/dist/utils/checkVersion.js +26 -0
  64. package/dist/utils/debounce.js +18 -0
  65. package/dist/utils/fileUtils/index.js +219 -0
  66. package/dist/utils/fileUtils/interface.js +1 -0
  67. package/dist/utils/install/install.ps1 +33 -0
  68. package/dist/utils/install/install.sh +53 -0
  69. package/dist/utils/installRuntime.js +80 -0
  70. package/dist/utils/openInBrowser.js +24 -0
  71. package/dist/utils/sleep.js +6 -0
  72. package/dist/zh_CN.md +177 -0
  73. package/package.json +93 -0
@@ -0,0 +1,139 @@
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 fs from 'fs';
11
+ import { execSync } from 'child_process';
12
+ import { isInstalledGit } from '../libs/git/index.js';
13
+ import { getCliConfig, projectConfigPath, getRoot } from '../utils/fileUtils/index.js';
14
+ import chalk from 'chalk';
15
+ import t from '../i18n/index.js';
16
+ import { ApiService } from '../libs/apiService.js';
17
+ import logger from '../libs/logger.js';
18
+ export const checkDirectory = (isCheckGit = false) => {
19
+ const root = getRoot();
20
+ if (fs.existsSync(projectConfigPath)) {
21
+ try {
22
+ if (isCheckGit && isInstalledGit()) {
23
+ const gitStatus = execSync('git status --porcelain', {
24
+ cwd: root
25
+ }).toString();
26
+ if (gitStatus) {
27
+ logger.warn(t('utils_git_not_commit').d('There are uncommitted changes in the repository.'));
28
+ return false;
29
+ }
30
+ }
31
+ }
32
+ catch (error) {
33
+ logger.error(`${t('utils_git_error').d('An error occurred while checking the Git status')}: ${error}`);
34
+ return false;
35
+ }
36
+ return true;
37
+ }
38
+ else {
39
+ logger.notInProject();
40
+ return false;
41
+ }
42
+ };
43
+ export const bindRoutineWithDomain = (name, domain) => __awaiter(void 0, void 0, void 0, function* () {
44
+ const server = yield ApiService.getInstance();
45
+ const req = { RecordName: domain };
46
+ const res = yield server.getMatchSite(req);
47
+ if (res) {
48
+ const record = res;
49
+ const createReq = {
50
+ Name: name,
51
+ SiteId: record.data.SiteId,
52
+ SiteName: record.data.SiteName,
53
+ RecordName: domain
54
+ };
55
+ const response = yield server.createRoutineRelatedRecord(createReq);
56
+ const isBindSuccess = (response === null || response === void 0 ? void 0 : response.data.Status) === 'OK';
57
+ if (isBindSuccess) {
58
+ logger.success(t('utils_bind_success', { domain }).d(`Binding domain ${domain} to routine successfully`));
59
+ }
60
+ else {
61
+ logger.error(t('utils_bind_error', { domain }).d(`Binding domain ${domain} to routine failed`));
62
+ }
63
+ }
64
+ else {
65
+ logger.error(t('utils_domain_error').d('Domain is not active'));
66
+ }
67
+ });
68
+ export const getRoutineVersionList = (name) => __awaiter(void 0, void 0, void 0, function* () {
69
+ var _a;
70
+ const server = yield ApiService.getInstance();
71
+ const req = { Name: name };
72
+ const res = yield server.getRoutine(req);
73
+ return ((_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.CodeVersions) || [];
74
+ });
75
+ export function validName(name) {
76
+ return /^[a-zA-Z0-9-_]+$/.test(name);
77
+ }
78
+ // 校验域名是否有效
79
+ export function validDomain(domain) {
80
+ return /^(?:[a-z0-9-](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/.test(domain);
81
+ }
82
+ export function checkIsLoginSuccess() {
83
+ return __awaiter(this, void 0, void 0, function* () {
84
+ const cliConfig = getCliConfig();
85
+ const namedCommand = chalk.green('esa login');
86
+ if (!cliConfig || !cliConfig.auth) {
87
+ return false;
88
+ }
89
+ if (!cliConfig.auth.accessKeyId || !cliConfig.auth.accessKeySecret) {
90
+ logger.log(`❌ ${t('utils_login_error').d('Maybe you are not logged in yet.')}`);
91
+ logger.log(`🔔 ${t('utils_login_error_config', { namedCommand }).d(`Please run command to login: ${namedCommand}`)}`);
92
+ return false;
93
+ }
94
+ const server = yield ApiService.getInstance();
95
+ server.updateConfig(cliConfig);
96
+ const res = yield server.checkLogin();
97
+ if (res.success) {
98
+ return true;
99
+ }
100
+ logger.log(res.message || '');
101
+ logger.log(`❌ ${t('utils_login_error').d('Maybe you are not logged in yet.')}`);
102
+ logger.log(`🔔 ${t('utils_login_error_config', { namedCommand }).d(`Please run command to login: ${namedCommand}`)}`);
103
+ return false;
104
+ });
105
+ }
106
+ export function isValidRouteForDomain(route, domain) {
107
+ // 构建一个允许子域和任意路径的正则表达式
108
+ // 例如,匹配形式如 *.example.com/* 的URL
109
+ return route.includes(domain);
110
+ }
111
+ export function escapeRegExp(string) {
112
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& 表示整个被匹配的字符串
113
+ }
114
+ export const getAllSites = () => __awaiter(void 0, void 0, void 0, function* () {
115
+ var _a;
116
+ const server = yield ApiService.getInstance();
117
+ const res = [];
118
+ while (true) {
119
+ const req = {
120
+ SiteSearchType: 'fuzzy',
121
+ Status: 'active',
122
+ PageNumber: res.length + 1,
123
+ PageSize: 500
124
+ };
125
+ const response = yield server.listSites(req);
126
+ if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.Sites) {
127
+ res.push(...response.data.Sites);
128
+ }
129
+ else {
130
+ break;
131
+ }
132
+ }
133
+ return res.map((site) => {
134
+ return {
135
+ label: site.SiteName,
136
+ value: site.SiteId
137
+ };
138
+ });
139
+ });
@@ -0,0 +1,38 @@
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 React, { useState } from 'react';
11
+ import { Box, render, Text } from 'ink';
12
+ import TextInput from 'ink-text-input';
13
+ export const DescriptionInput = ({ prompt, onSubmit, required }) => {
14
+ const [input, setInput] = useState('');
15
+ const [error, setError] = useState('');
16
+ const handleSubmit = () => {
17
+ if (required && !input.trim()) {
18
+ setError('This field is required');
19
+ }
20
+ else {
21
+ onSubmit(input);
22
+ }
23
+ };
24
+ return (React.createElement(Box, { flexDirection: "column" },
25
+ React.createElement(Box, null,
26
+ React.createElement(Text, null, prompt)),
27
+ React.createElement(TextInput, { value: input, onChange: setInput, onSubmit: handleSubmit }),
28
+ error && (React.createElement(Box, null,
29
+ React.createElement(Text, { color: "red" }, error)))));
30
+ };
31
+ export const descriptionInput = (prompt_1, ...args_1) => __awaiter(void 0, [prompt_1, ...args_1], void 0, function* (prompt, required = false) {
32
+ return new Promise((resolve) => {
33
+ const { unmount } = render(React.createElement(DescriptionInput, { prompt: prompt, required: required, onSubmit: (input) => {
34
+ unmount();
35
+ resolve(input);
36
+ } }));
37
+ });
38
+ });
@@ -0,0 +1,132 @@
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, useInput } from 'ink';
11
+ import TextInput from 'ink-text-input';
12
+ import React, { useState, useEffect } from 'react';
13
+ import t from '../i18n/index.js';
14
+ export const FilterSelector = ({ data, onSubmit, hideCount = 20 }) => {
15
+ const [inputValue, setInputValue] = useState('');
16
+ const [filteredData, setFilteredData] = useState(data);
17
+ const [isShowFilteredData, setIsShowFilteredData] = useState(false);
18
+ const [isSelectionMode, setIsSelectionMode] = useState(false);
19
+ const [selectedIndex, setSelectedIndex] = useState(-1);
20
+ const [tabPressCount, setTabPressCount] = useState(0);
21
+ const [showAll, setShowAll] = useState(false);
22
+ useEffect(() => {
23
+ if (showAll && !isSelectionMode) {
24
+ setFilteredData(data.filter((site) => site.label.includes(inputValue)));
25
+ }
26
+ }, [inputValue, data]);
27
+ const handleSubmit = () => {
28
+ onSubmit(inputValue);
29
+ };
30
+ useInput((input, key) => {
31
+ if (key.return && isSelectionMode && filteredData[selectedIndex]) {
32
+ setInputValue(filteredData[selectedIndex].label);
33
+ setIsSelectionMode(false);
34
+ setIsShowFilteredData(false);
35
+ setSelectedIndex(-1);
36
+ setTabPressCount(0);
37
+ }
38
+ else if (key.tab) {
39
+ if (tabPressCount === 0) {
40
+ const filteredDataInner = data.filter((site) => site.label.includes(inputValue));
41
+ setFilteredData(filteredDataInner);
42
+ if (filteredData.length === 1) {
43
+ setIsShowFilteredData(false);
44
+ setInputValue(filteredDataInner[0].label);
45
+ setSelectedIndex(0);
46
+ }
47
+ else {
48
+ setIsShowFilteredData(true);
49
+ }
50
+ }
51
+ else if (tabPressCount === 1) {
52
+ const filteredDataInner = data.filter((site) => site.label.includes(inputValue));
53
+ setFilteredData(filteredDataInner);
54
+ // 匹配结果大于等于1个时,进入选择模式
55
+ if ((filteredDataInner.length >= 1 &&
56
+ showAll &&
57
+ filteredDataInner.length > hideCount) ||
58
+ (filteredDataInner.length >= 1 &&
59
+ filteredDataInner.length <= hideCount)) {
60
+ setIsSelectionMode(true);
61
+ setSelectedIndex(0);
62
+ setInputValue(filteredDataInner[0].label);
63
+ }
64
+ }
65
+ else if (tabPressCount >= 2 &&
66
+ isSelectionMode &&
67
+ (showAll || filteredData.length <= hideCount) &&
68
+ filteredData.length > 1) {
69
+ setSelectedIndex((prevIndex) => (prevIndex + 1) % filteredData.length);
70
+ setInputValue(filteredData[(selectedIndex + 1) % filteredData.length].label);
71
+ }
72
+ setTabPressCount((prevCount) => prevCount + 1);
73
+ }
74
+ else if (key.downArrow && isSelectionMode) {
75
+ setSelectedIndex((prevIndex) => (prevIndex + 1) % filteredData.length);
76
+ setInputValue(filteredData[(selectedIndex + 1) % filteredData.length].label);
77
+ }
78
+ else if (key.upArrow && isSelectionMode) {
79
+ setSelectedIndex((prevIndex) => (prevIndex - 1 + filteredData.length) % filteredData.length);
80
+ setInputValue(filteredData[(selectedIndex - 1 + filteredData.length) % filteredData.length].label);
81
+ }
82
+ else if (key.leftArrow || key.rightArrow) {
83
+ }
84
+ else if (key.return) {
85
+ handleSubmit();
86
+ setTabPressCount(0);
87
+ }
88
+ else if (input === 'y' &&
89
+ !showAll &&
90
+ isShowFilteredData &&
91
+ (filteredData === null || filteredData === void 0 ? void 0 : filteredData.length) > hideCount) {
92
+ setShowAll(true);
93
+ setIsSelectionMode(true);
94
+ }
95
+ else {
96
+ setIsSelectionMode(false);
97
+ setIsShowFilteredData(false);
98
+ setSelectedIndex(-1);
99
+ setTabPressCount(0);
100
+ setShowAll(false);
101
+ }
102
+ });
103
+ const renderFilterData = () => {
104
+ return ((showAll || filteredData.length <= hideCount) &&
105
+ filteredData.length > 1 && (React.createElement(React.Fragment, null,
106
+ React.createElement(Text, null, `👉 ${t('route_add_tab_tip').d('Press Tab to select')}`),
107
+ filteredData.map((item, index) => (React.createElement(Text, { key: index, inverse: index === selectedIndex }, item.label))))));
108
+ };
109
+ return (React.createElement(Box, { flexDirection: "column" },
110
+ React.createElement(TextInput, { value: inputValue, highlightPastedText: true, onChange: (value) => {
111
+ if (!showAll &&
112
+ value[value.length - 1] === 'y' &&
113
+ tabPressCount === 1) {
114
+ return;
115
+ }
116
+ setInputValue(value);
117
+ } }),
118
+ isShowFilteredData && (React.createElement(React.Fragment, null,
119
+ filteredData.length > hideCount && !showAll && (React.createElement(Text, null, t('route_add_see_more').d(`Do you wish to see all ${filteredData.length} possibilities? (y/n)`))),
120
+ renderFilterData()))));
121
+ };
122
+ export const promptFilterSelector = (siteList) => __awaiter(void 0, void 0, void 0, function* () {
123
+ return new Promise((resolve) => {
124
+ const { unmount } = render(React.createElement(FilterSelector, { onSubmit: (input) => {
125
+ unmount();
126
+ resolve(siteList.find((site) => site.label === input) || {
127
+ label: '',
128
+ value: ''
129
+ });
130
+ }, data: siteList }));
131
+ });
132
+ });
@@ -0,0 +1,95 @@
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 React, { useState } from 'react';
11
+ import { Box, render, Text, useInput } from 'ink';
12
+ import t from '../i18n/index.js';
13
+ export const MultiSelectTable = ({ items, itemsPerRow, onSubmit, boxWidth = 25 }) => {
14
+ const [selectedIndexes, setSelectedIndexes] = useState(new Set());
15
+ const [cursorRow, setCursorRow] = useState(0);
16
+ const [cursorCol, setCursorCol] = useState(0);
17
+ const rows = [];
18
+ for (let i = 0; i < items.length; i += itemsPerRow) {
19
+ rows.push(items.slice(i, i + itemsPerRow));
20
+ }
21
+ const totalRows = Math.ceil(items.length / itemsPerRow);
22
+ const toggleSelect = (row, col) => {
23
+ const key = `${row}:${col}`;
24
+ setSelectedIndexes((prevSelectedIndexes) => {
25
+ const newSelectedIndexes = new Set(prevSelectedIndexes);
26
+ if (newSelectedIndexes.has(key)) {
27
+ newSelectedIndexes.delete(key);
28
+ }
29
+ else {
30
+ newSelectedIndexes.add(key);
31
+ }
32
+ return newSelectedIndexes;
33
+ });
34
+ };
35
+ const handleSubmission = () => {
36
+ const selectedItems = Array.from(selectedIndexes).map((key) => {
37
+ const [row, col] = key.split(':').map(Number);
38
+ return rows[row][col];
39
+ });
40
+ onSubmit(selectedItems);
41
+ };
42
+ useInput((input, key) => {
43
+ if (key.leftArrow) {
44
+ setCursorCol((prev) => Math.max(prev - 1, 0));
45
+ }
46
+ else if (key.rightArrow) {
47
+ setCursorCol((prev) => Math.min(prev + 1, itemsPerRow - 1));
48
+ }
49
+ else if (key.upArrow) {
50
+ setCursorRow((prev) => Math.max(prev - 1, 0));
51
+ }
52
+ else if (key.downArrow) {
53
+ setCursorRow((prev) => Math.min(prev + 1, totalRows - 1));
54
+ }
55
+ else if (input === ' ') {
56
+ toggleSelect(cursorRow, cursorCol);
57
+ }
58
+ else if (key.tab) {
59
+ setCursorCol((prevCol) => {
60
+ let newCol = prevCol + 1;
61
+ let newRow = cursorRow;
62
+ if (newCol >= itemsPerRow) {
63
+ newCol = 0;
64
+ newRow = cursorRow + 1;
65
+ if (newRow >= totalRows) {
66
+ newRow = 0;
67
+ }
68
+ setCursorRow(newRow);
69
+ }
70
+ return newCol;
71
+ });
72
+ }
73
+ else if (key.return) {
74
+ handleSubmission();
75
+ }
76
+ });
77
+ return (React.createElement(Box, { flexDirection: "column" },
78
+ rows.map((rowItems, row) => (React.createElement(Box, { key: row, flexDirection: "row" }, rowItems.map((item, col) => (React.createElement(Box, { key: `${row}:${col}`, width: boxWidth },
79
+ React.createElement(Text, { color: cursorRow === row && cursorCol === col ? 'green' : undefined },
80
+ selectedIndexes.has(`${row}:${col}`) ? '✅' : ' ',
81
+ item.label))))))),
82
+ React.createElement(Box, { flexDirection: "column" },
83
+ React.createElement(Text, null,
84
+ "\uD83D\uDD14",
85
+ ' ',
86
+ t('deploy_select_table_tip').d('Use arrow keys to move, space to select, and enter to submit.')))));
87
+ };
88
+ export const displayMultiSelectTable = (items_1, ...args_1) => __awaiter(void 0, [items_1, ...args_1], void 0, function* (items, itemsPerRow = 7, boxWidth = 25) {
89
+ return new Promise((resolve) => {
90
+ const { unmount } = render(React.createElement(MultiSelectTable, { items: items, itemsPerRow: itemsPerRow, onSubmit: (selectedItems) => {
91
+ unmount();
92
+ resolve(selectedItems.map((item) => item.label));
93
+ }, boxWidth: boxWidth }));
94
+ });
95
+ });
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { render } from 'ink';
3
+ import SelectInput from 'ink-select-input';
4
+ import { Text } from 'ink';
5
+ import Item from './selectItem.js';
6
+ const Indicator = ({ isSelected }) => {
7
+ return React.createElement(Text, null, isSelected ? '👉 ' : ' ');
8
+ };
9
+ const SelectItems = ({ items, handleSelect }) => {
10
+ const { unmount } = render(React.createElement(SelectInput, { items: items, onSelect: onSelect, itemComponent: Item, indicatorComponent: Indicator }));
11
+ function onSelect(item) {
12
+ unmount();
13
+ handleSelect(item);
14
+ }
15
+ return unmount;
16
+ };
17
+ export default SelectItems;
@@ -0,0 +1,6 @@
1
+ import * as React from 'react';
2
+ import { Text } from 'ink';
3
+ function Item({ isSelected = false, label }) {
4
+ return React.createElement(Text, { color: isSelected ? 'green' : undefined }, label);
5
+ }
6
+ export default Item;
@@ -0,0 +1,9 @@
1
+ import SelectItems from './selectInput.js';
2
+ const yesNoItems = [
3
+ { label: 'Yes', value: 'yes' },
4
+ { label: 'No', value: 'no' }
5
+ ];
6
+ export const yesNoPrompt = (handleSelect, title) => {
7
+ console.log(title);
8
+ SelectItems({ items: yesNoItems, handleSelect });
9
+ };
@@ -0,0 +1,224 @@
1
+ # Commands
2
+
3
+ ### init
4
+
5
+ Initialize a routine with a template.
6
+
7
+ ```bash
8
+ $ esa init [OPTIONS]
9
+ ```
10
+
11
+ - -c, --config `boolean` `optional`
12
+ - Generate a config file for your project.
13
+
14
+ ### routine [script]
15
+
16
+ Manage your routine.
17
+
18
+ #### delete <routineName>
19
+
20
+ Delete a routine.
21
+
22
+ ```bash
23
+ $ esa routine delete <routineName>
24
+ ```
25
+
26
+ - routineName `string` `required`
27
+ - The name of the routine to delete.
28
+
29
+ #### list
30
+
31
+ List all your routines.
32
+
33
+ ```bash
34
+ $ esa routine list
35
+ ```
36
+
37
+ ### route [script]
38
+
39
+ Manage the routes bound to your routine.
40
+
41
+ #### add [route] [site]
42
+
43
+ Bind a Route to a routine.
44
+
45
+ ```bash
46
+ $ esa route add [route] [site]
47
+ ```
48
+
49
+ #### delete <route>
50
+
51
+ Delete a related route.
52
+
53
+ ```bash
54
+ $ esa route delete <route>
55
+ ```
56
+
57
+ - route `string` `required`
58
+ - The name of the routes to delete.
59
+
60
+ #### list
61
+
62
+ List all related routes.
63
+
64
+ ```bash
65
+ $ esa route list
66
+ ```
67
+
68
+ ### login
69
+
70
+ Login to the server.
71
+
72
+ ```bash
73
+ $ esa login
74
+ ```
75
+
76
+ ### dev [entry]
77
+
78
+ Start a local server for developing your routine.
79
+
80
+ ```bash
81
+ $ esa dev [entry] [OPTIONS]
82
+ ```
83
+
84
+ - entry `string` `optional`
85
+ - Entry file of the Routine.
86
+
87
+ - -port, --p `number` `optional`
88
+ - Port to listen on.
89
+
90
+ - --inspect-port `number` `optional`
91
+ - Chrome inspect devTool port.
92
+
93
+ - -minify, --m `boolean` `optional`
94
+ - Minify code during development.
95
+
96
+ - --local-upstream `string` `optional`
97
+ - Host to act as origin in development.
98
+
99
+ - --refresh-command `string` `optional`
100
+ - Provide a command to be executed before the auto-refresh on save.
101
+
102
+ ### deployments [script]
103
+
104
+ Manage your deployments.
105
+
106
+ #### delete <deploymentId>
107
+
108
+ Delete one or more deployment versions.
109
+
110
+ ```bash
111
+ $ esa deployments delete <deploymentId>
112
+ ```
113
+
114
+ - deploymentId `string` `required`
115
+ - The ID of the deployments to delete.
116
+
117
+ #### list
118
+
119
+ List all deployments.
120
+
121
+ ```bash
122
+ $ esa deployments list
123
+ ```
124
+
125
+ ### deploy [entry]
126
+
127
+ Deploy your project.
128
+
129
+ ```bash
130
+ $ esa deploy [entry]
131
+ ```
132
+
133
+ - entry `string` `optional`
134
+ - Entry file of the Routine.
135
+
136
+ ### domain [script]
137
+
138
+ Manage the domain names bound to your routine.
139
+
140
+ #### add <domain>
141
+
142
+ Bind a domain to a routine.
143
+
144
+ ```bash
145
+ $ esa domain add <domain>
146
+ ```
147
+
148
+ - domain `string` `required`
149
+ - The name of domain to add.
150
+
151
+ #### delete <domain>
152
+
153
+ Delete a related domain.
154
+
155
+ ```bash
156
+ $ esa domain delete <domain>
157
+ ```
158
+
159
+ - domains `string` `required`
160
+ - The names of the related domains to delete.
161
+
162
+ #### list
163
+
164
+ List all related domains.
165
+
166
+ ```bash
167
+ $ esa domain list
168
+ ```
169
+
170
+ ### commit [entry]
171
+
172
+ Commit your code, save as a new version.
173
+
174
+ ```bash
175
+ $ esa commit [entry] [OPTIONS]
176
+ ```
177
+
178
+ - entry `string` `optional`
179
+ - Entry file of the Routine.
180
+
181
+ - -m, --minify `boolean` `optional`
182
+ - Minify code before committing.
183
+
184
+ ### logout
185
+
186
+ Logout.
187
+
188
+ ```bash
189
+ $ esa logout
190
+ ```
191
+
192
+ ### config
193
+
194
+ Modify your local or global configuration using -l, -g.
195
+
196
+ ```bash
197
+ $ esa config [OPTIONS]
198
+ ```
199
+
200
+ - -g, --global `boolean` `optional`
201
+ - Edit global config file.
202
+
203
+ - -l, --local `boolean` `optional`
204
+ - Edit local config file.
205
+
206
+ ### lang
207
+
208
+ Set the language of the CLI.
209
+
210
+ ```bash
211
+ $ esa lang
212
+ ```
213
+
214
+ ### site [script]
215
+
216
+ Manage your sites.
217
+
218
+ #### list
219
+
220
+ List all your sites.
221
+
222
+ ```bash
223
+ $ esa site list
224
+ ```