@raisenow/tamaro-cli 1.5.0 → 1.6.0-dev.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.
- package/.history/.eslintignore_20220609190420 +4 -0
- package/.history/.eslintignore_20230911190227 +6 -0
- package/.history/.eslintignore_20230911211247 +7 -0
- package/.history/.eslintignore_20230911211250 +7 -0
- package/.history/.eslintrc_20230911201601.js +49 -0
- package/.history/.eslintrc_20230911201643.js +49 -0
- package/.history/.eslintrc_20230911201735.js +49 -0
- package/.history/.eslintrc_20230911201913.js +64 -0
- package/.history/.eslintrc_20230911202002.js +62 -0
- package/.history/.eslintrc_20230911202138.js +133 -0
- package/.history/.eslintrc_20230911202140.js +133 -0
- package/.history/.eslintrc_20230911202145.js +133 -0
- package/.history/.eslintrc_20230911202147.js +133 -0
- package/.history/.eslintrc_20230911202406.js +133 -0
- package/.history/.eslintrc_20230911202447.js +133 -0
- package/.history/.eslintrc_20230911202453.js +133 -0
- package/.history/.eslintrc_20230911202511.js +133 -0
- package/.history/.eslintrc_20230911202527.js +133 -0
- package/.history/.eslintrc_20230911202639.js +125 -0
- package/.history/.eslintrc_20230911202721.js +149 -0
- package/.history/.eslintrc_20230911202746.js +149 -0
- package/.history/.eslintrc_20240423125702.cjs +148 -0
- package/.history/.gitignore_20220609190420 +14 -0
- package/.history/.gitignore_20230911185959 +4 -0
- package/.history/.gitignore_20230911190006 +4 -0
- package/.history/.gitignore_20230911190007 +4 -0
- package/.history/.nmprc_20241004144025 +0 -0
- package/.history/.nmprc_20241004144041 +1 -0
- package/.history/.npmrc_20241004144040 +1 -0
- package/.history/.npmrc_20241004144152 +1 -0
- package/.history/.npmrc_20241004145639 +2 -0
- package/.history/.npmrc_20241004145649 +1 -0
- package/.history/.nvmrc_20250729181039 +1 -0
- package/.history/.prettierignore_20220609190420 +5 -0
- package/.history/.prettierignore_20230911190242 +7 -0
- package/.history/.prettierignore_20230911190245 +7 -0
- package/.history/.prettierignore_20230911211301 +8 -0
- package/.history/CHANGELOG_20250729195139.md +28 -0
- package/.history/CHANGELOG_20250729195148.md +29 -0
- package/.history/CHANGELOG_20250729195156.md +28 -0
- package/.history/CHANGELOG_20250729195218.md +29 -0
- package/.history/CHANGELOG_20250729195223.md +27 -0
- package/.history/CHANGELOG_20250729195506.md +29 -0
- package/.history/CHANGELOG_20250729224404.md +30 -0
- package/.history/CHANGELOG_20250729224411.md +30 -0
- package/.history/CHANGELOG_20250730124538.md +41 -0
- package/.history/CHANGELOG_20250730124603.md +38 -0
- package/.history/CHANGELOG_20250730124627.md +36 -0
- package/.history/CHANGELOG_20250730124638.md +36 -0
- package/.history/CHANGELOG_20250730124640.md +36 -0
- package/.history/README_20230911145033.md +245 -0
- package/.history/README_20230911151749.md +245 -0
- package/.history/README_20230911151844.md +245 -0
- package/.history/README_20230911153040.md +245 -0
- package/.history/README_20230911202959.md +245 -0
- package/.history/bitbucket-pipelines_20250729111540.yml +46 -0
- package/.history/bitbucket-pipelines_20250729210338.yml +46 -0
- package/.history/bitbucket-pipelines_20250729210340.yml +46 -0
- package/.history/bitbucket-pipelines_20250729210342.yml +46 -0
- package/.history/bitbucket-pipelines_20250729222234.yml +47 -0
- package/.history/bitbucket-pipelines_20250729222554.yml +47 -0
- package/.history/bitbucket-pipelines_20250729222555.yml +47 -0
- package/.history/bitbucket-pipelines_20250729223022.yml +46 -0
- package/.history/bitbucket-pipelines_20250729223024.yml +46 -0
- package/.history/cli_20241005014539 +3 -0
- package/.history/cli_20241005014542 +3 -0
- package/.history/cli_20241005014848 +3 -0
- package/.history/dist/chunk-FICM3HUI_20230912183408.js +302 -0
- package/{dist/chunk-HGPQTHLY.js → .history/dist/chunk-FICM3HUI_20230912201610.js} +31 -50
- package/.history/package_20250729182417.json +111 -0
- package/.history/package_20250729182419.json +111 -0
- package/.history/package_20250729182618.json +110 -0
- package/.history/package_20250729182834.json +110 -0
- package/.history/package_20250729183032.json +110 -0
- package/.history/package_20250729183033.json +110 -0
- package/.history/package_20250729185750.json +110 -0
- package/.history/package_20250729185815.json +110 -0
- package/.history/package_20250729185846.json +110 -0
- package/.history/package_20250729185854.json +110 -0
- package/.history/package_20250729185943.json +110 -0
- package/.history/package_20250729190645.json +110 -0
- package/.history/package_20250729195934.json +110 -0
- package/.history/package_20250729200013.json +110 -0
- package/.history/package_20250729200056.json +110 -0
- package/.history/package_20250729200434.json +110 -0
- package/.history/package_20250729200808.json +110 -0
- package/.history/package_20250729200944.json +110 -0
- package/.history/package_20250729214420.json +114 -0
- package/.history/package_20250729223112.json +110 -0
- package/.history/package_20250729223127.json +110 -0
- package/.history/package_20250729223134.json +110 -0
- package/.history/package_20250730124647.json +114 -0
- package/.history/tsconfig_20241005001442.json +34 -0
- package/.history/tsconfig_20241005001500.json +34 -0
- package/.history/tsconfig_20241005001540.json +34 -0
- package/.history/tsconfig_20241005014429.json +42 -0
- package/.history/tsconfig_20241005014436.json +42 -0
- package/.history/tsconfig_20241005014439.json +38 -0
- package/.history/tsconfig_20241005014455.json +38 -0
- package/.history/tsconfig_20241005014521.json +38 -0
- package/.history/vitest.config_20250729214539.ts +0 -0
- package/.history/vitest.config_20250729214659.ts +24 -0
- package/.history/vitest.config_20250729214748.ts +21 -0
- package/.history/vitest.config_20250729214825.ts +21 -0
- package/.history/vitest.config_20250729214902.ts +21 -0
- package/.history/vitest.config_20250729222125.ts +20 -0
- package/.history/vitest.config_20250729222213.ts +20 -0
- package/.idea/codeStyles/Project.xml +131 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/misc.xml +17 -0
- package/.idea/modules.xml +8 -0
- package/.idea/prettier.xml +6 -0
- package/.idea/tamaro-cli.iml +12 -0
- package/.idea/vcs.xml +6 -0
- package/.nvmrc +1 -1
- package/bitbucket-pipelines.yml +1 -1
- package/dist/cli.js +559 -845
- package/dist/env-Cpc7KHou.js +245 -0
- package/dist/webpack.config.js +310 -441
- package/package.json +37 -41
- package/pnpm-workspace.yaml +4 -0
- package/tsdown.config.ts +11 -0
package/dist/cli.js
CHANGED
|
@@ -1,367 +1,315 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
AWS_CLOUDFRONT_DISTRIBUTION_ID,
|
|
4
|
-
AWS_S3_BUCKET_TAMARO,
|
|
5
|
-
AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD,
|
|
6
|
-
AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_STAGE,
|
|
7
|
-
CORE_CONFIG_NAME,
|
|
8
|
-
DEFAULT_PORT,
|
|
9
|
-
DEFAULT_TAG,
|
|
10
|
-
HTTPS_CRT_FILE,
|
|
11
|
-
HTTPS_KEY_FILE,
|
|
12
|
-
applyEnv,
|
|
13
|
-
assertEnvValid,
|
|
14
|
-
getIfCoreFns,
|
|
15
|
-
getPaths,
|
|
16
|
-
getWidgetUuid,
|
|
17
|
-
halt,
|
|
18
|
-
logCommand,
|
|
19
|
-
logDataTable,
|
|
20
|
-
logError,
|
|
21
|
-
logTitle,
|
|
22
|
-
resolveBin,
|
|
23
|
-
resolveOwn,
|
|
24
|
-
runCommandSync
|
|
25
|
-
} from "./chunk-HGPQTHLY.js";
|
|
26
|
-
|
|
27
|
-
// src/cli.ts
|
|
2
|
+
import { C as runCommandSync, D as logTitle, E as logError, S as halt, T as logDataTable, _ as CORE_CONFIG_NAME, a as getIfCoreFns, b as HTTPS_CRT_FILE, c as getWidgetUuid, f as resolveOwn, g as AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_STAGE, h as AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD, m as AWS_S3_BUCKET_TAMARO, n as assertEnvValid, o as getPaths, p as AWS_CLOUDFRONT_DISTRIBUTION_ID, t as applyEnv, u as resolveBin, v as DEFAULT_PORT, w as logCommand, x as HTTPS_KEY_FILE, y as DEFAULT_TAG } from "./env-Cpc7KHou.js";
|
|
28
3
|
import { createCommand } from "commander";
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
import
|
|
32
|
-
|
|
33
|
-
// src/lib/validators/validateEmailTemplates.ts
|
|
34
|
-
import fs from "fs";
|
|
4
|
+
import { globSync } from "glob";
|
|
5
|
+
import { execaCommandSync } from "execa";
|
|
6
|
+
import stripIndent from "strip-indent";
|
|
7
|
+
import fs from "node:fs";
|
|
35
8
|
import Handlebars from "handlebars";
|
|
36
9
|
import helpers from "handlebars-helpers";
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
10
|
+
import prompts from "prompts";
|
|
11
|
+
import { resolve } from "path";
|
|
12
|
+
import { existsSync } from "fs";
|
|
13
|
+
import notifier from "node-notifier";
|
|
14
|
+
import { getPortPromise } from "portfinder";
|
|
15
|
+
|
|
16
|
+
//#region src/lib/validators/validateEmailTemplates.ts
|
|
17
|
+
/**
|
|
18
|
+
* Register custom Handlebars helpers - the same, which are used in the Email Service.
|
|
19
|
+
* Make sure to update it if new helpers are added in the Email Service.
|
|
20
|
+
*/
|
|
21
|
+
helpers.comparison({ handlebars: Handlebars });
|
|
22
|
+
/**
|
|
23
|
+
* Recurse through the expected email templates folder and attempt to parse
|
|
24
|
+
* handlebars template to validate their syntax.
|
|
25
|
+
*/
|
|
26
|
+
const validateEmailTemplates = (templatePaths) => {
|
|
27
|
+
const errors = [];
|
|
28
|
+
for (const templatePath of templatePaths) try {
|
|
29
|
+
const template = fs.readFileSync(templatePath, "utf-8");
|
|
30
|
+
assureOnlySupportedHelpers(template);
|
|
31
|
+
compileEmailTemplate(template);
|
|
32
|
+
console.log(`${templatePath} is a valid email template`);
|
|
33
|
+
} catch (e) {
|
|
34
|
+
errors.push(`${templatePath} is invalid`);
|
|
35
|
+
errors.push(e);
|
|
36
|
+
}
|
|
37
|
+
return errors;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Validate that only supported Handlebars helpers are used in the template.
|
|
41
|
+
* This function extracts helpers from the template AST and checks them
|
|
42
|
+
* against a predefined set of supported helpers.
|
|
43
|
+
*/
|
|
44
|
+
const assureOnlySupportedHelpers = (template) => {
|
|
45
|
+
/**
|
|
46
|
+
* Recursively extract helpers from the AST
|
|
47
|
+
*/
|
|
48
|
+
const extractHelpers = (ast) => {
|
|
49
|
+
const usedHelpers = /* @__PURE__ */ new Set();
|
|
50
|
+
const extractHelperName = (node) => {
|
|
51
|
+
if (node.path?.type === "PathExpression" && (node.params?.length > 0 || node.hash?.pairs?.length > 0)) return node.path?.original;
|
|
52
|
+
};
|
|
53
|
+
const visit = (node) => {
|
|
54
|
+
if (!node) return;
|
|
55
|
+
switch (node.type) {
|
|
56
|
+
case "MustacheStatement":
|
|
57
|
+
case "BlockStatement": {
|
|
58
|
+
const name = extractHelperName(node);
|
|
59
|
+
if (name) usedHelpers.add(name);
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Recursively visit children of the AST node.
|
|
65
|
+
*/
|
|
66
|
+
for (const key in node) {
|
|
67
|
+
const value = node[key];
|
|
68
|
+
if (Array.isArray(value)) value.forEach(visit);
|
|
69
|
+
else if (value && typeof value === "object" && value.type) visit(value);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
visit(ast);
|
|
73
|
+
return usedHelpers;
|
|
74
|
+
};
|
|
75
|
+
const usedHelpers = extractHelpers(Handlebars.parse(template));
|
|
76
|
+
const supportedHelpers = new Set([
|
|
77
|
+
"if",
|
|
78
|
+
"unless",
|
|
79
|
+
"each",
|
|
80
|
+
"with",
|
|
81
|
+
"log",
|
|
82
|
+
"lookup",
|
|
83
|
+
"and",
|
|
84
|
+
"compare",
|
|
85
|
+
"contains",
|
|
86
|
+
"default",
|
|
87
|
+
"eq",
|
|
88
|
+
"gt",
|
|
89
|
+
"gte",
|
|
90
|
+
"has",
|
|
91
|
+
"isFalsey",
|
|
92
|
+
"isTruthy",
|
|
93
|
+
"ifEven",
|
|
94
|
+
"ifNth",
|
|
95
|
+
"ifOdd",
|
|
96
|
+
"is",
|
|
97
|
+
"isnt",
|
|
98
|
+
"lt",
|
|
99
|
+
"lte",
|
|
100
|
+
"neither",
|
|
101
|
+
"not",
|
|
102
|
+
"or",
|
|
103
|
+
"unlessEq",
|
|
104
|
+
"unlessGt",
|
|
105
|
+
"unlessLt",
|
|
106
|
+
"unlessGteq",
|
|
107
|
+
"unlessLteq"
|
|
108
|
+
]);
|
|
109
|
+
const unsupportedHelpers = Array.from(usedHelpers).filter((h) => !supportedHelpers.has(h));
|
|
110
|
+
if (unsupportedHelpers.length > 0) throw new Error(`Email template uses unsupported Handlebars helpers: ${unsupportedHelpers.join(", ")}`);
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Compile Email template and pass an empty context to validate syntax.
|
|
114
|
+
*/
|
|
115
|
+
const compileEmailTemplate = (template) => {
|
|
116
|
+
Handlebars.compile(template)({});
|
|
138
117
|
};
|
|
139
118
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
119
|
+
//#endregion
|
|
120
|
+
//#region src/commands/validate.ts
|
|
121
|
+
/**
|
|
122
|
+
* Validates the current Tamaro configuration to avoid common errors.
|
|
123
|
+
*
|
|
124
|
+
* The command description is kept generic on purpose. We check for a number
|
|
125
|
+
* of mistakes observed when tamaro configurations are manually edited and
|
|
126
|
+
* deployed.
|
|
127
|
+
*/
|
|
128
|
+
const validate = async () => {
|
|
129
|
+
const errors = validateEmailTemplates(globSync("email-config/templates/**/*.hbs").sort());
|
|
130
|
+
if (errors.length) halt(errors.map((el) => el.toString()).join("\n"));
|
|
131
|
+
logTitle("Validated successfully");
|
|
149
132
|
};
|
|
150
133
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
stripIndent(`
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region src/lib/aws.ts
|
|
136
|
+
const awsAuthenticate = (options) => {
|
|
137
|
+
if (options.ci)
|
|
138
|
+
/**
|
|
139
|
+
* Don't try to authenticate the user.
|
|
140
|
+
* This is done when CLI is running within an automated system like pipeline,
|
|
141
|
+
* In this case "AWS_ACCESS_KEY_ID" and "AWS_SECRET_ACCESS_KEY" are used instead of "AWS_PROFILE".
|
|
142
|
+
*/
|
|
143
|
+
return;
|
|
144
|
+
try {
|
|
145
|
+
checkIdentity(options);
|
|
146
|
+
} catch (error) {
|
|
147
|
+
login(options);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
const assertProfilesPresent = () => {
|
|
151
|
+
if (getAvailableProfiles().length === 0) halt(stripIndent(`
|
|
170
152
|
No AWS profiles found.
|
|
171
153
|
Run "aws configure sso" to set up SSO-enabled profile.
|
|
172
154
|
Check the wiki for more information:
|
|
173
155
|
https://raisenow.atlassian.net/wiki/x/lIrWvg
|
|
174
|
-
`)
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
};
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
156
|
+
`));
|
|
157
|
+
};
|
|
158
|
+
const getAvailableProfiles = () => {
|
|
159
|
+
const { stdout } = execaCommandSync("aws configure list-profiles");
|
|
160
|
+
return stdout.split("\n");
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Returns caller identity data (output is ignored here).
|
|
164
|
+
* Fails in case of expired SSO session.
|
|
165
|
+
*/
|
|
166
|
+
const checkIdentity = (options) => {
|
|
167
|
+
execaCommandSync(`aws sts get-caller-identity ${prepareFlags$3(options)}`);
|
|
168
|
+
};
|
|
169
|
+
/**
|
|
170
|
+
* Opens SSO authentication page in the browser.
|
|
171
|
+
* Fails if user canceled authentication process.
|
|
172
|
+
*/
|
|
173
|
+
const login = (options) => {
|
|
174
|
+
const flags = prepareFlags$3(options);
|
|
175
|
+
try {
|
|
176
|
+
execaCommandSync(`aws sso login ${flags}`, { stdio: "inherit" });
|
|
177
|
+
console.log("");
|
|
178
|
+
} catch (error) {
|
|
179
|
+
halt("Login failed.");
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
const prepareFlags$3 = (options) => {
|
|
183
|
+
const flags = [];
|
|
184
|
+
const { profile } = options;
|
|
185
|
+
if (profile) flags.push(`--profile ${profile}`);
|
|
186
|
+
return flags.join(" ");
|
|
187
|
+
};
|
|
188
|
+
const assertProfileValid = (profile) => {
|
|
189
|
+
const profiles = getAvailableProfiles();
|
|
190
|
+
if (!profiles.includes(profile)) halt(stripIndent(`
|
|
208
191
|
AWS profile "${profile}" is not found.
|
|
209
192
|
Available profiles are: ${profiles.map((v) => `"${v}"`).join(", ")}.
|
|
210
|
-
`)
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
}
|
|
224
|
-
],
|
|
225
|
-
{
|
|
226
|
-
onCancel: () => halt()
|
|
227
|
-
}
|
|
228
|
-
);
|
|
229
|
-
return profile;
|
|
193
|
+
`));
|
|
194
|
+
};
|
|
195
|
+
const promptProfile = async () => {
|
|
196
|
+
const { profile } = await prompts([{
|
|
197
|
+
type: "select",
|
|
198
|
+
name: "profile",
|
|
199
|
+
message: "Select AWS profile",
|
|
200
|
+
choices: getAvailableProfiles().filter((v) => !!v).map((v) => ({
|
|
201
|
+
title: v,
|
|
202
|
+
value: v
|
|
203
|
+
}))
|
|
204
|
+
}], { onCancel: () => halt() });
|
|
205
|
+
return profile;
|
|
230
206
|
};
|
|
231
207
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
if (existsSync(certFile) && existsSync(keyFile)) {
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
halt(
|
|
245
|
-
stripIndent2(`
|
|
208
|
+
//#endregion
|
|
209
|
+
//#region src/lib/https.ts
|
|
210
|
+
const assertCrtExists = () => {
|
|
211
|
+
const { ifCore } = getIfCoreFns();
|
|
212
|
+
const paths = getPaths(ifCore);
|
|
213
|
+
const certFile = resolve(paths.root, HTTPS_CRT_FILE);
|
|
214
|
+
const keyFile = resolve(paths.root, HTTPS_KEY_FILE);
|
|
215
|
+
if (existsSync(certFile) && existsSync(keyFile)) return;
|
|
216
|
+
halt(stripIndent(`
|
|
246
217
|
Flag "--https" is used, but "${HTTPS_CRT_FILE}" and/or "${HTTPS_KEY_FILE}" files are not found.
|
|
247
218
|
You need to generate certificate first.
|
|
248
219
|
Check docs: https://unpkg.com/@raisenow/tamaro-cli/readme.html#/?id=use-transport-level-security-https
|
|
249
|
-
`)
|
|
250
|
-
);
|
|
220
|
+
`));
|
|
251
221
|
};
|
|
252
222
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
});
|
|
223
|
+
//#endregion
|
|
224
|
+
//#region src/lib/notifier.ts
|
|
225
|
+
const notify = (args) => {
|
|
226
|
+
const { title, message = "" } = args;
|
|
227
|
+
notifier.notify({
|
|
228
|
+
title,
|
|
229
|
+
message: stripIndent(message).trim(),
|
|
230
|
+
contentImage: "https://assets.raisenow.io/favicon.png",
|
|
231
|
+
sound: "Funk"
|
|
232
|
+
});
|
|
264
233
|
};
|
|
265
234
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
const wpConfig = resolveOwn("dist/webpack.config.js");
|
|
286
|
-
const cmd = `
|
|
287
|
-
${wpBin}
|
|
288
|
-
--config ${wpConfig}
|
|
235
|
+
//#endregion
|
|
236
|
+
//#region src/commands/build.ts
|
|
237
|
+
const build = async (options) => {
|
|
238
|
+
const { env } = options;
|
|
239
|
+
applyEnv(env);
|
|
240
|
+
if (options.deploy && !options.profile && !options.ci) {
|
|
241
|
+
assertProfilesPresent();
|
|
242
|
+
options.profile = await promptProfile();
|
|
243
|
+
}
|
|
244
|
+
assertOptionsValid$5(options);
|
|
245
|
+
await validate();
|
|
246
|
+
const flags = prepareFlags$2(options);
|
|
247
|
+
const { ifCore } = getIfCoreFns();
|
|
248
|
+
const paths = getPaths(ifCore);
|
|
249
|
+
const configName = ifCore(CORE_CONFIG_NAME, getWidgetUuid());
|
|
250
|
+
const title = ifCore("Building optimised (minified) bundle of Tamaro Core …", `Building optimised (minified) bundle of "${configName}" customer configuration …`);
|
|
251
|
+
const cmd = `
|
|
252
|
+
${resolveBin("webpack")}
|
|
253
|
+
--config ${resolveOwn("dist/webpack.config.js")}
|
|
289
254
|
--env min
|
|
290
255
|
${flags}
|
|
291
256
|
`;
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
};
|
|
323
|
-
var prepareFlags2 = (options) => {
|
|
324
|
-
const flags = [];
|
|
325
|
-
const { localCore, analyze, https, nolint } = options;
|
|
326
|
-
if (localCore) {
|
|
327
|
-
flags.push("--env localCore");
|
|
328
|
-
}
|
|
329
|
-
if (analyze) {
|
|
330
|
-
flags.push("--env analyze");
|
|
331
|
-
}
|
|
332
|
-
if (https) {
|
|
333
|
-
flags.push("--env https");
|
|
334
|
-
}
|
|
335
|
-
if (nolint) {
|
|
336
|
-
flags.push("--env nolint");
|
|
337
|
-
}
|
|
338
|
-
return flags.join(" ");
|
|
257
|
+
logTitle(title);
|
|
258
|
+
logCommand(cmd);
|
|
259
|
+
runCommandSync(cmd, { stdio: "inherit" });
|
|
260
|
+
logTitle(`\nBundle for "${configName}" customer configuration is done.`);
|
|
261
|
+
console.log(`Path: ${paths.appDist}\n`);
|
|
262
|
+
process.on("exit", () => {
|
|
263
|
+
notify({
|
|
264
|
+
title: "build",
|
|
265
|
+
message: `Bundle for "${configName}" customer configuration is done.`
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
};
|
|
269
|
+
const assertOptionsValid$5 = (options) => {
|
|
270
|
+
const { localCore, https, deploy, env, profile } = options;
|
|
271
|
+
const { ifCore } = getIfCoreFns();
|
|
272
|
+
if (ifCore() && localCore) halt("Flag \"--local-core\" is redundant if running in Tamaro Core context.");
|
|
273
|
+
if (localCore && deploy) halt("Flags \"--local-core\" and \"--deploy\" must not be used together.");
|
|
274
|
+
if (https) assertCrtExists();
|
|
275
|
+
if (profile) assertProfileValid(profile);
|
|
276
|
+
assertEnvValid(env);
|
|
277
|
+
};
|
|
278
|
+
const prepareFlags$2 = (options) => {
|
|
279
|
+
const flags = [];
|
|
280
|
+
const { localCore, analyze, https, nolint, debug } = options;
|
|
281
|
+
if (localCore) flags.push("--env localCore");
|
|
282
|
+
if (analyze) flags.push("--env analyze");
|
|
283
|
+
if (https) flags.push("--env https");
|
|
284
|
+
if (nolint) flags.push("--env nolint");
|
|
285
|
+
if (debug) flags.push("--env debug");
|
|
286
|
+
return flags.join(" ");
|
|
339
287
|
};
|
|
340
288
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
289
|
+
//#endregion
|
|
290
|
+
//#region src/commands/deploy.ts
|
|
291
|
+
const deploy = async (options) => {
|
|
292
|
+
const { ifCore } = getIfCoreFns();
|
|
293
|
+
const paths = getPaths(ifCore);
|
|
294
|
+
assertDistPathExists(paths.appDist);
|
|
295
|
+
if (!options.profile && !options.ci) {
|
|
296
|
+
assertProfilesPresent();
|
|
297
|
+
options.profile = await promptProfile();
|
|
298
|
+
}
|
|
299
|
+
assertOptionsValid$4(options);
|
|
300
|
+
await validate();
|
|
301
|
+
awsAuthenticate(options);
|
|
302
|
+
const flags = prepareFlags$3(options);
|
|
303
|
+
const { tag, dryrun } = options;
|
|
304
|
+
const dryRunFlag = dryrun ? `--dryrun` : "";
|
|
305
|
+
const configName = ifCore(CORE_CONFIG_NAME, getWidgetUuid());
|
|
306
|
+
const deployUrl = `s3://${AWS_S3_BUCKET_TAMARO}/${configName}/${tag}`;
|
|
307
|
+
const entryFilename = ifCore("index.js", "widget.js");
|
|
308
|
+
if (dryRunFlag) logTitle("🧪 DRY RUN MODE - No actual changes will be made 🧪");
|
|
309
|
+
/**
|
|
310
|
+
* Sync all files except entrypoint (without deleting old files)
|
|
311
|
+
*/
|
|
312
|
+
const cmdSyncAll = `
|
|
365
313
|
aws s3 sync ${paths.appDist} ${deployUrl}
|
|
366
314
|
--acl public-read
|
|
367
315
|
--exclude ${paths.appDist}/${entryFilename}
|
|
@@ -369,564 +317,330 @@ var deploy = async (options) => {
|
|
|
369
317
|
${flags}
|
|
370
318
|
${dryRunFlag}
|
|
371
319
|
`;
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
320
|
+
logTitle("Deploying to AWS S3 …");
|
|
321
|
+
logCommand(cmdSyncAll);
|
|
322
|
+
try {
|
|
323
|
+
runCommandSync(cmdSyncAll, { stdout: "inherit" });
|
|
324
|
+
} catch (error) {
|
|
325
|
+
halt(error.stderr);
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Copy entrypoint
|
|
329
|
+
*/
|
|
330
|
+
const cmdCpEntry = `
|
|
380
331
|
aws s3 cp ${paths.appDist}/${entryFilename} ${deployUrl}/${entryFilename}
|
|
381
332
|
--acl public-read
|
|
382
333
|
--cache-control max-age=64800
|
|
383
334
|
${flags}
|
|
384
335
|
${dryRunFlag}
|
|
385
336
|
`;
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
337
|
+
logCommand(cmdCpEntry);
|
|
338
|
+
try {
|
|
339
|
+
runCommandSync(cmdCpEntry, { stdout: "inherit" });
|
|
340
|
+
} catch (error) {
|
|
341
|
+
halt(error.stderr);
|
|
342
|
+
}
|
|
343
|
+
if (!dryRunFlag) {
|
|
344
|
+
/**
|
|
345
|
+
* Invalidate cloudfront cache
|
|
346
|
+
*/
|
|
347
|
+
const cmdInvalidateCache = `
|
|
394
348
|
aws cloudfront create-invalidation
|
|
395
349
|
--distribution-id ${AWS_CLOUDFRONT_DISTRIBUTION_ID}
|
|
396
350
|
--paths /${configName}/${tag}/*
|
|
397
351
|
${flags}
|
|
398
352
|
`;
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
message: `
|
|
353
|
+
logTitle("\nInvalidating edge cache …");
|
|
354
|
+
logCommand(cmdInvalidateCache);
|
|
355
|
+
try {
|
|
356
|
+
runCommandSync(cmdInvalidateCache);
|
|
357
|
+
} catch (error) {
|
|
358
|
+
halt(error.stderr);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
const demoPage = `https://${AWS_S3_BUCKET_TAMARO}/${configName}/${tag}/index.html`;
|
|
362
|
+
const entryPoint = `https://${AWS_S3_BUCKET_TAMARO}/${configName}/${tag}/${entryFilename}`;
|
|
363
|
+
logTitle(`\nBundle for "${configName}" is deployed with tag "${tag}".`);
|
|
364
|
+
logDataTable({
|
|
365
|
+
"Demo page:": demoPage,
|
|
366
|
+
"Entry point:": entryPoint
|
|
367
|
+
});
|
|
368
|
+
process.on("exit", () => {
|
|
369
|
+
notify({
|
|
370
|
+
title: "deploy",
|
|
371
|
+
message: `
|
|
419
372
|
Bundle for "${configName}" is deployed with tag "${tag}".
|
|
420
373
|
Demo page: ${demoPage}
|
|
421
374
|
Entry point: ${entryPoint}
|
|
422
375
|
`
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
};
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
var assertDistPathExists = (distPath) => {
|
|
434
|
-
if (!existsSync2(distPath)) {
|
|
435
|
-
halt(
|
|
436
|
-
stripIndent4(`
|
|
376
|
+
});
|
|
377
|
+
});
|
|
378
|
+
};
|
|
379
|
+
const assertOptionsValid$4 = (options) => {
|
|
380
|
+
const { profile, tag } = options;
|
|
381
|
+
if (profile) assertProfileValid(profile);
|
|
382
|
+
assertTagValid(tag);
|
|
383
|
+
};
|
|
384
|
+
const assertDistPathExists = (distPath) => {
|
|
385
|
+
if (!existsSync(distPath)) halt(stripIndent(`
|
|
437
386
|
Dist folder does not exists.
|
|
438
387
|
Make sure you have built the bundle before trying to deploy it.
|
|
439
|
-
`)
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
const regex = /^[a-zA-Z0-9-_.]+$/;
|
|
445
|
-
if (!regex.test(tag)) {
|
|
446
|
-
halt(
|
|
447
|
-
`Flag "--tag" has forbidden format. Allowed format: ${regex.toString()}.`
|
|
448
|
-
);
|
|
449
|
-
}
|
|
388
|
+
`));
|
|
389
|
+
};
|
|
390
|
+
const assertTagValid = (tag) => {
|
|
391
|
+
const regex = /^[a-zA-Z0-9-_.]+$/;
|
|
392
|
+
if (!regex.test(tag)) halt(`Flag "--tag" has forbidden format. Allowed format: ${regex.toString()}.`);
|
|
450
393
|
};
|
|
451
394
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
const configName = getWidgetUuid();
|
|
474
|
-
const deployUrl = `s3://${options.bucket}/${configName}`;
|
|
475
|
-
if (dryRunFlag) {
|
|
476
|
-
logTitle("\u{1F9EA} DRY RUN MODE - No actual changes will be made \u{1F9EA}");
|
|
477
|
-
}
|
|
478
|
-
const cmd = `
|
|
395
|
+
//#endregion
|
|
396
|
+
//#region src/commands/deploy-email-config.ts
|
|
397
|
+
const deployEmailConfig = async (options) => {
|
|
398
|
+
const { ifCore } = getIfCoreFns();
|
|
399
|
+
const emailConfigPath = `${getPaths(ifCore).app}/email-config`;
|
|
400
|
+
assertIsNotCore();
|
|
401
|
+
assertEmailConfigPathExists(emailConfigPath);
|
|
402
|
+
if (!options.profile && !options.ci) {
|
|
403
|
+
assertProfilesPresent();
|
|
404
|
+
options.profile = await promptProfile();
|
|
405
|
+
}
|
|
406
|
+
if (!options.bucket) options.bucket = options.ci ? AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD : await promptBucketTamaroEmailConfig();
|
|
407
|
+
assertOptionsValid$3(options);
|
|
408
|
+
await validate();
|
|
409
|
+
awsAuthenticate(options);
|
|
410
|
+
const flags = prepareFlags$3(options);
|
|
411
|
+
const dryRunFlag = options.dryrun ? `--dryrun` : "";
|
|
412
|
+
const configName = getWidgetUuid();
|
|
413
|
+
const deployUrl = `s3://${options.bucket}/${configName}`;
|
|
414
|
+
if (dryRunFlag) logTitle("🧪 DRY RUN MODE - No actual changes will be made 🧪");
|
|
415
|
+
const cmd = `
|
|
479
416
|
aws s3 sync ${emailConfigPath} ${deployUrl}
|
|
480
417
|
--delete
|
|
481
418
|
--exact-timestamps
|
|
482
419
|
${flags}
|
|
483
420
|
${dryRunFlag}
|
|
484
421
|
`;
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (!buckets.includes(bucket)) {
|
|
531
|
-
halt("Invalid bucket name.");
|
|
532
|
-
}
|
|
533
|
-
};
|
|
534
|
-
var promptBucketTamaroEmailConfig = async () => {
|
|
535
|
-
const buckets = [
|
|
536
|
-
{ title: "stage", value: AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_STAGE },
|
|
537
|
-
{ title: "prod", value: AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD }
|
|
538
|
-
];
|
|
539
|
-
const { bucket } = await prompts2(
|
|
540
|
-
[
|
|
541
|
-
{
|
|
542
|
-
type: "select",
|
|
543
|
-
name: "bucket",
|
|
544
|
-
message: "Select environment",
|
|
545
|
-
choices: buckets
|
|
546
|
-
}
|
|
547
|
-
],
|
|
548
|
-
{
|
|
549
|
-
onCancel: () => halt()
|
|
550
|
-
}
|
|
551
|
-
);
|
|
552
|
-
return bucket;
|
|
422
|
+
logTitle(`Deploying email configuration for "${configName}" customer configuration to AWS S3 …`);
|
|
423
|
+
logCommand(cmd);
|
|
424
|
+
try {
|
|
425
|
+
runCommandSync(cmd, { stdout: "inherit" });
|
|
426
|
+
} catch (error) {
|
|
427
|
+
halt(error.stderr);
|
|
428
|
+
}
|
|
429
|
+
logTitle(`Email configuration for "${configName}" customer configuration is deployed.`);
|
|
430
|
+
logDataTable({ "Deploy URL:": deployUrl });
|
|
431
|
+
process.on("exit", () => {
|
|
432
|
+
notify({
|
|
433
|
+
title: "deploy-email-config",
|
|
434
|
+
message: `Email configuration for "${configName}" customer configuration is deployed.`
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
};
|
|
438
|
+
const assertOptionsValid$3 = (options) => {
|
|
439
|
+
const { profile, bucket } = options;
|
|
440
|
+
if (profile) assertProfileValid(profile);
|
|
441
|
+
if (bucket) assertBucketValid(bucket);
|
|
442
|
+
};
|
|
443
|
+
const assertEmailConfigPathExists = (distPath) => {
|
|
444
|
+
if (!existsSync(distPath)) halt("Email config folder does not exists. Nothing to deploy.");
|
|
445
|
+
};
|
|
446
|
+
const assertIsNotCore = () => {
|
|
447
|
+
const { ifCore } = getIfCoreFns();
|
|
448
|
+
if (ifCore()) halt("You cannot deploy widget email configuration for Tamaro Core.");
|
|
449
|
+
};
|
|
450
|
+
const assertBucketValid = (bucket) => {
|
|
451
|
+
if (![AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_STAGE, AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD].includes(bucket)) halt("Invalid bucket name.");
|
|
452
|
+
};
|
|
453
|
+
const promptBucketTamaroEmailConfig = async () => {
|
|
454
|
+
const { bucket } = await prompts([{
|
|
455
|
+
type: "select",
|
|
456
|
+
name: "bucket",
|
|
457
|
+
message: "Select environment",
|
|
458
|
+
choices: [{
|
|
459
|
+
title: "stage",
|
|
460
|
+
value: AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_STAGE
|
|
461
|
+
}, {
|
|
462
|
+
title: "prod",
|
|
463
|
+
value: AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD
|
|
464
|
+
}]
|
|
465
|
+
}], { onCancel: () => halt() });
|
|
466
|
+
return bucket;
|
|
553
467
|
};
|
|
554
468
|
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
"
|
|
566
|
-
|
|
567
|
-
const wpBin = resolveBin("webpack");
|
|
568
|
-
const wpConfig = resolveOwn("dist/webpack.config.js");
|
|
569
|
-
const cmd = `
|
|
570
|
-
${wpBin} serve
|
|
571
|
-
--config ${wpConfig}
|
|
469
|
+
//#endregion
|
|
470
|
+
//#region src/commands/dev.ts
|
|
471
|
+
const dev = async (options) => {
|
|
472
|
+
const { env } = options;
|
|
473
|
+
applyEnv(env);
|
|
474
|
+
assertOptionsValid$2(options);
|
|
475
|
+
const flags = await prepareFlags$1(options);
|
|
476
|
+
const { ifCore } = getIfCoreFns();
|
|
477
|
+
const title = ifCore("Running dev web-server for Tamaro Core …", "Running dev web-server for customer configuration …");
|
|
478
|
+
const cmd = `
|
|
479
|
+
${resolveBin("webpack")} serve
|
|
480
|
+
--config ${resolveOwn("dist/webpack.config.js")}
|
|
572
481
|
${flags}
|
|
573
482
|
`;
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
};
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
};
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
if (localCore) {
|
|
597
|
-
flags.push("--env localCore");
|
|
598
|
-
}
|
|
599
|
-
flags.push(`--port ${port}`);
|
|
600
|
-
if (https) {
|
|
601
|
-
flags.push("--env https");
|
|
602
|
-
}
|
|
603
|
-
if (nolint) {
|
|
604
|
-
flags.push("--env nolint");
|
|
605
|
-
}
|
|
606
|
-
return flags.join(" ");
|
|
483
|
+
logTitle(title);
|
|
484
|
+
logCommand(cmd);
|
|
485
|
+
runCommandSync(cmd, { stdio: "inherit" });
|
|
486
|
+
};
|
|
487
|
+
const assertOptionsValid$2 = (options) => {
|
|
488
|
+
const { localCore, https, port, env } = options;
|
|
489
|
+
const { ifCore } = getIfCoreFns();
|
|
490
|
+
if (ifCore() && localCore) halt("Flag \"--local-core\" is redundant if running in Tamaro Core context.");
|
|
491
|
+
if (isNaN(Number(port))) halt("Flag \"--port\" should be a number.");
|
|
492
|
+
if (https) assertCrtExists();
|
|
493
|
+
assertEnvValid(env);
|
|
494
|
+
};
|
|
495
|
+
const prepareFlags$1 = async (options) => {
|
|
496
|
+
const flags = [];
|
|
497
|
+
const { localCore, port: defaultPort, https, nolint, debug } = options;
|
|
498
|
+
const port = await getPortPromise({ port: Number(defaultPort) });
|
|
499
|
+
if (localCore) flags.push("--env localCore");
|
|
500
|
+
flags.push(`--port ${port}`);
|
|
501
|
+
if (https) flags.push("--env https");
|
|
502
|
+
if (nolint) flags.push("--env nolint");
|
|
503
|
+
if (debug) flags.push("--env debug");
|
|
504
|
+
return flags.join(" ");
|
|
607
505
|
};
|
|
608
506
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
}
|
|
655
|
-
};
|
|
656
|
-
var assertConfigValid = (config) => {
|
|
657
|
-
if (!config) {
|
|
658
|
-
return;
|
|
659
|
-
}
|
|
660
|
-
const regex = /^[a-zA-Z0-9-_]+$/;
|
|
661
|
-
if (!regex.test(config)) {
|
|
662
|
-
halt(
|
|
663
|
-
`Flag "--config" has forbidden format. Allowed format: ${regex.toString()}.`
|
|
664
|
-
);
|
|
665
|
-
}
|
|
666
|
-
};
|
|
667
|
-
var parseTags = (lines) => {
|
|
668
|
-
const regex = /^\s*PRE\s*/;
|
|
669
|
-
return lines.filter((line) => regex.test(line)).map((line) => line.replace(regex, "").replace(/\/$/, ""));
|
|
507
|
+
//#endregion
|
|
508
|
+
//#region src/commands/list-deployed.ts
|
|
509
|
+
const listDeployed = async (options) => {
|
|
510
|
+
if (!options.profile && !options.ci) {
|
|
511
|
+
assertProfilesPresent();
|
|
512
|
+
options.profile = await promptProfile();
|
|
513
|
+
}
|
|
514
|
+
assertOptionsValid$1(options);
|
|
515
|
+
awsAuthenticate(options);
|
|
516
|
+
const flags = prepareFlags$3(options);
|
|
517
|
+
const { config } = options;
|
|
518
|
+
const { ifCore } = getIfCoreFns();
|
|
519
|
+
const configName = config ?? ifCore(CORE_CONFIG_NAME, getWidgetUuid());
|
|
520
|
+
const title = !config && ifCore() ? `Listing deployments of Tamaro Core …` : `Listing deployments of "${configName}" customer configuration …`;
|
|
521
|
+
const cmd = `aws s3 ls ${`s3://${AWS_S3_BUCKET_TAMARO}/${configName}/`} ${flags}`;
|
|
522
|
+
let out = "";
|
|
523
|
+
logTitle(title);
|
|
524
|
+
logCommand(cmd);
|
|
525
|
+
try {
|
|
526
|
+
out = runCommandSync(cmd).stdout;
|
|
527
|
+
} catch (error) {
|
|
528
|
+
out = error.stdout;
|
|
529
|
+
if (error.stderr) halt(error.stderr);
|
|
530
|
+
}
|
|
531
|
+
const tags = parseTags(out.split("\n"));
|
|
532
|
+
let text = "";
|
|
533
|
+
if (tags.length === 0) text = "No deployments found.";
|
|
534
|
+
else text = tags.map((tag, idx) => {
|
|
535
|
+
return `${idx + 1}. https://${AWS_S3_BUCKET_TAMARO}/${configName}/${tag}/index.html`;
|
|
536
|
+
}).join("\n");
|
|
537
|
+
console.log(`${text}\n`);
|
|
538
|
+
};
|
|
539
|
+
const assertOptionsValid$1 = (options) => {
|
|
540
|
+
const { config, profile } = options;
|
|
541
|
+
assertConfigValid(config);
|
|
542
|
+
if (profile) assertProfileValid(profile);
|
|
543
|
+
};
|
|
544
|
+
const assertConfigValid = (config) => {
|
|
545
|
+
if (!config) return;
|
|
546
|
+
const regex = /^[a-zA-Z0-9-_]+$/;
|
|
547
|
+
if (!regex.test(config)) halt(`Flag "--config" has forbidden format. Allowed format: ${regex.toString()}.`);
|
|
548
|
+
};
|
|
549
|
+
const parseTags = (lines) => {
|
|
550
|
+
const regex = /^\s*PRE\s*/;
|
|
551
|
+
return lines.filter((line) => regex.test(line)).map((line) => line.replace(regex, "").replace(/\/$/, ""));
|
|
670
552
|
};
|
|
671
553
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
const cmd = `
|
|
681
|
-
npx -y serve ${paths.appDist}
|
|
554
|
+
//#endregion
|
|
555
|
+
//#region src/commands/serve.ts
|
|
556
|
+
const serve = async (options) => {
|
|
557
|
+
assertOptionsValid(options);
|
|
558
|
+
const flags = await prepareFlags(options);
|
|
559
|
+
const { ifCore } = getIfCoreFns();
|
|
560
|
+
const cmd = `
|
|
561
|
+
npx -y serve ${getPaths(ifCore).appDist}
|
|
682
562
|
--cors
|
|
683
563
|
${flags}
|
|
684
564
|
`;
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
};
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
};
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
flags.push(`--ssl-cert ${certFile}`);
|
|
709
|
-
flags.push(`--ssl-key ${keyFile}`);
|
|
710
|
-
}
|
|
711
|
-
return flags.join(" ");
|
|
565
|
+
logTitle(`Running web-server for pre-built bundle …`);
|
|
566
|
+
logCommand(cmd);
|
|
567
|
+
runCommandSync(cmd, { stdio: "inherit" });
|
|
568
|
+
};
|
|
569
|
+
const assertOptionsValid = (options) => {
|
|
570
|
+
const { port, https } = options;
|
|
571
|
+
if (isNaN(Number(port))) halt("Flag \"--port\" should be a number.");
|
|
572
|
+
if (https) assertCrtExists();
|
|
573
|
+
};
|
|
574
|
+
const prepareFlags = async (options) => {
|
|
575
|
+
const flags = [];
|
|
576
|
+
const { port: defaultPort, https } = options;
|
|
577
|
+
const port = await getPortPromise({ port: Number(defaultPort) });
|
|
578
|
+
flags.push(`-p ${port}`);
|
|
579
|
+
if (https) {
|
|
580
|
+
const { ifCore } = getIfCoreFns();
|
|
581
|
+
const paths = getPaths(ifCore);
|
|
582
|
+
const certFile = resolve(paths.root, HTTPS_CRT_FILE);
|
|
583
|
+
const keyFile = resolve(paths.root, HTTPS_KEY_FILE);
|
|
584
|
+
flags.push(`--ssl-cert ${certFile}`);
|
|
585
|
+
flags.push(`--ssl-key ${keyFile}`);
|
|
586
|
+
}
|
|
587
|
+
return flags.join(" ");
|
|
712
588
|
};
|
|
713
589
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
author: {
|
|
719
|
-
name: "RaiseNow",
|
|
720
|
-
email: "development@raisenow.com"
|
|
721
|
-
},
|
|
722
|
-
type: "module",
|
|
723
|
-
bin: "dist/cli.js",
|
|
724
|
-
packageManager: "pnpm@10.17.1",
|
|
725
|
-
engines: {
|
|
726
|
-
node: ">=22",
|
|
727
|
-
pnpm: ">=10",
|
|
728
|
-
npm: "please-use-pnpm",
|
|
729
|
-
yarn: "please-use-pnpm"
|
|
730
|
-
},
|
|
731
|
-
scripts: {
|
|
732
|
-
prepare: "pnpm build",
|
|
733
|
-
typecheck: "tsc --noEmit",
|
|
734
|
-
build: "tsup src/cli.ts src/webpack.config.ts --clean --shims --format esm",
|
|
735
|
-
"build:watch": "pnpm build --watch --ignore-watch .history --ignore-watch .idea",
|
|
736
|
-
readme: "pnpx http-server . --cors -o /readme.html",
|
|
737
|
-
lint: "DEBUG=eslint:cli-engine eslint .",
|
|
738
|
-
"lint:fix": "DEBUG=eslint:cli-engine eslint --fix .",
|
|
739
|
-
format: "prettier --write .",
|
|
740
|
-
test: "vitest",
|
|
741
|
-
"test:watch": "vitest --watch",
|
|
742
|
-
"test:coverage": "vitest --coverage"
|
|
743
|
-
},
|
|
744
|
-
dependencies: {
|
|
745
|
-
"@babel/cli": "^7.28.3",
|
|
746
|
-
"@babel/core": "^7.28.4",
|
|
747
|
-
"@babel/plugin-proposal-decorators": "^7.28.0",
|
|
748
|
-
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
749
|
-
"@babel/plugin-transform-runtime": "^7.28.3",
|
|
750
|
-
"@babel/preset-env": "^7.28.3",
|
|
751
|
-
"@babel/preset-react": "^7.27.1",
|
|
752
|
-
"@babel/preset-typescript": "^7.27.1",
|
|
753
|
-
"@babel/runtime-corejs3": "^7.28.4",
|
|
754
|
-
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.1",
|
|
755
|
-
"@statoscope/webpack-plugin": "^5.29.0",
|
|
756
|
-
"@types/columnify": "^1.5.4",
|
|
757
|
-
"@types/handlebars-helpers": "^0.5.6",
|
|
758
|
-
"@types/lodash": "^4.17.20",
|
|
759
|
-
"@types/node": "^22.18.6",
|
|
760
|
-
"@types/node-notifier": "^8.0.5",
|
|
761
|
-
"@types/prompts": "^2.4.9",
|
|
762
|
-
"@types/resolve-bin": "^0.4.3",
|
|
763
|
-
"@types/webpack-config-utils": "^2.3.4",
|
|
764
|
-
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
765
|
-
"@typescript-eslint/parser": "^7.18.0",
|
|
766
|
-
autoprefixer: "^10.4.21",
|
|
767
|
-
"babel-loader": "^10.0.0",
|
|
768
|
-
"babel-plugin-istanbul": "^7.0.1",
|
|
769
|
-
"babel-plugin-lodash": "^3.3.4",
|
|
770
|
-
chalk: "^5.6.2",
|
|
771
|
-
"clean-webpack-plugin": "^4.0.0",
|
|
772
|
-
columnify: "^1.6.0",
|
|
773
|
-
commander: "^14.0.1",
|
|
774
|
-
"copy-webpack-plugin": "^13.0.1",
|
|
775
|
-
"core-js": "^3.45.1",
|
|
776
|
-
"css-loader": "^7.1.2",
|
|
777
|
-
"css-minimizer-webpack-plugin": "^7.0.2",
|
|
778
|
-
dotenv: "^17.2.2",
|
|
779
|
-
"escape-string-regexp": "^5.0.0",
|
|
780
|
-
eslint: "^8.57.1",
|
|
781
|
-
"eslint-config-prettier": "^10.1.8",
|
|
782
|
-
"eslint-import-resolver-typescript": "^3.6.3",
|
|
783
|
-
"eslint-plugin-deprecation": "^3.0.0",
|
|
784
|
-
"eslint-plugin-import": "^2.32.0",
|
|
785
|
-
"eslint-plugin-markdownlint": "^0.9.0",
|
|
786
|
-
"eslint-plugin-promise": "^7.2.1",
|
|
787
|
-
"eslint-plugin-unused-imports": "^3.2.0",
|
|
788
|
-
"eslint-plugin-yml": "^1.18.0",
|
|
789
|
-
"eslint-webpack-plugin": "^5.0.2",
|
|
790
|
-
execa: "^9.6.0",
|
|
791
|
-
"file-loader": "^6.2.0",
|
|
792
|
-
"fork-ts-checker-webpack-plugin": "^9.1.0",
|
|
793
|
-
glob: "^11.0.3",
|
|
794
|
-
handlebars: "^4.7.8",
|
|
795
|
-
"handlebars-helpers": "^0.10.0",
|
|
796
|
-
"html-loader": "^5.1.0",
|
|
797
|
-
"html-webpack-plugin": "^5.6.4",
|
|
798
|
-
"json-loader": "^0.5.7",
|
|
799
|
-
lodash: "^4.17.21",
|
|
800
|
-
"mini-css-extract-plugin": "^2.9.4",
|
|
801
|
-
"node-notifier": "^10.0.1",
|
|
802
|
-
portfinder: "^1.0.38",
|
|
803
|
-
postcss: "^8.5.6",
|
|
804
|
-
"postcss-custom-properties": "^14.0.6",
|
|
805
|
-
"postcss-import": "^16.1.1",
|
|
806
|
-
"postcss-loader": "^8.2.0",
|
|
807
|
-
"postcss-nested": "^7.0.2",
|
|
808
|
-
prettier: "^3.6.2",
|
|
809
|
-
prompts: "^2.4.2",
|
|
810
|
-
"react-refresh": "^0.17.0",
|
|
811
|
-
"resolve-url-loader": "^5.0.0",
|
|
812
|
-
sass: "^1.93.1",
|
|
813
|
-
"sass-loader": "^16.0.5",
|
|
814
|
-
"strip-indent": "^4.1.0",
|
|
815
|
-
"style-loader": "^4.0.0",
|
|
816
|
-
"terser-webpack-plugin": "^5.3.14",
|
|
817
|
-
"tsconfig-paths-webpack-plugin": "^4.2.0",
|
|
818
|
-
tsup: "^8.5.0",
|
|
819
|
-
typescript: "^5.9.2",
|
|
820
|
-
"url-loader": "^4.1.1",
|
|
821
|
-
vitest: "^3.2.4",
|
|
822
|
-
webpack: "^5.101.3",
|
|
823
|
-
"webpack-cli": "^6.0.1",
|
|
824
|
-
"webpack-config-utils": "^2.3.1",
|
|
825
|
-
"webpack-dev-server": "^5.2.2",
|
|
826
|
-
"yaml-loader": "^0.8.1"
|
|
827
|
-
}
|
|
828
|
-
};
|
|
590
|
+
//#endregion
|
|
591
|
+
//#region package.json
|
|
592
|
+
var name = "@raisenow/tamaro-cli";
|
|
593
|
+
var version = "1.6.0-dev.1";
|
|
829
594
|
|
|
830
|
-
|
|
595
|
+
//#endregion
|
|
596
|
+
//#region src/cli.ts
|
|
597
|
+
/**
|
|
598
|
+
* Makes the script crash on unhandled rejections instead of silently
|
|
599
|
+
* ignoring them. In the future, promise rejections that are not handled will
|
|
600
|
+
* terminate the Node.js process with a non-zero exit code.
|
|
601
|
+
*/
|
|
831
602
|
process.on("unhandledRejection", (error) => {
|
|
832
|
-
|
|
603
|
+
throw error;
|
|
833
604
|
});
|
|
834
605
|
process.on("SIGINT", () => {
|
|
835
|
-
|
|
606
|
+
halt();
|
|
836
607
|
});
|
|
837
|
-
|
|
838
|
-
cli.command("dev").description(
|
|
839
|
-
|
|
840
|
-
).option(
|
|
841
|
-
"--local-core",
|
|
842
|
-
"Load Tamaro Core from localhost:1234 instead of the CDN",
|
|
843
|
-
false
|
|
844
|
-
).option(
|
|
845
|
-
"--https",
|
|
846
|
-
"Let local web server serve Tamaro with SSL encryption",
|
|
847
|
-
false
|
|
848
|
-
).option("--port <port>", "Web server port", `${DEFAULT_PORT}`).option("--env <env>", "Environment (dev, stage, prod)").option("--nolint", "Disable ESLint", false).action(async (options) => {
|
|
849
|
-
await dev(options);
|
|
608
|
+
const cli = createCommand().name(name).version(version, "-v, --version");
|
|
609
|
+
cli.command("dev").description("Run the local development server for Tamaro Core or a particular customer configuration").option("--local-core", "Load Tamaro Core from localhost:1234 instead of the CDN", false).option("--https", "Let local web server serve Tamaro with SSL encryption", false).option("--port <port>", "Web server port", `${DEFAULT_PORT}`).option("--env <env>", "Environment (dev, stage, prod)").option("--nolint", "Disable ESLint", false).option("--debug", "Enable debug mode", false).action(async (options) => {
|
|
610
|
+
await dev(options);
|
|
850
611
|
});
|
|
851
|
-
cli.command("build").description(
|
|
852
|
-
|
|
853
|
-
)
|
|
854
|
-
|
|
855
|
-
"Load Tamaro Core from localhost:1234 instead of the CDN",
|
|
856
|
-
false
|
|
857
|
-
).option("--analyze", 'Generate bundle statistics to "reports" folder', false).option("--serve", "Run the generated bundle with a local web server", false).option(
|
|
858
|
-
"--https",
|
|
859
|
-
"Let local web server serve Tamaro with SSL encryption",
|
|
860
|
-
false
|
|
861
|
-
).option("--port <port>", "Web server port", `${DEFAULT_PORT}`).option("--env <env>", "Environment (dev, stage, prod)").option("--profile <profile>", "AWS profile").option("--ci", "CI environment", false).option(
|
|
862
|
-
"--deploy",
|
|
863
|
-
"Deploy Tamaro Core or a customer configuration bundle to AWS S3",
|
|
864
|
-
false
|
|
865
|
-
).option(
|
|
866
|
-
"--tag <tag>",
|
|
867
|
-
"Tag which should be used for the deployment of the bundle",
|
|
868
|
-
DEFAULT_TAG
|
|
869
|
-
).option("--nolint", "Disable ESLint", false).action(async (options) => {
|
|
870
|
-
await build(options);
|
|
871
|
-
if (options.serve) {
|
|
872
|
-
await serve(options);
|
|
873
|
-
}
|
|
874
|
-
if (options.deploy) {
|
|
875
|
-
await deploy(options);
|
|
876
|
-
}
|
|
612
|
+
cli.command("build").description("Build an optimised (minified) bundle of Tamaro Core or a customer configuration").option("--local-core", "Load Tamaro Core from localhost:1234 instead of the CDN", false).option("--analyze", "Generate bundle statistics to \"reports\" folder", false).option("--serve", "Run the generated bundle with a local web server", false).option("--https", "Let local web server serve Tamaro with SSL encryption", false).option("--port <port>", "Web server port", `${DEFAULT_PORT}`).option("--env <env>", "Environment (dev, stage, prod)").option("--profile <profile>", "AWS profile").option("--ci", "CI environment", false).option("--deploy", "Deploy Tamaro Core or a customer configuration bundle to AWS S3", false).option("--tag <tag>", "Tag which should be used for the deployment of the bundle", DEFAULT_TAG).option("--nolint", "Disable ESLint", false).option("--debug", "Enable debug mode", false).action(async (options) => {
|
|
613
|
+
await build(options);
|
|
614
|
+
if (options.serve) await serve(options);
|
|
615
|
+
if (options.deploy) await deploy(options);
|
|
877
616
|
});
|
|
878
|
-
cli.command("serve").description("Run a local web server for pre-built bundle").option("--port <port>", "Web server port", `${DEFAULT_PORT}`).option(
|
|
879
|
-
|
|
880
|
-
"Let local web server serve Tamaro with SSL encryption",
|
|
881
|
-
false
|
|
882
|
-
).action(async (options) => {
|
|
883
|
-
await serve(options);
|
|
617
|
+
cli.command("serve").description("Run a local web server for pre-built bundle").option("--port <port>", "Web server port", `${DEFAULT_PORT}`).option("--https", "Let local web server serve Tamaro with SSL encryption", false).action(async (options) => {
|
|
618
|
+
await serve(options);
|
|
884
619
|
});
|
|
885
|
-
cli.command("deploy").description(
|
|
886
|
-
|
|
887
|
-
).option("--profile <profile>", "AWS profile").option("--ci", "CI environment", false).option(
|
|
888
|
-
"--tag <tag>",
|
|
889
|
-
"Tag which should be used for the deployment of the bundle",
|
|
890
|
-
DEFAULT_TAG
|
|
891
|
-
).option(
|
|
892
|
-
"--dryrun",
|
|
893
|
-
"Displays the operations that would be performed without actually running them",
|
|
894
|
-
false
|
|
895
|
-
).action(async (options) => {
|
|
896
|
-
await deploy(options);
|
|
620
|
+
cli.command("deploy").description("Deploy a pre-built Tamaro Core or customer configuration bundle to AWS S3").option("--profile <profile>", "AWS profile").option("--ci", "CI environment", false).option("--tag <tag>", "Tag which should be used for the deployment of the bundle", DEFAULT_TAG).option("--dryrun", "Displays the operations that would be performed without actually running them", false).action(async (options) => {
|
|
621
|
+
await deploy(options);
|
|
897
622
|
});
|
|
898
|
-
cli.command("list-deployed").description(
|
|
899
|
-
|
|
900
|
-
).option("--profile <profile>", "AWS profile").option("--ci", "CI environment", false).option(
|
|
901
|
-
"--config <config>",
|
|
902
|
-
"Configuration name (default: current customer configuration)"
|
|
903
|
-
).action(async (options) => {
|
|
904
|
-
await listDeployed(options);
|
|
623
|
+
cli.command("list-deployed").description("List deployments of Tamaro Core or a particular customer configuration").option("--profile <profile>", "AWS profile").option("--ci", "CI environment", false).option("--config <config>", "Configuration name (default: current customer configuration)").action(async (options) => {
|
|
624
|
+
await listDeployed(options);
|
|
905
625
|
});
|
|
906
|
-
cli.command("deploy-email-config").description("Deploy a widget's email configuration to AWS S3").option("--profile <profile>", "AWS profile").option("--ci", "CI environment", false).option("--bucket <bucket>", "AWS bucket for email configs").option(
|
|
907
|
-
|
|
908
|
-
"Displays the operations that would be performed without actually running them",
|
|
909
|
-
false
|
|
910
|
-
).action(async (options) => {
|
|
911
|
-
await deployEmailConfig(options);
|
|
626
|
+
cli.command("deploy-email-config").description("Deploy a widget's email configuration to AWS S3").option("--profile <profile>", "AWS profile").option("--ci", "CI environment", false).option("--bucket <bucket>", "AWS bucket for email configs").option("--dryrun", "Displays the operations that would be performed without actually running them", false).action(async (options) => {
|
|
627
|
+
await deployEmailConfig(options);
|
|
912
628
|
});
|
|
913
|
-
cli.command("validate").description(
|
|
914
|
-
|
|
915
|
-
).action(async () => {
|
|
916
|
-
await validate();
|
|
629
|
+
cli.command("validate").description("Validate the current Tamaro configuration to avoid common errors").action(async () => {
|
|
630
|
+
await validate();
|
|
917
631
|
});
|
|
918
632
|
(async () => {
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
logError(error.stack);
|
|
930
|
-
}
|
|
931
|
-
}
|
|
633
|
+
try {
|
|
634
|
+
logTitle(`${name} ${version}\n`);
|
|
635
|
+
await cli.parseAsync(process.argv);
|
|
636
|
+
} catch (error) {
|
|
637
|
+
if (error.signal === "SIGINT" && error.signalDescription) logError(`\n${error.signalDescription}`);
|
|
638
|
+
else {
|
|
639
|
+
console.log("");
|
|
640
|
+
logError(error.stack);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
932
643
|
})();
|
|
644
|
+
|
|
645
|
+
//#endregion
|
|
646
|
+
export { };
|