@raisenow/tamaro-cli 1.0.8 → 1.0.11
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/.eslintignore +1 -0
- package/{.eslintrc.js → .eslintrc.cjs} +2 -14
- package/.gitignore +4 -5
- package/.nvmrc +1 -1
- package/.prettierignore +1 -0
- package/{.prettierrc.js → .prettierrc.cjs} +0 -0
- package/README.md +229 -0
- package/dist/chunk-PIEFLCDU.js +144 -0
- package/dist/cli.js +486 -194
- package/dist/webpack.config.js +119 -227
- package/package.json +38 -47
- package/readme.html +1 -1
- package/src/cli.ts +109 -21
- package/src/commands/build.ts +99 -0
- package/src/commands/deploy-email-config.ts +115 -0
- package/src/commands/deploy.ts +163 -0
- package/src/commands/dev.ts +68 -0
- package/src/commands/list-deployed.ts +112 -0
- package/src/commands/serve.ts +53 -0
- package/src/lib/InterpolateHtmlPlugin.ts +10 -8
- package/src/lib/aws.ts +127 -0
- package/src/lib/command.ts +27 -0
- package/src/lib/constants.ts +7 -0
- package/src/lib/env.ts +102 -0
- package/src/lib/logging.ts +32 -0
- package/src/lib/notifier.ts +22 -0
- package/src/lib/resolve.ts +144 -0
- package/src/webpack.config.ts +36 -28
- package/tsconfig.json +1 -1
- package/readme.md +0 -201
- package/src/assets/rnw-logo.png +0 -0
- package/src/commands/build/index.ts +0 -42
- package/src/commands/deploy/index.ts +0 -24
- package/src/commands/dev/index.ts +0 -32
- package/src/commands/serve/index.ts +0 -12
- package/src/lib/helpers.ts +0 -279
- package/src/lib/polyfills.js +0 -8
package/dist/cli.js
CHANGED
|
@@ -1,42 +1,34 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return target;
|
|
16
|
-
};
|
|
17
|
-
var __toESM = (module2, isNodeMode) => {
|
|
18
|
-
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", !isNodeMode && module2 && module2.__esModule ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
|
|
19
|
-
};
|
|
2
|
+
import {
|
|
3
|
+
getIfCoreFns,
|
|
4
|
+
getPaths,
|
|
5
|
+
getWidgetUuid,
|
|
6
|
+
logCommand,
|
|
7
|
+
logDataTable,
|
|
8
|
+
logError,
|
|
9
|
+
logTitle,
|
|
10
|
+
resolveBin,
|
|
11
|
+
resolveOwn
|
|
12
|
+
} from "./chunk-PIEFLCDU.js";
|
|
20
13
|
|
|
21
14
|
// src/cli.ts
|
|
22
|
-
|
|
15
|
+
import { createCommand } from "commander";
|
|
23
16
|
|
|
24
17
|
// package.json
|
|
25
18
|
var name = "@raisenow/tamaro-cli";
|
|
26
|
-
var version = "1.0.
|
|
19
|
+
var version = "1.0.11";
|
|
27
20
|
var author = {
|
|
28
21
|
name: "RaiseNow",
|
|
29
22
|
email: "development@raisenow.com"
|
|
30
23
|
};
|
|
31
|
-
var
|
|
24
|
+
var type = "module";
|
|
32
25
|
var scripts = {
|
|
33
26
|
prepare: "npm run build",
|
|
34
27
|
start: "npm run dev",
|
|
35
|
-
|
|
36
|
-
build: "
|
|
28
|
+
build: "tsup src/cli.ts src/webpack.config.ts --clean --format esm",
|
|
29
|
+
"build:watch": "npm run build -- --watch --ignore-watch .idea",
|
|
37
30
|
docs: "npx -y http-server . --cors -o /readme.html",
|
|
38
|
-
lint: "eslint ."
|
|
39
|
-
"lint:fix": "eslint . --fix"
|
|
31
|
+
lint: "eslint . --fix && prettier --write ."
|
|
40
32
|
};
|
|
41
33
|
var bin = "dist/cli.js";
|
|
42
34
|
var engines = {
|
|
@@ -44,241 +36,525 @@ var engines = {
|
|
|
44
36
|
npm: ">=8"
|
|
45
37
|
};
|
|
46
38
|
var dependencies = {
|
|
47
|
-
"@babel/cli": "^7.
|
|
48
|
-
"@babel/core": "^7.
|
|
49
|
-
"@babel/plugin-proposal-decorators": "^7.
|
|
39
|
+
"@babel/cli": "^7.17.3",
|
|
40
|
+
"@babel/core": "^7.17.5",
|
|
41
|
+
"@babel/plugin-proposal-decorators": "^7.17.2",
|
|
50
42
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
51
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
43
|
+
"@babel/plugin-transform-runtime": "^7.17.0",
|
|
52
44
|
"@babel/preset-env": "^7.16.11",
|
|
53
45
|
"@babel/preset-react": "^7.16.7",
|
|
54
46
|
"@babel/preset-typescript": "^7.16.7",
|
|
55
|
-
"@babel/runtime-corejs3": "^7.
|
|
47
|
+
"@babel/runtime-corejs3": "^7.17.2",
|
|
56
48
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.4",
|
|
57
|
-
"@statoscope/webpack-plugin": "^5.20.
|
|
58
|
-
"@svgr/webpack": "^6.2.
|
|
49
|
+
"@statoscope/webpack-plugin": "^5.20.1",
|
|
50
|
+
"@svgr/webpack": "^6.2.1",
|
|
59
51
|
"@types/columnify": "^1.5.1",
|
|
60
52
|
"@types/lodash": "^4.14.178",
|
|
61
|
-
"@types/
|
|
62
|
-
"@types/node": "^17.0.12",
|
|
53
|
+
"@types/node": "^17.0.21",
|
|
63
54
|
"@types/node-notifier": "^8.0.2",
|
|
64
55
|
"@types/resolve-bin": "^0.4.1",
|
|
65
56
|
"@types/webpack-config-utils": "^2.3.1",
|
|
66
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
67
|
-
"@typescript-eslint/parser": "^5.
|
|
57
|
+
"@typescript-eslint/eslint-plugin": "^5.12.0",
|
|
58
|
+
"@typescript-eslint/parser": "^5.12.0",
|
|
68
59
|
autoprefixer: "^10.4.2",
|
|
69
60
|
"babel-loader": "^8.2.3",
|
|
70
61
|
"babel-plugin-lodash": "^3.3.4",
|
|
71
|
-
|
|
72
|
-
chalk: "^4.1.2",
|
|
62
|
+
chalk: "^5.0.0",
|
|
73
63
|
"clean-webpack-plugin": "^4.0.0",
|
|
74
|
-
columnify: "^1.
|
|
75
|
-
commander: "^
|
|
76
|
-
"copy-webpack-plugin": "^10.2.
|
|
77
|
-
"core-js": "^3.
|
|
78
|
-
"css-loader": "^6.
|
|
64
|
+
columnify: "^1.6.0",
|
|
65
|
+
commander: "^9.0.0",
|
|
66
|
+
"copy-webpack-plugin": "^10.2.4",
|
|
67
|
+
"core-js": "^3.21.1",
|
|
68
|
+
"css-loader": "^6.6.0",
|
|
79
69
|
"css-minimizer-webpack-plugin": "^3.4.1",
|
|
80
|
-
|
|
81
|
-
dotenv: "^
|
|
82
|
-
"
|
|
83
|
-
|
|
84
|
-
"
|
|
85
|
-
eslint: "^8.7.0",
|
|
86
|
-
"eslint-config-prettier": "^8.3.0",
|
|
70
|
+
dotenv: "^16.0.0",
|
|
71
|
+
"dotenv-expand": "^8.0.1",
|
|
72
|
+
"escape-string-regexp": "^5.0.0",
|
|
73
|
+
eslint: "^8.9.0",
|
|
74
|
+
"eslint-config-prettier": "^8.4.0",
|
|
87
75
|
"eslint-plugin-node": "^11.1.0",
|
|
88
|
-
"eslint-plugin-prettier": "^4.0.0",
|
|
89
76
|
"eslint-plugin-promise": "^6.0.0",
|
|
90
|
-
"eslint-webpack-plugin": "^3.1.
|
|
91
|
-
execa: "^
|
|
77
|
+
"eslint-webpack-plugin": "^3.1.1",
|
|
78
|
+
execa: "^6.1.0",
|
|
92
79
|
"file-loader": "^6.2.0",
|
|
93
|
-
"fork-ts-checker-webpack-plugin": "^
|
|
80
|
+
"fork-ts-checker-webpack-plugin": "^7.2.1",
|
|
94
81
|
glob: "^7.2.0",
|
|
95
82
|
"html-loader": "^3.1.0",
|
|
96
83
|
"html-webpack-plugin": "^5.5.0",
|
|
97
84
|
"json-loader": "^0.5.7",
|
|
98
85
|
lodash: "^4.17.21",
|
|
99
86
|
"mini-css-extract-plugin": "^2.5.3",
|
|
100
|
-
"node-notifier": "^10.0.
|
|
87
|
+
"node-notifier": "^10.0.1",
|
|
101
88
|
portfinder: "^1.0.28",
|
|
102
|
-
postcss: "^8.4.
|
|
103
|
-
"postcss-custom-properties": "^12.1.
|
|
89
|
+
postcss: "^8.4.6",
|
|
90
|
+
"postcss-custom-properties": "^12.1.4",
|
|
104
91
|
"postcss-loader": "^6.2.1",
|
|
105
92
|
prettier: "^2.5.1",
|
|
106
93
|
"react-refresh": "^0.11.0",
|
|
107
|
-
"resolve-bin": "^1.0.0",
|
|
108
94
|
"resolve-url-loader": "^5.0.0",
|
|
109
|
-
sass: "^1.49.
|
|
110
|
-
"sass-loader": "^12.
|
|
95
|
+
sass: "^1.49.8",
|
|
96
|
+
"sass-loader": "^12.6.0",
|
|
111
97
|
"source-map-loader": "^3.0.1",
|
|
112
|
-
"strip-indent": "^
|
|
98
|
+
"strip-indent": "^4.0.0",
|
|
113
99
|
"style-loader": "^3.3.1",
|
|
114
|
-
tailwindcss: "^0.7.4",
|
|
115
100
|
"tsconfig-paths-webpack-plugin": "^3.5.2",
|
|
116
|
-
tsup: "^5.11.
|
|
101
|
+
tsup: "^5.11.13",
|
|
117
102
|
typescript: "^4.5.5",
|
|
118
|
-
unfetch: "^4.2.0",
|
|
119
103
|
"url-loader": "^4.1.1",
|
|
120
|
-
webpack: "^5.
|
|
104
|
+
webpack: "^5.69.1",
|
|
121
105
|
"webpack-cli": "^4.9.2",
|
|
122
106
|
"webpack-config-utils": "^2.3.1",
|
|
123
|
-
"webpack-dev-server": "^4.7.
|
|
107
|
+
"webpack-dev-server": "^4.7.4",
|
|
124
108
|
"yaml-loader": "^0.6.0"
|
|
125
109
|
};
|
|
126
110
|
var package_default = {
|
|
127
111
|
name,
|
|
128
112
|
version,
|
|
129
113
|
author,
|
|
130
|
-
|
|
114
|
+
type,
|
|
131
115
|
scripts,
|
|
132
116
|
bin,
|
|
133
117
|
engines,
|
|
134
118
|
dependencies
|
|
135
119
|
};
|
|
136
120
|
|
|
137
|
-
// src/
|
|
138
|
-
var
|
|
121
|
+
// src/lib/constants.ts
|
|
122
|
+
var DEFAULT_TAG = "latest";
|
|
123
|
+
var DEFAULT_PORT = 1234;
|
|
124
|
+
var DEFAULT_AWS_PROFILE = "payments-prod-cs-deployer";
|
|
125
|
+
var DEFAULT_AWS_S3_EMAIL_CONFIG_BUCKET = "rnw-email-service";
|
|
126
|
+
var AWS_S3_BUCKET = "tamaro.raisenow.com";
|
|
127
|
+
var CORE_CONFIG_NAME = "tamaro-core";
|
|
128
|
+
var AWS_CLOUDFRONT_DISTRIBUTION_ID = "EHJ1OM458YQ0I";
|
|
139
129
|
|
|
140
|
-
// src/
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
var
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
var
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
var
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
130
|
+
// src/commands/dev.ts
|
|
131
|
+
import { getPortPromise } from "portfinder";
|
|
132
|
+
|
|
133
|
+
// src/lib/command.ts
|
|
134
|
+
import { execaCommandSync } from "execa";
|
|
135
|
+
var fail = (message) => {
|
|
136
|
+
logError(message);
|
|
137
|
+
process.exit(1);
|
|
138
|
+
};
|
|
139
|
+
var prepareCommand = (cmd) => {
|
|
140
|
+
return cmd.replace(/\n/gm, " ").replace(/[ \t]{2,}/gm, " ").trim();
|
|
141
|
+
};
|
|
142
|
+
var runCommandSync = (cmd, options) => {
|
|
143
|
+
return execaCommandSync(prepareCommand(cmd), options);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// src/commands/dev.ts
|
|
147
|
+
var dev = async (options) => {
|
|
148
|
+
assertOptionsValid(options);
|
|
149
|
+
const flags = (await prepareFlags([], options)).join(" ");
|
|
150
|
+
const { ifCore } = getIfCoreFns();
|
|
151
|
+
const title = ifCore("Running dev web-server for Tamaro Core \u2026", "Running dev web-server for customer configuration \u2026");
|
|
152
|
+
const wpBin = resolveBin("webpack");
|
|
153
|
+
const wpConfig = resolveOwn("dist/webpack.config.js");
|
|
154
|
+
const cmd = `
|
|
155
|
+
${wpBin} serve
|
|
156
|
+
--config ${wpConfig}
|
|
157
|
+
${flags}
|
|
158
|
+
`;
|
|
159
|
+
logTitle(title);
|
|
160
|
+
logCommand(cmd);
|
|
161
|
+
runCommandSync(cmd, { stdio: "inherit" });
|
|
162
|
+
};
|
|
163
|
+
var assertOptionsValid = (options) => {
|
|
164
|
+
const { localCore, port } = options;
|
|
165
|
+
const { ifCore } = getIfCoreFns();
|
|
166
|
+
if (ifCore() && localCore) {
|
|
167
|
+
fail('Flag "--local-core" is redundant if running in Tamaro Core context.');
|
|
168
|
+
}
|
|
169
|
+
if (isNaN(Number(port))) {
|
|
170
|
+
fail('Flag "--port" should be a number.');
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
var prepareFlags = async (flags, options) => {
|
|
174
|
+
const { localCore, port: defaultPort } = options;
|
|
175
|
+
const port = await getPortPromise({ port: Number(defaultPort) });
|
|
176
|
+
if (localCore) {
|
|
177
|
+
flags.push("--env localCore");
|
|
178
|
+
}
|
|
179
|
+
flags.push(`--port ${port}`);
|
|
180
|
+
return flags;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// src/lib/aws.ts
|
|
184
|
+
import { execaCommandSync as execaCommandSync2 } from "execa";
|
|
185
|
+
import stripIndent from "strip-indent";
|
|
186
|
+
var withAwsAuthenticate = (fn, options) => {
|
|
187
|
+
awsAuthenticate(options);
|
|
188
|
+
return fn();
|
|
189
|
+
};
|
|
190
|
+
var awsAuthenticate = (options) => {
|
|
191
|
+
if (isSetEnv()) {
|
|
192
|
+
return;
|
|
164
193
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
194
|
+
try {
|
|
195
|
+
checkIdentity(options);
|
|
196
|
+
} catch (error) {
|
|
197
|
+
login(options);
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
var isSetEnv = () => {
|
|
201
|
+
return !!(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY);
|
|
202
|
+
};
|
|
203
|
+
var assertProfileValid = (profile) => {
|
|
204
|
+
if (isSetEnv()) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const profiles = getAvailableProfiles();
|
|
208
|
+
if (!profiles.includes(profile)) {
|
|
209
|
+
console.log(`Using AWS profile: \u201C${profile}\u201D`);
|
|
210
|
+
let message;
|
|
211
|
+
if (profiles.length === 0) {
|
|
212
|
+
message = stripIndent(`
|
|
213
|
+
No AWS profiles found.
|
|
214
|
+
`);
|
|
215
|
+
} else {
|
|
216
|
+
message = stripIndent(`
|
|
217
|
+
AWS profile \u201C${profile}\u201D has not been found.
|
|
218
|
+
Available profiles are: ${profiles.map((v) => `\u201C${v}\u201D`).join(", ")}.
|
|
219
|
+
`);
|
|
169
220
|
}
|
|
221
|
+
message += stripIndent(`
|
|
222
|
+
Run \u201Caws configure sso\u201D to set up SSO-enabled profile.
|
|
223
|
+
Check the wiki for more information:
|
|
224
|
+
https://raisenow.atlassian.net/wiki/x/lIrWvg
|
|
225
|
+
`);
|
|
226
|
+
fail(message);
|
|
170
227
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
var
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
228
|
+
};
|
|
229
|
+
var getAvailableProfiles = () => {
|
|
230
|
+
const { stdout } = execaCommandSync2("aws configure list-profiles");
|
|
231
|
+
return stdout.split("\n");
|
|
232
|
+
};
|
|
233
|
+
var checkIdentity = (options) => {
|
|
234
|
+
const flags = prepareFlags2([], options).join(" ");
|
|
235
|
+
execaCommandSync2(`aws sts get-caller-identity ${flags}`);
|
|
236
|
+
};
|
|
237
|
+
var login = (options) => {
|
|
238
|
+
const flags = prepareFlags2([], options).join(" ");
|
|
239
|
+
try {
|
|
240
|
+
execaCommandSync2(`aws sso login ${flags}`, { stdio: "inherit" });
|
|
241
|
+
console.log("");
|
|
242
|
+
} catch (error) {
|
|
243
|
+
fail("Login failed.");
|
|
186
244
|
}
|
|
187
|
-
return resolveFn(`${filePath}.js`);
|
|
188
|
-
};
|
|
189
|
-
var getWidgetUuid = () => (0, import_path.basename)(resolveApp("."));
|
|
190
|
-
var getPaths = (ifCore) => {
|
|
191
|
-
return ifCore({
|
|
192
|
-
app: resolveApp("."),
|
|
193
|
-
appEntry: resolveModule(resolveApp, "src/index"),
|
|
194
|
-
appDist: resolveApp("dist"),
|
|
195
|
-
appNodeModules: resolveApp("node_modules"),
|
|
196
|
-
appTsConfig: resolveApp("tsconfig.json"),
|
|
197
|
-
appHtml: resolveApp("src/*.html"),
|
|
198
|
-
appEnv: resolveApp(".env"),
|
|
199
|
-
appTailwindConfig: resolveApp("tailwind.config.js")
|
|
200
|
-
}, {
|
|
201
|
-
app: resolveApp("."),
|
|
202
|
-
appEntry: resolveModule(resolveApp, "widget"),
|
|
203
|
-
appDist: resolveApp(`../../dist/${getWidgetUuid()}`),
|
|
204
|
-
appNodeModules: resolveApp("../../node_modules"),
|
|
205
|
-
appTsConfig: resolveApp("tsconfig.json"),
|
|
206
|
-
appHtml: resolveApp("*.html"),
|
|
207
|
-
appEnv: resolveApp(".env"),
|
|
208
|
-
appTailwindConfig: void 0
|
|
209
|
-
});
|
|
210
245
|
};
|
|
211
|
-
var
|
|
212
|
-
|
|
246
|
+
var prepareFlags2 = (flags, options) => {
|
|
247
|
+
const { profile } = options;
|
|
248
|
+
if (!isSetEnv()) {
|
|
249
|
+
flags.push(`--profile ${profile}`);
|
|
250
|
+
}
|
|
251
|
+
return flags;
|
|
213
252
|
};
|
|
253
|
+
|
|
254
|
+
// src/lib/notifier.ts
|
|
255
|
+
import notifier from "node-notifier";
|
|
256
|
+
import stripIndent2 from "strip-indent";
|
|
214
257
|
var notify = (args) => {
|
|
215
|
-
const { title, message } = args;
|
|
216
|
-
|
|
258
|
+
const { title, message = "" } = args;
|
|
259
|
+
notifier.notify({
|
|
217
260
|
title,
|
|
218
|
-
message,
|
|
219
|
-
contentImage:
|
|
261
|
+
message: stripIndent2(message).trim(),
|
|
262
|
+
contentImage: "https://assets.raisenow.io/favicon.png",
|
|
220
263
|
sound: "Funk"
|
|
221
264
|
});
|
|
222
265
|
};
|
|
223
266
|
|
|
224
|
-
// src/commands/
|
|
225
|
-
var
|
|
226
|
-
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
const flags = prepareDevFlags(options);
|
|
234
|
-
const wpBin = import_resolve_bin.default.sync("webpack");
|
|
267
|
+
// src/commands/build.ts
|
|
268
|
+
var build = async (options) => {
|
|
269
|
+
assertOptionsValid2(options);
|
|
270
|
+
const flags = prepareFlags3([], options).join(" ");
|
|
271
|
+
const { ifCore } = getIfCoreFns();
|
|
272
|
+
const paths = getPaths(ifCore);
|
|
273
|
+
const configName = ifCore(CORE_CONFIG_NAME, getWidgetUuid());
|
|
274
|
+
const title = ifCore("Building optimised (minified) bundle of Tamaro Core \u2026", `Building optimised (minified) bundle of \u201C${configName}\u201D customer configuration \u2026`);
|
|
275
|
+
const wpBin = resolveBin("webpack");
|
|
235
276
|
const wpConfig = resolveOwn("dist/webpack.config.js");
|
|
236
|
-
const cmd =
|
|
277
|
+
const cmd = `
|
|
278
|
+
${wpBin}
|
|
279
|
+
--config ${wpConfig}
|
|
280
|
+
--env min
|
|
281
|
+
${flags}
|
|
282
|
+
`;
|
|
283
|
+
logTitle(title);
|
|
237
284
|
logCommand(cmd);
|
|
238
|
-
(
|
|
285
|
+
runCommandSync(cmd, { stdio: "inherit" });
|
|
286
|
+
logTitle(`
|
|
287
|
+
Bundle for \u201C${configName}\u201D customer configuration is done.`);
|
|
288
|
+
console.log(`Path: ${paths.appDist}
|
|
289
|
+
`);
|
|
290
|
+
process.on("exit", () => {
|
|
291
|
+
notify({
|
|
292
|
+
title: "build",
|
|
293
|
+
message: `Bundle for \u201C${configName}\u201D customer configuration is done.`
|
|
294
|
+
});
|
|
295
|
+
});
|
|
239
296
|
};
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
297
|
+
var assertOptionsValid2 = (options) => {
|
|
298
|
+
const { localCore, deploy: deploy2, profile } = options;
|
|
299
|
+
const { ifCore } = getIfCoreFns();
|
|
300
|
+
if (ifCore() && localCore) {
|
|
301
|
+
fail('Flag "--local-core" is redundant if running in Tamaro Core context.');
|
|
302
|
+
}
|
|
303
|
+
if (localCore && deploy2) {
|
|
304
|
+
fail('Flags "--local-core" and "--deploy" must not be used together.');
|
|
305
|
+
}
|
|
306
|
+
assertProfileValid(profile);
|
|
307
|
+
};
|
|
308
|
+
var prepareFlags3 = (flags, options) => {
|
|
245
309
|
const { localCore, analyze } = options;
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
310
|
+
if (localCore) {
|
|
311
|
+
flags.push("--env localCore");
|
|
312
|
+
}
|
|
313
|
+
if (analyze) {
|
|
314
|
+
flags.push("--env analyze");
|
|
315
|
+
}
|
|
316
|
+
return flags;
|
|
250
317
|
};
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
(
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
318
|
+
|
|
319
|
+
// src/commands/deploy.ts
|
|
320
|
+
import { existsSync } from "fs";
|
|
321
|
+
var deploy = async (options) => {
|
|
322
|
+
const { ifCore } = getIfCoreFns();
|
|
323
|
+
const paths = getPaths(ifCore);
|
|
324
|
+
assertOptionsValid3(options);
|
|
325
|
+
assertDistPathExists(paths.appDist);
|
|
326
|
+
const flags = prepareFlags4([], options).join(" ");
|
|
327
|
+
const { tag } = options;
|
|
328
|
+
const configName = ifCore(CORE_CONFIG_NAME, getWidgetUuid());
|
|
329
|
+
const deployUrl = `s3://${AWS_S3_BUCKET}/${configName}/${tag}`;
|
|
330
|
+
const entryFilename = ifCore("index.js", "widget.js");
|
|
331
|
+
const cmdSyncAll = `
|
|
332
|
+
aws s3 sync ${paths.appDist} ${deployUrl}
|
|
333
|
+
--acl public-read
|
|
334
|
+
--size-only
|
|
335
|
+
--exclude ${paths.appDist}/${entryFilename}
|
|
336
|
+
--cache-control max-age=31536000
|
|
337
|
+
${flags}
|
|
338
|
+
`;
|
|
339
|
+
logTitle("Deploying to AWS S3 \u2026");
|
|
340
|
+
logCommand(cmdSyncAll);
|
|
341
|
+
try {
|
|
342
|
+
withAwsAuthenticate(() => runCommandSync(cmdSyncAll, { stdout: "inherit" }), options);
|
|
343
|
+
} catch (error) {
|
|
344
|
+
fail(error.stderr);
|
|
345
|
+
}
|
|
346
|
+
const cmdCpEntry = `
|
|
347
|
+
aws s3 cp ${paths.appDist}/${entryFilename} ${deployUrl}/${entryFilename}
|
|
348
|
+
--acl public-read
|
|
349
|
+
--cache-control max-age=64800
|
|
350
|
+
${flags}
|
|
351
|
+
`;
|
|
352
|
+
logCommand(cmdCpEntry);
|
|
353
|
+
try {
|
|
354
|
+
withAwsAuthenticate(() => runCommandSync(cmdCpEntry, { stdout: "inherit" }), options);
|
|
355
|
+
} catch (error) {
|
|
356
|
+
fail(error.stderr);
|
|
357
|
+
}
|
|
358
|
+
const cmdInvalidateCache = `
|
|
359
|
+
aws cloudfront create-invalidation
|
|
360
|
+
--distribution-id ${AWS_CLOUDFRONT_DISTRIBUTION_ID}
|
|
361
|
+
--paths /${configName}/${tag}/*
|
|
362
|
+
${flags}
|
|
363
|
+
`;
|
|
364
|
+
logTitle("\nInvalidating edge cache \u2026");
|
|
365
|
+
logCommand(cmdInvalidateCache);
|
|
366
|
+
try {
|
|
367
|
+
withAwsAuthenticate(() => runCommandSync(cmdInvalidateCache), options);
|
|
368
|
+
} catch (error) {
|
|
369
|
+
fail(error.stderr);
|
|
370
|
+
}
|
|
371
|
+
const demoPage = `https://${AWS_S3_BUCKET}/${configName}/${tag}/index.html`;
|
|
372
|
+
const entryPoint = `https://${AWS_S3_BUCKET}/${configName}/${tag}/${entryFilename}`;
|
|
373
|
+
logTitle(`
|
|
374
|
+
Bundle for \u201C${configName}\u201D is deployed with tag \u201C${tag}\u201D.`);
|
|
375
|
+
logDataTable({
|
|
376
|
+
"Demo page:": demoPage,
|
|
377
|
+
"Entry point:": entryPoint
|
|
378
|
+
});
|
|
379
|
+
process.on("exit", () => {
|
|
380
|
+
notify({
|
|
381
|
+
title: "deploy",
|
|
382
|
+
message: `
|
|
383
|
+
Bundle for \u201C${configName}\u201D is deployed with tag \u201C${tag}\u201D.
|
|
384
|
+
Demo page: ${demoPage}
|
|
385
|
+
Entry point: ${entryPoint}
|
|
386
|
+
`
|
|
387
|
+
});
|
|
261
388
|
});
|
|
262
389
|
};
|
|
390
|
+
var assertOptionsValid3 = (options) => {
|
|
391
|
+
const { tag, profile } = options;
|
|
392
|
+
assertTagValid(tag);
|
|
393
|
+
assertProfileValid(profile);
|
|
394
|
+
};
|
|
395
|
+
var assertDistPathExists = (distPath) => {
|
|
396
|
+
if (!existsSync(distPath)) {
|
|
397
|
+
fail(`
|
|
398
|
+
Dist folder does not exists.
|
|
399
|
+
Make sure you have built the bundle before trying to deploy it.
|
|
400
|
+
`);
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
var assertTagValid = (tag) => {
|
|
404
|
+
const regex = /^[a-zA-Z0-9-_.]+$/;
|
|
405
|
+
if (!regex.test(tag)) {
|
|
406
|
+
fail(`Flag "--tag" has forbidden format. Allowed format: ${regex}.`);
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
var prepareFlags4 = (flags, options) => {
|
|
410
|
+
return prepareFlags2(flags, options);
|
|
411
|
+
};
|
|
263
412
|
|
|
264
|
-
// src/commands/
|
|
265
|
-
|
|
266
|
-
var
|
|
413
|
+
// src/commands/serve.ts
|
|
414
|
+
import { getPortPromise as getPortPromise2 } from "portfinder";
|
|
415
|
+
var serve = async (options) => {
|
|
416
|
+
assertOptionsValid4(options);
|
|
417
|
+
const flags = (await prepareFlags5([], options)).join(" ");
|
|
267
418
|
const { ifCore } = getIfCoreFns();
|
|
268
419
|
const paths = getPaths(ifCore);
|
|
269
|
-
const cmd = `
|
|
420
|
+
const cmd = `
|
|
421
|
+
npx -y serve ${paths.appDist}
|
|
422
|
+
--cors
|
|
423
|
+
${flags}
|
|
424
|
+
`;
|
|
425
|
+
logTitle(`Running web-server for pre-built bundle \u2026`);
|
|
270
426
|
logCommand(cmd);
|
|
271
|
-
(
|
|
427
|
+
runCommandSync(cmd, { stdio: "inherit" });
|
|
428
|
+
};
|
|
429
|
+
var assertOptionsValid4 = (options) => {
|
|
430
|
+
const { port } = options;
|
|
431
|
+
if (isNaN(Number(port))) {
|
|
432
|
+
fail('Flag "--port" should be a number.');
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
var prepareFlags5 = async (flags, options) => {
|
|
436
|
+
const { port: defaultPort } = options;
|
|
437
|
+
const port = await getPortPromise2({ port: Number(defaultPort) });
|
|
438
|
+
flags.push(`-p ${port}`);
|
|
439
|
+
return flags;
|
|
272
440
|
};
|
|
273
441
|
|
|
274
|
-
// src/commands/
|
|
275
|
-
var
|
|
276
|
-
|
|
442
|
+
// src/commands/list-deployed.ts
|
|
443
|
+
var listDeployed = async (options) => {
|
|
444
|
+
assertOptionsValid5(options);
|
|
445
|
+
const flags = prepareFlags6([], options).join(" ");
|
|
446
|
+
const { config } = options;
|
|
447
|
+
const { ifCore } = getIfCoreFns();
|
|
448
|
+
const configName = config != null ? config : ifCore(CORE_CONFIG_NAME, getWidgetUuid());
|
|
449
|
+
const title = !config && ifCore() ? `Listing deployments of Tamaro Core \u2026` : `Listing deployments of \u201C${configName}\u201D customer configuration \u2026`;
|
|
450
|
+
const deployUrl = `s3://${AWS_S3_BUCKET}/${configName}/`;
|
|
451
|
+
const cmd = `aws s3 ls ${deployUrl} ${flags}`;
|
|
452
|
+
let out = "";
|
|
453
|
+
logTitle(title);
|
|
454
|
+
logCommand(cmd);
|
|
455
|
+
try {
|
|
456
|
+
const result = withAwsAuthenticate(() => runCommandSync(cmd), options);
|
|
457
|
+
out = result.stdout;
|
|
458
|
+
} catch (error) {
|
|
459
|
+
out = error.stdout;
|
|
460
|
+
if (error.stderr) {
|
|
461
|
+
fail(error.stderr);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
const lines = out.split("\n");
|
|
465
|
+
const tags = parseTags(lines);
|
|
466
|
+
let text = "";
|
|
467
|
+
if (tags.length === 0) {
|
|
468
|
+
text = "No deployments found.";
|
|
469
|
+
} else {
|
|
470
|
+
text = tags.map((tag, idx) => {
|
|
471
|
+
return `${idx + 1}. https://${AWS_S3_BUCKET}/${configName}/${tag}/index.html`;
|
|
472
|
+
}).join("\n");
|
|
473
|
+
}
|
|
474
|
+
console.log(`${text}
|
|
475
|
+
`);
|
|
476
|
+
};
|
|
477
|
+
var assertOptionsValid5 = (options) => {
|
|
478
|
+
const { config, profile } = options;
|
|
479
|
+
assertConfigValid(config);
|
|
480
|
+
assertProfileValid(profile);
|
|
481
|
+
};
|
|
482
|
+
var assertConfigValid = (config) => {
|
|
483
|
+
if (!config) {
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
const regex = /^[a-zA-Z0-9-_]+$/;
|
|
487
|
+
if (!regex.test(config)) {
|
|
488
|
+
fail(`Flag "--config" has forbidden format. Allowed format: ${regex}.`);
|
|
489
|
+
}
|
|
490
|
+
};
|
|
491
|
+
var prepareFlags6 = (flags, options) => {
|
|
492
|
+
return prepareFlags2(flags, options);
|
|
493
|
+
};
|
|
494
|
+
var parseTags = (lines) => {
|
|
495
|
+
const regex = /^\s*PRE\s*/;
|
|
496
|
+
return lines.filter((line) => regex.test(line)).map((line) => line.replace(regex, "").replace(/\/$/, ""));
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
// src/commands/deploy-email-config.ts
|
|
500
|
+
import { existsSync as existsSync2 } from "fs";
|
|
501
|
+
var deployEmailConfig = async (options) => {
|
|
277
502
|
const { ifCore } = getIfCoreFns();
|
|
278
503
|
const paths = getPaths(ifCore);
|
|
279
|
-
const
|
|
504
|
+
const emailConfigPath = `${paths.app}/email-config`;
|
|
505
|
+
assertOptionsValid6(options);
|
|
506
|
+
assertEmailConfigPathExists(emailConfigPath);
|
|
507
|
+
assertIsNotCore();
|
|
508
|
+
const flags = prepareFlags7([], options).join(" ");
|
|
509
|
+
const { bucket } = options;
|
|
510
|
+
const configName = getWidgetUuid();
|
|
511
|
+
const deployUrl = `s3://${bucket}/${configName}`;
|
|
512
|
+
const cmd = `
|
|
513
|
+
aws s3 sync ${emailConfigPath} ${deployUrl}
|
|
514
|
+
--delete
|
|
515
|
+
--exact-timestamps
|
|
516
|
+
${flags}
|
|
517
|
+
`;
|
|
518
|
+
logTitle(`Deploying email configuration for \u201C${configName}\u201D customer configuration to AWS S3 \u2026`);
|
|
280
519
|
logCommand(cmd);
|
|
281
|
-
|
|
520
|
+
try {
|
|
521
|
+
withAwsAuthenticate(() => runCommandSync(cmd, { stdout: "inherit" }), options);
|
|
522
|
+
} catch (error) {
|
|
523
|
+
fail(error.stderr);
|
|
524
|
+
}
|
|
525
|
+
logTitle(`Email configuration for \u201C${configName}\u201D customer configuration is deployed.`);
|
|
526
|
+
logDataTable({ "Deploy URL:": deployUrl });
|
|
527
|
+
process.on("exit", () => {
|
|
528
|
+
notify({
|
|
529
|
+
title: `deploy-email-config`,
|
|
530
|
+
message: `Email configuration for \u201C${configName}\u201D customer configuration is deployed.`
|
|
531
|
+
});
|
|
532
|
+
});
|
|
533
|
+
};
|
|
534
|
+
var assertOptionsValid6 = (options) => {
|
|
535
|
+
const { bucket, profile } = options;
|
|
536
|
+
assertBucketValid(bucket);
|
|
537
|
+
assertProfileValid(profile);
|
|
538
|
+
};
|
|
539
|
+
var assertEmailConfigPathExists = (distPath) => {
|
|
540
|
+
if (!existsSync2(distPath)) {
|
|
541
|
+
fail("Email config folder does not exists. Nothing to deploy.");
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
var assertBucketValid = (tag) => {
|
|
545
|
+
const regex = /^[a-zA-Z0-9-_]+$/;
|
|
546
|
+
if (!regex.test(tag)) {
|
|
547
|
+
fail(`Flag "--bucket" has forbidden format. Allowed format: ${regex}.`);
|
|
548
|
+
}
|
|
549
|
+
};
|
|
550
|
+
var assertIsNotCore = () => {
|
|
551
|
+
const { ifCore } = getIfCoreFns();
|
|
552
|
+
if (ifCore()) {
|
|
553
|
+
fail("You cannot deploy widget email configuration for Tamaro Core.");
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
var prepareFlags7 = (flags, options) => {
|
|
557
|
+
return prepareFlags2(flags, options);
|
|
282
558
|
};
|
|
283
559
|
|
|
284
560
|
// src/cli.ts
|
|
@@ -286,27 +562,43 @@ process.on("unhandledRejection", (error) => {
|
|
|
286
562
|
throw error;
|
|
287
563
|
});
|
|
288
564
|
process.on("SIGINT", () => {
|
|
289
|
-
process.exit(
|
|
565
|
+
process.exit(1);
|
|
290
566
|
});
|
|
291
|
-
var cli =
|
|
292
|
-
cli.command("dev").description("Run
|
|
567
|
+
var cli = createCommand().name(package_default.name).version(package_default.version, "-v, --version");
|
|
568
|
+
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("--port <port>", "Web server port", `${DEFAULT_PORT}`).action(async (options) => {
|
|
293
569
|
await dev(options);
|
|
294
570
|
});
|
|
295
|
-
cli.command("build").description("Build optimised (minified) bundle of Tamaro Core or customer configuration
|
|
571
|
+
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("--port <port>", "Web server port", `${DEFAULT_PORT}`).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("--profile <profile>", "AWS profile which should be used for the deployment of the bundle", DEFAULT_AWS_PROFILE).action(async (options) => {
|
|
296
572
|
await build(options);
|
|
573
|
+
if (options.serve) {
|
|
574
|
+
await serve(options);
|
|
575
|
+
}
|
|
297
576
|
if (options.deploy) {
|
|
298
577
|
await deploy(options);
|
|
299
578
|
}
|
|
300
|
-
if (options.serve) {
|
|
301
|
-
await serve();
|
|
302
|
-
}
|
|
303
579
|
});
|
|
304
|
-
cli.command("
|
|
580
|
+
cli.command("serve").description("Run a local web server for pre-built bundle").option("--port <port>", "Web server port", `${DEFAULT_PORT}`).action(async (options) => {
|
|
581
|
+
await serve(options);
|
|
582
|
+
});
|
|
583
|
+
cli.command("deploy").description("Deploy a pre-built Tamaro Core or customer configuration bundle to AWS S3").option("--tag <tag>", "Tag which should be used for the deployment of the bundle", DEFAULT_TAG).option("--profile <profile>", "AWS profile which should be used for the deployment of the bundle", DEFAULT_AWS_PROFILE).action(async (options) => {
|
|
305
584
|
await deploy(options);
|
|
306
585
|
});
|
|
307
|
-
cli.command("
|
|
308
|
-
await
|
|
586
|
+
cli.command("list-deployed").description("List deployments of Tamaro Core or a particular customer configuration").option("--config <config>", "Configuration name (default: current customer configuration)").option("--profile <profile>", "AWS profile which should be used for fetching deployments", DEFAULT_AWS_PROFILE).action(async (options) => {
|
|
587
|
+
await listDeployed(options);
|
|
588
|
+
});
|
|
589
|
+
cli.command("deploy-email-config").description("Deploy a widget\u2019s email configuration to AWS S3").option("--bucket <bucket>", "AWS S3 bucket where it should be deployed", DEFAULT_AWS_S3_EMAIL_CONFIG_BUCKET).option("--profile <profile>", "AWS profile which should be used for the deployment of email configuration", DEFAULT_AWS_PROFILE).action(async (options) => {
|
|
590
|
+
await deployEmailConfig(options);
|
|
309
591
|
});
|
|
310
592
|
(async () => {
|
|
311
|
-
|
|
593
|
+
try {
|
|
594
|
+
await cli.parseAsync(process.argv);
|
|
595
|
+
} catch (error) {
|
|
596
|
+
if (error.signal === "SIGINT" && error.signalDescription) {
|
|
597
|
+
logError(`
|
|
598
|
+
${error.signalDescription}`);
|
|
599
|
+
} else {
|
|
600
|
+
console.log("");
|
|
601
|
+
logError(error.stack);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
312
604
|
})();
|