mstate-cli 0.1.4 → 0.1.7
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.
- package/.vscode/settings.json +3 -0
- package/Readme.md +32 -9
- package/dist/common/constant.js +2 -1
- package/dist/common/enum.js +1 -0
- package/dist/common/utils.js +7 -0
- package/dist/handlers/action.handler.js +70 -84
- package/dist/handlers/company.handler.js +104 -0
- package/dist/handlers/environment.handler.js +59 -74
- package/dist/handlers/help.handler.js +21 -0
- package/dist/handlers/mobioffice.handler.js +43 -47
- package/dist/handlers/workflow.handler.js +68 -78
- package/dist/index.js +60 -41
- package/package.json +4 -2
- package/src/common/constant.ts +2 -1
- package/src/common/enum.ts +1 -0
- package/src/common/utils.ts +7 -1
- package/src/handlers/action.handler.ts +87 -95
- package/src/handlers/company.handler.ts +108 -0
- package/src/handlers/environment.handler.ts +73 -79
- package/src/handlers/help.handler.ts +34 -0
- package/src/handlers/mobioffice.handler.ts +47 -47
- package/src/handlers/workflow.handler.ts +81 -77
- package/src/index.ts +52 -60
@@ -15,6 +15,7 @@ const utils_1 = require("../common/utils");
|
|
15
15
|
var Key;
|
16
16
|
(function (Key) {
|
17
17
|
Key["WORKFLOW"] = "workflow=";
|
18
|
+
Key["PERMISSIONS"] = "permissions=";
|
18
19
|
Key["SECRET_KEY"] = "secret=";
|
19
20
|
Key["COMPANY_ID"] = "company=";
|
20
21
|
Key["USER_ID"] = "user=";
|
@@ -23,54 +24,49 @@ class MobiofficeHandler {
|
|
23
24
|
constructor() { }
|
24
25
|
linkToMobioffice(action) {
|
25
26
|
return __awaiter(this, void 0, void 0, function* () {
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
return;
|
36
|
-
}
|
37
|
-
if (!secretKey) {
|
38
|
-
utils_1.customLog.error(`Parameter secret is required`);
|
39
|
-
return;
|
40
|
-
}
|
41
|
-
if (!companyID) {
|
42
|
-
utils_1.customLog.error(`Parameter company is required`);
|
43
|
-
return;
|
44
|
-
}
|
45
|
-
if (!user) {
|
46
|
-
utils_1.customLog.error(`Parameter user is required`);
|
47
|
-
return;
|
48
|
-
}
|
49
|
-
const url = `${constant_1.MOBIOFFICE_URL}/Mstate/workFlow/user`;
|
50
|
-
const responseJSON = yield fetch(url, {
|
51
|
-
method: 'POST',
|
52
|
-
headers: {
|
53
|
-
'secret-key': secretKey,
|
54
|
-
'Content-Type': 'application/json',
|
55
|
-
},
|
56
|
-
body: JSON.stringify({
|
57
|
-
action: action.toUpperCase(),
|
58
|
-
workflow: workflowName,
|
59
|
-
secret: secretKey,
|
60
|
-
companyID,
|
61
|
-
user,
|
62
|
-
}),
|
63
|
-
});
|
64
|
-
const response = yield responseJSON.json();
|
65
|
-
if (responseJSON.status >= 400) {
|
66
|
-
utils_1.customLog.error('Invalid Parameters: ', responseJSON.statusText);
|
67
|
-
}
|
68
|
-
else {
|
69
|
-
utils_1.customLog.success('Workflow Added successfully', response === null || response === void 0 ? void 0 : response.message);
|
70
|
-
}
|
27
|
+
const args = process.argv;
|
28
|
+
const dirPath = (0, utils_1.getValueFromArgs)(args, Key.WORKFLOW);
|
29
|
+
const workflowName = dirPath.replace(/\//g, '__');
|
30
|
+
const secretKey = (0, utils_1.getValueFromArgs)(args, Key.SECRET_KEY);
|
31
|
+
const companyID = (0, utils_1.getValueFromArgs)(args, Key.COMPANY_ID);
|
32
|
+
const user = (0, utils_1.getValueFromArgs)(args, Key.USER_ID);
|
33
|
+
if (!workflowName) {
|
34
|
+
utils_1.customLog.changeAndThrow(`Parameter workflow is required`);
|
35
|
+
return;
|
71
36
|
}
|
72
|
-
|
73
|
-
utils_1.customLog.
|
37
|
+
if (!secretKey) {
|
38
|
+
utils_1.customLog.changeAndThrow(`Parameter secret is required`);
|
39
|
+
return;
|
40
|
+
}
|
41
|
+
if (!companyID) {
|
42
|
+
utils_1.customLog.changeAndThrow(`Parameter company is required`);
|
43
|
+
return;
|
44
|
+
}
|
45
|
+
if (!user) {
|
46
|
+
utils_1.customLog.changeAndThrow(`Parameter user is required`);
|
47
|
+
return;
|
48
|
+
}
|
49
|
+
const url = `${constant_1.MOBIOFFICE_URL}/Mstate/workFlow/user`;
|
50
|
+
const responseJSON = yield fetch(url, {
|
51
|
+
method: 'POST',
|
52
|
+
headers: {
|
53
|
+
'secret-key': secretKey,
|
54
|
+
'Content-Type': 'application/json',
|
55
|
+
},
|
56
|
+
body: JSON.stringify({
|
57
|
+
action: action.toUpperCase(),
|
58
|
+
workflow: workflowName,
|
59
|
+
secret: secretKey,
|
60
|
+
companyID,
|
61
|
+
user,
|
62
|
+
}),
|
63
|
+
});
|
64
|
+
const response = yield responseJSON.json();
|
65
|
+
if (responseJSON.status >= 400) {
|
66
|
+
utils_1.customLog.changeAndThrow('Invalid Parameters for Linking: ', responseJSON.statusText);
|
67
|
+
}
|
68
|
+
else {
|
69
|
+
utils_1.customLog.success('Workflow Added successfully', response === null || response === void 0 ? void 0 : response.message);
|
74
70
|
}
|
75
71
|
});
|
76
72
|
}
|
@@ -58,11 +58,11 @@ class WorkflowHandler {
|
|
58
58
|
const file = (0, utils_1.getValueFromArgs)(args, Key.FILE);
|
59
59
|
const secretKey = (0, utils_1.getValueFromArgs)(args, Key.SECRET_KEY);
|
60
60
|
if (!file) {
|
61
|
-
utils_1.customLog.
|
61
|
+
utils_1.customLog.changeAndThrow(`Parameter file is required`);
|
62
62
|
return;
|
63
63
|
}
|
64
64
|
if (!secretKey) {
|
65
|
-
utils_1.customLog.
|
65
|
+
utils_1.customLog.changeAndThrow(`Parameter secret is required`);
|
66
66
|
return;
|
67
67
|
}
|
68
68
|
const filePath = path_1.default.resolve(file);
|
@@ -85,97 +85,87 @@ class WorkflowHandler {
|
|
85
85
|
});
|
86
86
|
const response = yield responseJSON.json();
|
87
87
|
if (response === null || response === void 0 ? void 0 : response.errors) {
|
88
|
-
utils_1.customLog.
|
88
|
+
utils_1.customLog.changeAndThrow('Invalid Parameters for Workflow: ', ...response === null || response === void 0 ? void 0 : response.errors);
|
89
89
|
}
|
90
90
|
else {
|
91
91
|
utils_1.customLog.success('Workflow Added successfully', response === null || response === void 0 ? void 0 : response.data);
|
92
92
|
}
|
93
93
|
}
|
94
94
|
catch (error) {
|
95
|
-
utils_1.customLog.
|
95
|
+
utils_1.customLog.changeAndThrow(error.message);
|
96
96
|
}
|
97
97
|
});
|
98
98
|
}
|
99
99
|
updateWorkflowToDB() {
|
100
100
|
return __awaiter(this, void 0, void 0, function* () {
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
return;
|
109
|
-
}
|
110
|
-
if (!workflowName) {
|
111
|
-
utils_1.customLog.error(`Parameter workflow is required`);
|
112
|
-
return;
|
113
|
-
}
|
114
|
-
const folderPath = path_1.default.resolve(dirPath);
|
115
|
-
const filePath = path_1.default.join(folderPath, 'workflow.json');
|
116
|
-
const workflowJSON = fs.readFileSync(filePath, 'utf8');
|
117
|
-
let query = `?workflow=${workflowName}`;
|
118
|
-
const url = `${constant_1.MSTATE_URL}/workflow/config${query}`;
|
119
|
-
const responseJSON = yield fetch(url, {
|
120
|
-
method: 'PUT',
|
121
|
-
headers: {
|
122
|
-
'secret-key': secretKey,
|
123
|
-
'Content-Type': 'application/json',
|
124
|
-
},
|
125
|
-
body: workflowJSON,
|
126
|
-
});
|
127
|
-
const response = yield responseJSON.json();
|
128
|
-
if (response === null || response === void 0 ? void 0 : response.errors) {
|
129
|
-
utils_1.customLog.error('Invalid Parameters: ', response === null || response === void 0 ? void 0 : response.errors);
|
130
|
-
}
|
131
|
-
else {
|
132
|
-
utils_1.customLog.success('Workflow Uploaded successfully \n', response === null || response === void 0 ? void 0 : response.data);
|
133
|
-
}
|
134
|
-
return response;
|
101
|
+
const args = process.argv;
|
102
|
+
const dirPath = (0, utils_1.getValueFromArgs)(args, Key.WORKFLOW);
|
103
|
+
const workflowName = dirPath.replace(/\//g, '__');
|
104
|
+
const secretKey = (0, utils_1.getValueFromArgs)(args, Key.SECRET_KEY);
|
105
|
+
if (!secretKey) {
|
106
|
+
utils_1.customLog.changeAndThrow(`Parameter secret is required`);
|
107
|
+
return;
|
135
108
|
}
|
136
|
-
|
137
|
-
utils_1.customLog.
|
109
|
+
if (!workflowName) {
|
110
|
+
utils_1.customLog.changeAndThrow(`Parameter workflow is required`);
|
111
|
+
return;
|
112
|
+
}
|
113
|
+
const folderPath = path_1.default.resolve(dirPath);
|
114
|
+
const filePath = path_1.default.join(folderPath, 'workflow.json');
|
115
|
+
const workflowJSON = fs.readFileSync(filePath, 'utf8');
|
116
|
+
let query = `?workflow=${workflowName}`;
|
117
|
+
const url = `${constant_1.MSTATE_URL}/workflow/config${query}`;
|
118
|
+
const responseJSON = yield fetch(url, {
|
119
|
+
method: 'PUT',
|
120
|
+
headers: {
|
121
|
+
'secret-key': secretKey,
|
122
|
+
'Content-Type': 'application/json',
|
123
|
+
},
|
124
|
+
body: workflowJSON,
|
125
|
+
});
|
126
|
+
const response = yield responseJSON.json();
|
127
|
+
if (response === null || response === void 0 ? void 0 : response.errors) {
|
128
|
+
utils_1.customLog.changeAndThrow('Invalid Parameters for Server: ', ...response === null || response === void 0 ? void 0 : response.errors);
|
129
|
+
}
|
130
|
+
else {
|
131
|
+
utils_1.customLog.success('Workflow Uploaded successfully \n', response === null || response === void 0 ? void 0 : response.data);
|
138
132
|
}
|
133
|
+
return response;
|
139
134
|
});
|
140
135
|
}
|
141
136
|
cloneWorkflow() {
|
142
137
|
return __awaiter(this, void 0, void 0, function* () {
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
return;
|
151
|
-
}
|
152
|
-
if (!workflowName) {
|
153
|
-
utils_1.customLog.error(`Parameter workflow is required`);
|
154
|
-
return;
|
155
|
-
}
|
156
|
-
const url = `${constant_1.MSTATE_URL}/workflow/config/${workflowName}`;
|
157
|
-
const responseJSON = yield fetch(url, {
|
158
|
-
method: 'GET',
|
159
|
-
headers: {
|
160
|
-
'Content-Type': 'application/json',
|
161
|
-
'secret-key': secretKey,
|
162
|
-
},
|
163
|
-
});
|
164
|
-
const response = yield responseJSON.json();
|
165
|
-
if (response === null || response === void 0 ? void 0 : response.errors) {
|
166
|
-
utils_1.customLog.error('Invalid Parameters: ', response === null || response === void 0 ? void 0 : response.errors);
|
167
|
-
}
|
168
|
-
else {
|
169
|
-
const workflowConfig = response === null || response === void 0 ? void 0 : response.data;
|
170
|
-
const folderPath = path_1.default.resolve(dirPath);
|
171
|
-
fs.mkdirSync(folderPath, { recursive: true });
|
172
|
-
const filePath = path_1.default.join(folderPath, 'workflow.json');
|
173
|
-
fs.writeFileSync(filePath, JSON.stringify(workflowConfig, null, 2));
|
174
|
-
utils_1.customLog.success(`Workflow cloned successfully`);
|
175
|
-
}
|
138
|
+
const args = process.argv;
|
139
|
+
const dirPath = (0, utils_1.getValueFromArgs)(args, Key.WORKFLOW);
|
140
|
+
const workflowName = dirPath.replace(/\//g, '__');
|
141
|
+
const secretKey = (0, utils_1.getValueFromArgs)(args, Key.SECRET_KEY);
|
142
|
+
if (!secretKey) {
|
143
|
+
utils_1.customLog.changeAndThrow(`Parameter secret is required`);
|
144
|
+
return;
|
176
145
|
}
|
177
|
-
|
178
|
-
utils_1.customLog.
|
146
|
+
if (!workflowName) {
|
147
|
+
utils_1.customLog.changeAndThrow(`Parameter workflow is required`);
|
148
|
+
return;
|
149
|
+
}
|
150
|
+
const url = `${constant_1.MSTATE_URL}/workflow/config/${workflowName}`;
|
151
|
+
const responseJSON = yield fetch(url, {
|
152
|
+
method: 'GET',
|
153
|
+
headers: {
|
154
|
+
'Content-Type': 'application/json',
|
155
|
+
'secret-key': secretKey,
|
156
|
+
},
|
157
|
+
});
|
158
|
+
const response = yield responseJSON.json();
|
159
|
+
if (response === null || response === void 0 ? void 0 : response.errors) {
|
160
|
+
utils_1.customLog.changeAndThrow('Invalid Parameters for Workflow: ', ...response === null || response === void 0 ? void 0 : response.errors);
|
161
|
+
}
|
162
|
+
else {
|
163
|
+
const workflowConfig = response === null || response === void 0 ? void 0 : response.data;
|
164
|
+
const folderPath = path_1.default.resolve(dirPath);
|
165
|
+
fs.mkdirSync(folderPath, { recursive: true });
|
166
|
+
const filePath = path_1.default.join(folderPath, 'workflow.json');
|
167
|
+
fs.writeFileSync(filePath, JSON.stringify(workflowConfig, null, 2));
|
168
|
+
utils_1.customLog.success(`Workflow cloned successfully`);
|
179
169
|
}
|
180
170
|
});
|
181
171
|
}
|
@@ -186,11 +176,11 @@ class WorkflowHandler {
|
|
186
176
|
const workflowName = dirPath.replace(/\//g, '__');
|
187
177
|
const secretKey = (0, utils_1.getValueFromArgs)(args, Key.SECRET_KEY);
|
188
178
|
if (!secretKey) {
|
189
|
-
utils_1.customLog.
|
179
|
+
utils_1.customLog.changeAndThrow(`Parameter secret is required`);
|
190
180
|
return;
|
191
181
|
}
|
192
182
|
if (!workflowName) {
|
193
|
-
utils_1.customLog.
|
183
|
+
utils_1.customLog.changeAndThrow(`Parameter workflow is required`);
|
194
184
|
return;
|
195
185
|
}
|
196
186
|
const url = `${constant_1.MSTATE_URL}/cache/reset/${workflowName}`;
|
@@ -203,7 +193,7 @@ class WorkflowHandler {
|
|
203
193
|
});
|
204
194
|
const response = yield responseJSON.json();
|
205
195
|
if (response === null || response === void 0 ? void 0 : response.errors) {
|
206
|
-
utils_1.customLog.
|
196
|
+
utils_1.customLog.changeAndThrow('Invalid Parameters for Workflow: ', ...response === null || response === void 0 ? void 0 : response.errors);
|
207
197
|
}
|
208
198
|
else {
|
209
199
|
utils_1.customLog.success(`Workflow updated successfully`);
|
package/dist/index.js
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
"use strict";
|
3
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
4
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
5
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
6
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
7
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
8
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
9
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
10
|
+
});
|
11
|
+
};
|
3
12
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
4
13
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
5
14
|
};
|
@@ -11,45 +20,55 @@ const enum_1 = require("./common/enum");
|
|
11
20
|
const mobioffice_handler_1 = require("./handlers/mobioffice.handler");
|
12
21
|
const utils_1 = require("./common/utils");
|
13
22
|
const environment_handler_1 = require("./handlers/environment.handler");
|
14
|
-
const
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
}
|
23
|
+
const company_handler_1 = require("./handlers/company.handler");
|
24
|
+
const process_1 = require("process");
|
25
|
+
const help_handler_1 = require("./handlers/help.handler");
|
26
|
+
const [action] = process_1.argv.slice(2);
|
27
|
+
(function () {
|
28
|
+
return __awaiter(this, void 0, void 0, function* () {
|
29
|
+
switch (action) {
|
30
|
+
case enum_1.CmdAction.VERSION:
|
31
|
+
case enum_1.CmdAction.VERSION_FLAG:
|
32
|
+
console.log(`v${package_json_1.default.version}`);
|
33
|
+
break;
|
34
|
+
case enum_1.CmdAction.LINK:
|
35
|
+
case enum_1.CmdAction.UNLINK:
|
36
|
+
yield mobioffice_handler_1.mobiofficeHandler.linkToMobioffice(action);
|
37
|
+
break;
|
38
|
+
case enum_1.CmdAction.USER:
|
39
|
+
if ((0, utils_1.hasFlag)(process_1.argv, '-d'))
|
40
|
+
company_handler_1.companyHandler.revokePermission();
|
41
|
+
else
|
42
|
+
company_handler_1.companyHandler.addToken();
|
43
|
+
break;
|
44
|
+
case enum_1.CmdAction.CLONE:
|
45
|
+
yield workflow_handler_1.workflowHandler.cloneWorkflow();
|
46
|
+
yield action_handler_1.actionHandler.cloneActions();
|
47
|
+
yield environment_handler_1.environmentHandler.cloneEnvironments();
|
48
|
+
break;
|
49
|
+
case enum_1.CmdAction.ADD:
|
50
|
+
yield workflow_handler_1.workflowHandler.saveToDB();
|
51
|
+
break;
|
52
|
+
case enum_1.CmdAction.PUSH:
|
53
|
+
yield workflow_handler_1.workflowHandler.updateWorkflowToDB();
|
54
|
+
yield action_handler_1.actionHandler.saveToDB();
|
55
|
+
yield environment_handler_1.environmentHandler.saveToDB();
|
56
|
+
yield workflow_handler_1.workflowHandler.resetCache();
|
57
|
+
break;
|
58
|
+
case enum_1.CmdAction.HELP:
|
59
|
+
case enum_1.CmdAction.HELP_FLAG:
|
60
|
+
help_handler_1.helpHandler.logCommandInfo();
|
61
|
+
break;
|
62
|
+
default:
|
63
|
+
utils_1.customLog.changeAndThrow(`${action ? 'Invalid' : 'Missing'} script: ${action !== null && action !== void 0 ? action : ''}`);
|
64
|
+
console.log(`use 'mstate ${enum_1.CmdAction.HELP_FLAG}, ${enum_1.CmdAction.HELP}' for getting allowed action`);
|
65
|
+
}
|
66
|
+
});
|
67
|
+
})().catch((error) => {
|
68
|
+
if ((0, utils_1.hasFlag)(process_1.argv, enum_1.CmdAction.HELP) || (0, utils_1.hasFlag)(process_1.argv, enum_1.CmdAction.HELP_FLAG)) {
|
69
|
+
help_handler_1.helpHandler.logActionInfo(action);
|
70
|
+
}
|
71
|
+
else
|
72
|
+
utils_1.customLog.error(error.message);
|
73
|
+
});
|
55
74
|
console.log('');
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "mstate-cli",
|
3
|
-
"version": "0.1.
|
3
|
+
"version": "0.1.7",
|
4
4
|
"main": "index.js",
|
5
5
|
"bin": {
|
6
6
|
"mstate": "./dist/index.js"
|
@@ -11,7 +11,9 @@
|
|
11
11
|
},
|
12
12
|
"keywords": [
|
13
13
|
"mstate",
|
14
|
-
"workflow"
|
14
|
+
"workflow",
|
15
|
+
"cli",
|
16
|
+
"automation"
|
15
17
|
],
|
16
18
|
"author": "",
|
17
19
|
"license": "ISC",
|
package/src/common/constant.ts
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
export const MSTATE_URL = 'http://localhost:3000/api';
|
1
2
|
// export const MSTATE_URL = 'https://dev.mstate.mobioffice.io/api';
|
2
|
-
export const MSTATE_URL = 'https://api.mstate.mobioffice.io/api';
|
3
|
+
// export const MSTATE_URL = 'https://api.mstate.mobioffice.io/api';
|
3
4
|
export const MOBIOFFICE_URL = 'https://server.mobioffice.io/api';
|
package/src/common/enum.ts
CHANGED
package/src/common/utils.ts
CHANGED
@@ -3,13 +3,15 @@ export function getValueFromArgs(args: string[], key: string) {
|
|
3
3
|
}
|
4
4
|
|
5
5
|
export const customLog = {
|
6
|
+
changeAndThrow(...message: string[]) {
|
7
|
+
throw new Error(message.join('\n'));
|
8
|
+
},
|
6
9
|
error(...message: string[]) {
|
7
10
|
const RED_COLOR = '\x1b[31m'; // ANSI code for red
|
8
11
|
const RESET_COLOR = '\x1b[0m'; // ANSI code to reset to default color
|
9
12
|
|
10
13
|
console.error(`${RED_COLOR}[MSTATE][ERROR] ${RESET_COLOR}`, ...message);
|
11
14
|
},
|
12
|
-
|
13
15
|
success(...message: string[]) {
|
14
16
|
const GREEN_COLOR = '\x1b[32m'; // ANSI code for green
|
15
17
|
const RESET_COLOR = '\x1b[0m'; // ANSI code to reset to default color
|
@@ -25,3 +27,7 @@ export const customLog = {
|
|
25
27
|
);
|
26
28
|
},
|
27
29
|
};
|
30
|
+
|
31
|
+
export function hasFlag(args: string[], flag: string) {
|
32
|
+
return args.includes(flag.toUpperCase()) || args.includes(flag.toLowerCase());
|
33
|
+
}
|