@raisenow/tamaro-cli 1.5.0 → 1.6.0-beta.0
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/.nvmrc +1 -1
- package/README.md +92 -0
- package/bitbucket-pipelines.yml +1 -1
- package/dist/{chunk-HGPQTHLY.js → chunk-MCUAYEGK.js} +13 -2
- package/dist/cli.js +624 -179
- package/dist/webpack.config.js +1 -1
- package/package.json +40 -39
- package/pnpm-workspace.yaml +4 -0
package/dist/cli.js
CHANGED
|
@@ -18,17 +18,415 @@ import {
|
|
|
18
18
|
logCommand,
|
|
19
19
|
logDataTable,
|
|
20
20
|
logError,
|
|
21
|
+
logSuccess,
|
|
21
22
|
logTitle,
|
|
22
23
|
resolveBin,
|
|
23
24
|
resolveOwn,
|
|
24
25
|
runCommandSync
|
|
25
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-MCUAYEGK.js";
|
|
26
27
|
|
|
27
28
|
// src/cli.ts
|
|
28
29
|
import { createCommand } from "commander";
|
|
29
30
|
|
|
31
|
+
// src/commands/archive.ts
|
|
32
|
+
import { existsSync, mkdirSync, renameSync } from "fs";
|
|
33
|
+
import { basename, dirname, resolve } from "path";
|
|
34
|
+
import chalk from "chalk";
|
|
35
|
+
|
|
36
|
+
// src/lib/aws.ts
|
|
37
|
+
import { execaCommandSync } from "execa";
|
|
38
|
+
import prompts from "prompts";
|
|
39
|
+
import stripIndent from "strip-indent";
|
|
40
|
+
var awsAuthenticate = (options) => {
|
|
41
|
+
if (options.ci) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
checkIdentity(options);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
login(options);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
var assertProfilesPresent = () => {
|
|
51
|
+
const profiles = getAvailableProfiles();
|
|
52
|
+
if (profiles.length === 0) {
|
|
53
|
+
halt(
|
|
54
|
+
stripIndent(`
|
|
55
|
+
No AWS profiles found.
|
|
56
|
+
Run "aws configure sso" to set up SSO-enabled profile.
|
|
57
|
+
Check the wiki for more information:
|
|
58
|
+
https://raisenow.atlassian.net/wiki/x/lIrWvg
|
|
59
|
+
`)
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
var getAvailableProfiles = () => {
|
|
64
|
+
const { stdout } = execaCommandSync("aws configure list-profiles");
|
|
65
|
+
return stdout.split("\n");
|
|
66
|
+
};
|
|
67
|
+
var checkIdentity = (options) => {
|
|
68
|
+
const flags = prepareFlags(options);
|
|
69
|
+
execaCommandSync(`aws sts get-caller-identity ${flags}`);
|
|
70
|
+
};
|
|
71
|
+
var login = (options) => {
|
|
72
|
+
const flags = prepareFlags(options);
|
|
73
|
+
try {
|
|
74
|
+
execaCommandSync(`aws sso login ${flags}`, { stdio: "inherit" });
|
|
75
|
+
console.log("");
|
|
76
|
+
} catch (error) {
|
|
77
|
+
halt("Login failed.");
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var prepareFlags = (options) => {
|
|
81
|
+
const flags = [];
|
|
82
|
+
const { profile } = options;
|
|
83
|
+
if (profile) {
|
|
84
|
+
flags.push(`--profile ${profile}`);
|
|
85
|
+
}
|
|
86
|
+
return flags.join(" ");
|
|
87
|
+
};
|
|
88
|
+
var assertProfileValid = (profile) => {
|
|
89
|
+
const profiles = getAvailableProfiles();
|
|
90
|
+
if (!profiles.includes(profile)) {
|
|
91
|
+
halt(
|
|
92
|
+
stripIndent(`
|
|
93
|
+
AWS profile "${profile}" is not found.
|
|
94
|
+
Available profiles are: ${profiles.map((v) => `"${v}"`).join(", ")}.
|
|
95
|
+
`)
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
var promptProfile = async () => {
|
|
100
|
+
const profiles = getAvailableProfiles().filter((v) => !!v).map((v) => ({ title: v, value: v }));
|
|
101
|
+
const { profile } = await prompts(
|
|
102
|
+
[
|
|
103
|
+
{
|
|
104
|
+
type: "select",
|
|
105
|
+
name: "profile",
|
|
106
|
+
message: "Select AWS profile",
|
|
107
|
+
choices: profiles
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
{
|
|
111
|
+
onCancel: () => halt()
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
return profile;
|
|
115
|
+
};
|
|
116
|
+
var promptConfirmation = async (message, skipConfirmation) => {
|
|
117
|
+
if (skipConfirmation) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const { confirmed } = await prompts(
|
|
121
|
+
[
|
|
122
|
+
{
|
|
123
|
+
type: "confirm",
|
|
124
|
+
name: "confirmed",
|
|
125
|
+
message,
|
|
126
|
+
initial: false
|
|
127
|
+
}
|
|
128
|
+
],
|
|
129
|
+
{
|
|
130
|
+
onCancel: () => halt()
|
|
131
|
+
}
|
|
132
|
+
);
|
|
133
|
+
if (!confirmed) {
|
|
134
|
+
halt("Operation cancelled.");
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
var assertTagValid = (tag) => {
|
|
138
|
+
const regex = /^[a-zA-Z0-9-_.]+$/;
|
|
139
|
+
if (!regex.test(tag)) {
|
|
140
|
+
halt(
|
|
141
|
+
`Flag "--tag" has forbidden format. Allowed format: ${regex.toString()}.`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// src/lib/notifier.ts
|
|
147
|
+
import notifier from "node-notifier";
|
|
148
|
+
import stripIndent2 from "strip-indent";
|
|
149
|
+
var notify = (args) => {
|
|
150
|
+
const { title, message = "" } = args;
|
|
151
|
+
notifier.notify({
|
|
152
|
+
title,
|
|
153
|
+
message: stripIndent2(message).trim(),
|
|
154
|
+
contentImage: "https://assets.raisenow.io/favicon.png",
|
|
155
|
+
sound: "Funk"
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// src/commands/undeploy.ts
|
|
160
|
+
var undeploy = async (options) => {
|
|
161
|
+
const { ifCore } = getIfCoreFns();
|
|
162
|
+
const configName = ifCore(CORE_CONFIG_NAME, getWidgetUuid());
|
|
163
|
+
if (!options.profile && !options.ci) {
|
|
164
|
+
assertProfilesPresent();
|
|
165
|
+
options.profile = await promptProfile();
|
|
166
|
+
}
|
|
167
|
+
assertOptionsValid(options);
|
|
168
|
+
awsAuthenticate(options);
|
|
169
|
+
const flags = prepareFlags(options);
|
|
170
|
+
const { tag, all, dryrun } = options;
|
|
171
|
+
const dryRunFlag = dryrun ? `--dryrun` : "";
|
|
172
|
+
const deployUrl = all ? `s3://${AWS_S3_BUCKET_TAMARO}/${configName}/` : `s3://${AWS_S3_BUCKET_TAMARO}/${configName}/${tag}/`;
|
|
173
|
+
const description = all ? `all tags of "${configName}"` : `tag "${tag}" of "${configName}"`;
|
|
174
|
+
if (dryRunFlag) {
|
|
175
|
+
logTitle("\u{1F9EA} DRY RUN MODE - No actual changes will be made \u{1F9EA}");
|
|
176
|
+
}
|
|
177
|
+
await promptConfirmation(
|
|
178
|
+
`Are you sure you want to undeploy ${description}?`,
|
|
179
|
+
options.yes
|
|
180
|
+
);
|
|
181
|
+
const cmd = `
|
|
182
|
+
aws s3 rm ${deployUrl}
|
|
183
|
+
--recursive
|
|
184
|
+
${flags}
|
|
185
|
+
${dryRunFlag}
|
|
186
|
+
`;
|
|
187
|
+
logTitle(`Undeploying ${description} from AWS S3 \u2026`);
|
|
188
|
+
logCommand(cmd);
|
|
189
|
+
try {
|
|
190
|
+
runCommandSync(cmd, { stdout: "inherit" });
|
|
191
|
+
} catch (error) {
|
|
192
|
+
halt(error.stderr);
|
|
193
|
+
}
|
|
194
|
+
if (!dryRunFlag) {
|
|
195
|
+
const invalidationPath = all ? `/${configName}/*` : `/${configName}/${tag}/*`;
|
|
196
|
+
const cmdInvalidateCache = `
|
|
197
|
+
aws cloudfront create-invalidation
|
|
198
|
+
--distribution-id ${AWS_CLOUDFRONT_DISTRIBUTION_ID}
|
|
199
|
+
--paths ${invalidationPath}
|
|
200
|
+
${flags}
|
|
201
|
+
`;
|
|
202
|
+
logTitle("\nInvalidating edge cache \u2026");
|
|
203
|
+
logCommand(cmdInvalidateCache);
|
|
204
|
+
try {
|
|
205
|
+
runCommandSync(cmdInvalidateCache);
|
|
206
|
+
} catch (error) {
|
|
207
|
+
halt(error.stderr);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
logTitle(`
|
|
211
|
+
${description} has been undeployed.`);
|
|
212
|
+
logDataTable({ "Removed URL:": deployUrl });
|
|
213
|
+
process.on("exit", () => {
|
|
214
|
+
notify({
|
|
215
|
+
title: "undeploy",
|
|
216
|
+
message: `${description} has been undeployed.`
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
};
|
|
220
|
+
var assertOptionsValid = (options) => {
|
|
221
|
+
const { profile, tag, all } = options;
|
|
222
|
+
const { ifCore } = getIfCoreFns();
|
|
223
|
+
if (ifCore() && all) {
|
|
224
|
+
halt('Flag "--all" must not be used in Tamaro Core context.');
|
|
225
|
+
}
|
|
226
|
+
if (ifCore() && tag === DEFAULT_TAG) {
|
|
227
|
+
halt("You cannot undeploy the default tag for Tamaro Core.");
|
|
228
|
+
}
|
|
229
|
+
if (profile) {
|
|
230
|
+
assertProfileValid(profile);
|
|
231
|
+
}
|
|
232
|
+
if (all && tag) {
|
|
233
|
+
halt('Flags "--tag" and "--all" must not be used together.');
|
|
234
|
+
}
|
|
235
|
+
if (!all && tag) {
|
|
236
|
+
assertTagValid(tag);
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// src/commands/undeploy-email-config.ts
|
|
241
|
+
import prompts2 from "prompts";
|
|
242
|
+
var undeployEmailConfig = async (options) => {
|
|
243
|
+
const { ifCore } = getIfCoreFns();
|
|
244
|
+
assertIsNotCore(ifCore);
|
|
245
|
+
if (!options.profile && !options.ci) {
|
|
246
|
+
assertProfilesPresent();
|
|
247
|
+
options.profile = await promptProfile();
|
|
248
|
+
}
|
|
249
|
+
if (!options.bucket) {
|
|
250
|
+
options.bucket = options.ci ? AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD : await promptBucketTamaroEmailConfig();
|
|
251
|
+
}
|
|
252
|
+
assertOptionsValid2(options);
|
|
253
|
+
awsAuthenticate(options);
|
|
254
|
+
const flags = prepareFlags(options);
|
|
255
|
+
const dryRunFlag = options.dryrun ? `--dryrun` : "";
|
|
256
|
+
const configName = getWidgetUuid();
|
|
257
|
+
const deployUrl = `s3://${options.bucket}/${configName}/`;
|
|
258
|
+
await promptConfirmation(
|
|
259
|
+
`Are you sure you want to undeploy the email configuration for "${configName}" from "${options.bucket}"?`,
|
|
260
|
+
options.yes
|
|
261
|
+
);
|
|
262
|
+
if (dryRunFlag) {
|
|
263
|
+
logTitle("\u{1F9EA} DRY RUN MODE - No actual changes will be made \u{1F9EA}");
|
|
264
|
+
}
|
|
265
|
+
const cmd = `
|
|
266
|
+
aws s3 rm ${deployUrl}
|
|
267
|
+
--recursive
|
|
268
|
+
${flags}
|
|
269
|
+
${dryRunFlag}
|
|
270
|
+
`;
|
|
271
|
+
logTitle(
|
|
272
|
+
`Undeploying email configuration for "${configName}" from AWS S3 \u2026`
|
|
273
|
+
);
|
|
274
|
+
logCommand(cmd);
|
|
275
|
+
try {
|
|
276
|
+
runCommandSync(cmd, { stdout: "inherit" });
|
|
277
|
+
} catch (error) {
|
|
278
|
+
halt(error.stderr);
|
|
279
|
+
}
|
|
280
|
+
logTitle(
|
|
281
|
+
`Email configuration for "${configName}" has been undeployed from "${options.bucket}".`
|
|
282
|
+
);
|
|
283
|
+
logDataTable({ "Removed URL:": deployUrl });
|
|
284
|
+
process.on("exit", () => {
|
|
285
|
+
notify({
|
|
286
|
+
title: "undeploy-email-config",
|
|
287
|
+
message: `Email configuration for "${configName}" has been undeployed.`
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
};
|
|
291
|
+
var assertOptionsValid2 = (options) => {
|
|
292
|
+
const { profile, bucket } = options;
|
|
293
|
+
if (profile) {
|
|
294
|
+
assertProfileValid(profile);
|
|
295
|
+
}
|
|
296
|
+
if (bucket) {
|
|
297
|
+
assertBucketValid(bucket);
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
var assertIsNotCore = (ifCore) => {
|
|
301
|
+
if (ifCore()) {
|
|
302
|
+
halt("You cannot undeploy widget email configuration for Tamaro Core.");
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
var assertBucketValid = (bucket) => {
|
|
306
|
+
const buckets = [
|
|
307
|
+
AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_STAGE,
|
|
308
|
+
AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD
|
|
309
|
+
];
|
|
310
|
+
if (!buckets.includes(bucket)) {
|
|
311
|
+
halt("Invalid bucket name.");
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
var promptBucketTamaroEmailConfig = async () => {
|
|
315
|
+
const buckets = [
|
|
316
|
+
{ title: "stage", value: AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_STAGE },
|
|
317
|
+
{ title: "prod", value: AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD }
|
|
318
|
+
];
|
|
319
|
+
const { bucket } = await prompts2(
|
|
320
|
+
[
|
|
321
|
+
{
|
|
322
|
+
type: "select",
|
|
323
|
+
name: "bucket",
|
|
324
|
+
message: "Select environment",
|
|
325
|
+
choices: buckets
|
|
326
|
+
}
|
|
327
|
+
],
|
|
328
|
+
{
|
|
329
|
+
onCancel: () => halt()
|
|
330
|
+
}
|
|
331
|
+
);
|
|
332
|
+
return bucket;
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
// src/commands/archive.ts
|
|
336
|
+
var archive = async (options) => {
|
|
337
|
+
const { ifCore } = getIfCoreFns();
|
|
338
|
+
assertIsNotCore2(ifCore);
|
|
339
|
+
assertIsNotArchived();
|
|
340
|
+
const configName = getWidgetUuid();
|
|
341
|
+
const cwd = process.cwd();
|
|
342
|
+
const parentDir = dirname(cwd);
|
|
343
|
+
const archiveDir = resolve(parentDir, "_archived");
|
|
344
|
+
const archiveTarget = resolve(archiveDir, configName);
|
|
345
|
+
assertArchiveTargetDoesNotExist(archiveTarget);
|
|
346
|
+
if (!options.profile && !options.ci) {
|
|
347
|
+
assertProfilesPresent();
|
|
348
|
+
options.profile = await promptProfile();
|
|
349
|
+
}
|
|
350
|
+
assertOptionsValid3(options);
|
|
351
|
+
if (options.dryrun) {
|
|
352
|
+
logTitle("\u{1F9EA} DRY RUN MODE - No actual changes will be made \u{1F9EA}");
|
|
353
|
+
}
|
|
354
|
+
await promptConfirmation(
|
|
355
|
+
`Are you sure you want to archive "${configName}"? This will ${chalk.red(`undeploy all tags and email configurations of "${configName}"`)}.`,
|
|
356
|
+
options.yes
|
|
357
|
+
);
|
|
358
|
+
logTitle(`
|
|
359
|
+
Undeploying all tags for "${configName}" \u2026`);
|
|
360
|
+
await undeploy({
|
|
361
|
+
all: true,
|
|
362
|
+
yes: true,
|
|
363
|
+
profile: options.profile,
|
|
364
|
+
ci: options.ci,
|
|
365
|
+
dryrun: options.dryrun
|
|
366
|
+
});
|
|
367
|
+
logSuccess(`
|
|
368
|
+
\u2705 Undeployed all tags for "${configName}" \u2026`);
|
|
369
|
+
logTitle(`
|
|
370
|
+
Undeploying email configuration for "${configName}" \u2026`);
|
|
371
|
+
await undeployEmailConfig({
|
|
372
|
+
yes: true,
|
|
373
|
+
profile: options.profile,
|
|
374
|
+
ci: options.ci,
|
|
375
|
+
dryrun: options.dryrun,
|
|
376
|
+
bucket: AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD
|
|
377
|
+
});
|
|
378
|
+
logSuccess(`
|
|
379
|
+
\u2705 Undeployed email configuration for "${configName}" \u2026`);
|
|
380
|
+
logTitle(`
|
|
381
|
+
Archiving "${configName}" \u2026`);
|
|
382
|
+
if (!options.dryrun) {
|
|
383
|
+
if (!existsSync(archiveDir)) {
|
|
384
|
+
mkdirSync(archiveDir, { recursive: true });
|
|
385
|
+
}
|
|
386
|
+
renameSync(cwd, archiveTarget);
|
|
387
|
+
logSuccess(`\u2705 Moved to ${archiveTarget}`);
|
|
388
|
+
} else {
|
|
389
|
+
logTitle(`Would move ${cwd} \u2192 ${archiveTarget}`);
|
|
390
|
+
}
|
|
391
|
+
logSuccess(`
|
|
392
|
+
"\u2705 ${configName}" has been archived.`);
|
|
393
|
+
logDataTable({
|
|
394
|
+
"Archived to:": archiveTarget
|
|
395
|
+
});
|
|
396
|
+
process.on("exit", () => {
|
|
397
|
+
notify({
|
|
398
|
+
title: "archive",
|
|
399
|
+
message: `"${configName}" has been archived.`
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
};
|
|
403
|
+
var assertOptionsValid3 = (options) => {
|
|
404
|
+
const { profile } = options;
|
|
405
|
+
if (profile) {
|
|
406
|
+
assertProfileValid(profile);
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
var assertIsNotCore2 = (ifCore) => {
|
|
410
|
+
if (ifCore()) {
|
|
411
|
+
halt("You cannot archive Tamaro Core.");
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
var assertIsNotArchived = () => {
|
|
415
|
+
const parentDirName = basename(dirname(process.cwd()));
|
|
416
|
+
if (parentDirName === "_archived") {
|
|
417
|
+
halt("This configuration is already archived.");
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
var assertArchiveTargetDoesNotExist = (archiveTarget) => {
|
|
421
|
+
if (existsSync(archiveTarget)) {
|
|
422
|
+
halt(
|
|
423
|
+
`Archive target already exists: ${archiveTarget}. Please remove it first.`
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
|
|
30
428
|
// src/commands/validate.ts
|
|
31
|
-
import {
|
|
429
|
+
import { globSync } from "glob";
|
|
32
430
|
|
|
33
431
|
// src/lib/validators/validateEmailTemplates.ts
|
|
34
432
|
import fs from "fs";
|
|
@@ -140,7 +538,7 @@ var compileEmailTemplate = (template) => {
|
|
|
140
538
|
// src/commands/validate.ts
|
|
141
539
|
var validate = async () => {
|
|
142
540
|
const errors = validateEmailTemplates(
|
|
143
|
-
(
|
|
541
|
+
globSync("email-config/templates/**/*.hbs").sort()
|
|
144
542
|
);
|
|
145
543
|
if (errors.length) {
|
|
146
544
|
halt(errors.map((el) => el.toString()).join("\n"));
|
|
@@ -148,101 +546,20 @@ var validate = async () => {
|
|
|
148
546
|
logTitle("Validated successfully");
|
|
149
547
|
};
|
|
150
548
|
|
|
151
|
-
// src/lib/aws.ts
|
|
152
|
-
import { execaCommandSync } from "execa";
|
|
153
|
-
import prompts from "prompts";
|
|
154
|
-
import stripIndent from "strip-indent";
|
|
155
|
-
var awsAuthenticate = (options) => {
|
|
156
|
-
if (options.ci) {
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
try {
|
|
160
|
-
checkIdentity(options);
|
|
161
|
-
} catch (error) {
|
|
162
|
-
login(options);
|
|
163
|
-
}
|
|
164
|
-
};
|
|
165
|
-
var assertProfilesPresent = () => {
|
|
166
|
-
const profiles = getAvailableProfiles();
|
|
167
|
-
if (profiles.length === 0) {
|
|
168
|
-
halt(
|
|
169
|
-
stripIndent(`
|
|
170
|
-
No AWS profiles found.
|
|
171
|
-
Run "aws configure sso" to set up SSO-enabled profile.
|
|
172
|
-
Check the wiki for more information:
|
|
173
|
-
https://raisenow.atlassian.net/wiki/x/lIrWvg
|
|
174
|
-
`)
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
var getAvailableProfiles = () => {
|
|
179
|
-
const { stdout } = execaCommandSync("aws configure list-profiles");
|
|
180
|
-
return stdout.split("\n");
|
|
181
|
-
};
|
|
182
|
-
var checkIdentity = (options) => {
|
|
183
|
-
const flags = prepareFlags(options);
|
|
184
|
-
execaCommandSync(`aws sts get-caller-identity ${flags}`);
|
|
185
|
-
};
|
|
186
|
-
var login = (options) => {
|
|
187
|
-
const flags = prepareFlags(options);
|
|
188
|
-
try {
|
|
189
|
-
execaCommandSync(`aws sso login ${flags}`, { stdio: "inherit" });
|
|
190
|
-
console.log("");
|
|
191
|
-
} catch (error) {
|
|
192
|
-
halt("Login failed.");
|
|
193
|
-
}
|
|
194
|
-
};
|
|
195
|
-
var prepareFlags = (options) => {
|
|
196
|
-
const flags = [];
|
|
197
|
-
const { profile } = options;
|
|
198
|
-
if (profile) {
|
|
199
|
-
flags.push(`--profile ${profile}`);
|
|
200
|
-
}
|
|
201
|
-
return flags.join(" ");
|
|
202
|
-
};
|
|
203
|
-
var assertProfileValid = (profile) => {
|
|
204
|
-
const profiles = getAvailableProfiles();
|
|
205
|
-
if (!profiles.includes(profile)) {
|
|
206
|
-
halt(
|
|
207
|
-
stripIndent(`
|
|
208
|
-
AWS profile "${profile}" is not found.
|
|
209
|
-
Available profiles are: ${profiles.map((v) => `"${v}"`).join(", ")}.
|
|
210
|
-
`)
|
|
211
|
-
);
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
var promptProfile = async () => {
|
|
215
|
-
const profiles = getAvailableProfiles().filter((v) => !!v).map((v) => ({ title: v, value: v }));
|
|
216
|
-
const { profile } = await prompts(
|
|
217
|
-
[
|
|
218
|
-
{
|
|
219
|
-
type: "select",
|
|
220
|
-
name: "profile",
|
|
221
|
-
message: "Select AWS profile",
|
|
222
|
-
choices: profiles
|
|
223
|
-
}
|
|
224
|
-
],
|
|
225
|
-
{
|
|
226
|
-
onCancel: () => halt()
|
|
227
|
-
}
|
|
228
|
-
);
|
|
229
|
-
return profile;
|
|
230
|
-
};
|
|
231
|
-
|
|
232
549
|
// src/lib/https.ts
|
|
233
|
-
import { existsSync } from "fs";
|
|
234
|
-
import { resolve } from "path";
|
|
235
|
-
import
|
|
550
|
+
import { existsSync as existsSync2 } from "fs";
|
|
551
|
+
import { resolve as resolve2 } from "path";
|
|
552
|
+
import stripIndent3 from "strip-indent";
|
|
236
553
|
var assertCrtExists = () => {
|
|
237
554
|
const { ifCore } = getIfCoreFns();
|
|
238
555
|
const paths = getPaths(ifCore);
|
|
239
|
-
const certFile =
|
|
240
|
-
const keyFile =
|
|
241
|
-
if (
|
|
556
|
+
const certFile = resolve2(paths.root, HTTPS_CRT_FILE);
|
|
557
|
+
const keyFile = resolve2(paths.root, HTTPS_KEY_FILE);
|
|
558
|
+
if (existsSync2(certFile) && existsSync2(keyFile)) {
|
|
242
559
|
return;
|
|
243
560
|
}
|
|
244
561
|
halt(
|
|
245
|
-
|
|
562
|
+
stripIndent3(`
|
|
246
563
|
Flag "--https" is used, but "${HTTPS_CRT_FILE}" and/or "${HTTPS_KEY_FILE}" files are not found.
|
|
247
564
|
You need to generate certificate first.
|
|
248
565
|
Check docs: https://unpkg.com/@raisenow/tamaro-cli/readme.html#/?id=use-transport-level-security-https
|
|
@@ -250,19 +567,6 @@ var assertCrtExists = () => {
|
|
|
250
567
|
);
|
|
251
568
|
};
|
|
252
569
|
|
|
253
|
-
// src/lib/notifier.ts
|
|
254
|
-
import notifier from "node-notifier";
|
|
255
|
-
import stripIndent3 from "strip-indent";
|
|
256
|
-
var notify = (args) => {
|
|
257
|
-
const { title, message = "" } = args;
|
|
258
|
-
notifier.notify({
|
|
259
|
-
title,
|
|
260
|
-
message: stripIndent3(message).trim(),
|
|
261
|
-
contentImage: "https://assets.raisenow.io/favicon.png",
|
|
262
|
-
sound: "Funk"
|
|
263
|
-
});
|
|
264
|
-
};
|
|
265
|
-
|
|
266
570
|
// src/commands/build.ts
|
|
267
571
|
var build = async (options) => {
|
|
268
572
|
const { env } = options;
|
|
@@ -271,7 +575,7 @@ var build = async (options) => {
|
|
|
271
575
|
assertProfilesPresent();
|
|
272
576
|
options.profile = await promptProfile();
|
|
273
577
|
}
|
|
274
|
-
|
|
578
|
+
assertOptionsValid4(options);
|
|
275
579
|
await validate();
|
|
276
580
|
const flags = prepareFlags2(options);
|
|
277
581
|
const { ifCore } = getIfCoreFns();
|
|
@@ -303,7 +607,7 @@ Bundle for "${configName}" customer configuration is done.`);
|
|
|
303
607
|
});
|
|
304
608
|
});
|
|
305
609
|
};
|
|
306
|
-
var
|
|
610
|
+
var assertOptionsValid4 = (options) => {
|
|
307
611
|
const { localCore, https, deploy: deploy2, env, profile } = options;
|
|
308
612
|
const { ifCore } = getIfCoreFns();
|
|
309
613
|
if (ifCore() && localCore) {
|
|
@@ -339,7 +643,7 @@ var prepareFlags2 = (options) => {
|
|
|
339
643
|
};
|
|
340
644
|
|
|
341
645
|
// src/commands/deploy.ts
|
|
342
|
-
import { existsSync as
|
|
646
|
+
import { existsSync as existsSync3 } from "fs";
|
|
343
647
|
import stripIndent4 from "strip-indent";
|
|
344
648
|
var deploy = async (options) => {
|
|
345
649
|
const { ifCore } = getIfCoreFns();
|
|
@@ -349,7 +653,7 @@ var deploy = async (options) => {
|
|
|
349
653
|
assertProfilesPresent();
|
|
350
654
|
options.profile = await promptProfile();
|
|
351
655
|
}
|
|
352
|
-
|
|
656
|
+
assertOptionsValid5(options);
|
|
353
657
|
await validate();
|
|
354
658
|
awsAuthenticate(options);
|
|
355
659
|
const flags = prepareFlags(options);
|
|
@@ -423,7 +727,7 @@ Bundle for "${configName}" is deployed with tag "${tag}".`);
|
|
|
423
727
|
});
|
|
424
728
|
});
|
|
425
729
|
};
|
|
426
|
-
var
|
|
730
|
+
var assertOptionsValid5 = (options) => {
|
|
427
731
|
const { profile, tag } = options;
|
|
428
732
|
if (profile) {
|
|
429
733
|
assertProfileValid(profile);
|
|
@@ -431,7 +735,7 @@ var assertOptionsValid2 = (options) => {
|
|
|
431
735
|
assertTagValid(tag);
|
|
432
736
|
};
|
|
433
737
|
var assertDistPathExists = (distPath) => {
|
|
434
|
-
if (!
|
|
738
|
+
if (!existsSync3(distPath)) {
|
|
435
739
|
halt(
|
|
436
740
|
stripIndent4(`
|
|
437
741
|
Dist folder does not exists.
|
|
@@ -440,32 +744,24 @@ var assertDistPathExists = (distPath) => {
|
|
|
440
744
|
);
|
|
441
745
|
}
|
|
442
746
|
};
|
|
443
|
-
var assertTagValid = (tag) => {
|
|
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
|
-
}
|
|
450
|
-
};
|
|
451
747
|
|
|
452
748
|
// src/commands/deploy-email-config.ts
|
|
453
|
-
import { existsSync as
|
|
454
|
-
import
|
|
749
|
+
import { existsSync as existsSync4 } from "fs";
|
|
750
|
+
import prompts3 from "prompts";
|
|
455
751
|
var deployEmailConfig = async (options) => {
|
|
456
752
|
const { ifCore } = getIfCoreFns();
|
|
457
753
|
const paths = getPaths(ifCore);
|
|
458
754
|
const emailConfigPath = `${paths.app}/email-config`;
|
|
459
|
-
|
|
755
|
+
assertIsNotCore3();
|
|
460
756
|
assertEmailConfigPathExists(emailConfigPath);
|
|
461
757
|
if (!options.profile && !options.ci) {
|
|
462
758
|
assertProfilesPresent();
|
|
463
759
|
options.profile = await promptProfile();
|
|
464
760
|
}
|
|
465
761
|
if (!options.bucket) {
|
|
466
|
-
options.bucket = options.ci ? AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD : await
|
|
762
|
+
options.bucket = options.ci ? AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD : await promptBucketTamaroEmailConfig2();
|
|
467
763
|
}
|
|
468
|
-
|
|
764
|
+
assertOptionsValid6(options);
|
|
469
765
|
await validate();
|
|
470
766
|
awsAuthenticate(options);
|
|
471
767
|
const flags = prepareFlags(options);
|
|
@@ -502,27 +798,27 @@ var deployEmailConfig = async (options) => {
|
|
|
502
798
|
});
|
|
503
799
|
});
|
|
504
800
|
};
|
|
505
|
-
var
|
|
801
|
+
var assertOptionsValid6 = (options) => {
|
|
506
802
|
const { profile, bucket } = options;
|
|
507
803
|
if (profile) {
|
|
508
804
|
assertProfileValid(profile);
|
|
509
805
|
}
|
|
510
806
|
if (bucket) {
|
|
511
|
-
|
|
807
|
+
assertBucketValid2(bucket);
|
|
512
808
|
}
|
|
513
809
|
};
|
|
514
810
|
var assertEmailConfigPathExists = (distPath) => {
|
|
515
|
-
if (!
|
|
811
|
+
if (!existsSync4(distPath)) {
|
|
516
812
|
halt("Email config folder does not exists. Nothing to deploy.");
|
|
517
813
|
}
|
|
518
814
|
};
|
|
519
|
-
var
|
|
815
|
+
var assertIsNotCore3 = () => {
|
|
520
816
|
const { ifCore } = getIfCoreFns();
|
|
521
817
|
if (ifCore()) {
|
|
522
818
|
halt("You cannot deploy widget email configuration for Tamaro Core.");
|
|
523
819
|
}
|
|
524
820
|
};
|
|
525
|
-
var
|
|
821
|
+
var assertBucketValid2 = (bucket) => {
|
|
526
822
|
const buckets = [
|
|
527
823
|
AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_STAGE,
|
|
528
824
|
AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD
|
|
@@ -531,12 +827,12 @@ var assertBucketValid = (bucket) => {
|
|
|
531
827
|
halt("Invalid bucket name.");
|
|
532
828
|
}
|
|
533
829
|
};
|
|
534
|
-
var
|
|
830
|
+
var promptBucketTamaroEmailConfig2 = async () => {
|
|
535
831
|
const buckets = [
|
|
536
832
|
{ title: "stage", value: AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_STAGE },
|
|
537
833
|
{ title: "prod", value: AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD }
|
|
538
834
|
];
|
|
539
|
-
const { bucket } = await
|
|
835
|
+
const { bucket } = await prompts3(
|
|
540
836
|
[
|
|
541
837
|
{
|
|
542
838
|
type: "select",
|
|
@@ -557,7 +853,7 @@ import { getPortPromise } from "portfinder";
|
|
|
557
853
|
var dev = async (options) => {
|
|
558
854
|
const { env } = options;
|
|
559
855
|
applyEnv(env);
|
|
560
|
-
|
|
856
|
+
assertOptionsValid7(options);
|
|
561
857
|
const flags = await prepareFlags3(options);
|
|
562
858
|
const { ifCore } = getIfCoreFns();
|
|
563
859
|
const title = ifCore(
|
|
@@ -575,7 +871,7 @@ var dev = async (options) => {
|
|
|
575
871
|
logCommand(cmd);
|
|
576
872
|
runCommandSync(cmd, { stdio: "inherit" });
|
|
577
873
|
};
|
|
578
|
-
var
|
|
874
|
+
var assertOptionsValid7 = (options) => {
|
|
579
875
|
const { localCore, https, port, env } = options;
|
|
580
876
|
const { ifCore } = getIfCoreFns();
|
|
581
877
|
if (ifCore() && localCore) {
|
|
@@ -612,7 +908,7 @@ var listDeployed = async (options) => {
|
|
|
612
908
|
assertProfilesPresent();
|
|
613
909
|
options.profile = await promptProfile();
|
|
614
910
|
}
|
|
615
|
-
|
|
911
|
+
assertOptionsValid8(options);
|
|
616
912
|
awsAuthenticate(options);
|
|
617
913
|
const flags = prepareFlags(options);
|
|
618
914
|
const { config } = options;
|
|
@@ -646,7 +942,7 @@ var listDeployed = async (options) => {
|
|
|
646
942
|
console.log(`${text}
|
|
647
943
|
`);
|
|
648
944
|
};
|
|
649
|
-
var
|
|
945
|
+
var assertOptionsValid8 = (options) => {
|
|
650
946
|
const { config, profile } = options;
|
|
651
947
|
assertConfigValid(config);
|
|
652
948
|
if (profile) {
|
|
@@ -670,10 +966,10 @@ var parseTags = (lines) => {
|
|
|
670
966
|
};
|
|
671
967
|
|
|
672
968
|
// src/commands/serve.ts
|
|
673
|
-
import { resolve as
|
|
969
|
+
import { resolve as resolve3 } from "path";
|
|
674
970
|
import { getPortPromise as getPortPromise2 } from "portfinder";
|
|
675
971
|
var serve = async (options) => {
|
|
676
|
-
|
|
972
|
+
assertOptionsValid9(options);
|
|
677
973
|
const flags = await prepareFlags4(options);
|
|
678
974
|
const { ifCore } = getIfCoreFns();
|
|
679
975
|
const paths = getPaths(ifCore);
|
|
@@ -686,7 +982,7 @@ var serve = async (options) => {
|
|
|
686
982
|
logCommand(cmd);
|
|
687
983
|
runCommandSync(cmd, { stdio: "inherit" });
|
|
688
984
|
};
|
|
689
|
-
var
|
|
985
|
+
var assertOptionsValid9 = (options) => {
|
|
690
986
|
const { port, https } = options;
|
|
691
987
|
if (isNaN(Number(port))) {
|
|
692
988
|
halt('Flag "--port" should be a number.');
|
|
@@ -703,28 +999,138 @@ var prepareFlags4 = async (options) => {
|
|
|
703
999
|
if (https) {
|
|
704
1000
|
const { ifCore } = getIfCoreFns();
|
|
705
1001
|
const paths = getPaths(ifCore);
|
|
706
|
-
const certFile =
|
|
707
|
-
const keyFile =
|
|
1002
|
+
const certFile = resolve3(paths.root, HTTPS_CRT_FILE);
|
|
1003
|
+
const keyFile = resolve3(paths.root, HTTPS_KEY_FILE);
|
|
708
1004
|
flags.push(`--ssl-cert ${certFile}`);
|
|
709
1005
|
flags.push(`--ssl-key ${keyFile}`);
|
|
710
1006
|
}
|
|
711
1007
|
return flags.join(" ");
|
|
712
1008
|
};
|
|
713
1009
|
|
|
1010
|
+
// src/commands/unarchive.ts
|
|
1011
|
+
import { existsSync as existsSync5, renameSync as renameSync2 } from "fs";
|
|
1012
|
+
import { basename as basename2, dirname as dirname2, resolve as resolve4 } from "path";
|
|
1013
|
+
var unarchive = async (options) => {
|
|
1014
|
+
const { ifCore } = getIfCoreFns({ allowArchived: true });
|
|
1015
|
+
assertIsNotCore4(ifCore);
|
|
1016
|
+
assertIsArchived();
|
|
1017
|
+
const configName = getWidgetUuid();
|
|
1018
|
+
const cwd = process.cwd();
|
|
1019
|
+
const archivedDir = dirname2(cwd);
|
|
1020
|
+
const configsDir = dirname2(archivedDir);
|
|
1021
|
+
const restoreTarget = resolve4(configsDir, configName);
|
|
1022
|
+
assertRestoreTargetDoesNotExist(restoreTarget);
|
|
1023
|
+
if (!options.profile && !options.ci) {
|
|
1024
|
+
assertProfilesPresent();
|
|
1025
|
+
options.profile = await promptProfile();
|
|
1026
|
+
}
|
|
1027
|
+
assertOptionsValid10(options);
|
|
1028
|
+
await promptConfirmation(
|
|
1029
|
+
`Are you sure you want to unarchive "${configName}"? This will restore, build, and deploy the configuration.`,
|
|
1030
|
+
options.yes
|
|
1031
|
+
);
|
|
1032
|
+
if (options.dryrun) {
|
|
1033
|
+
logTitle("\u{1F9EA} DRY RUN MODE - No actual changes will be made \u{1F9EA}");
|
|
1034
|
+
}
|
|
1035
|
+
logTitle(`
|
|
1036
|
+
Unarchiving "${configName}" \u2026`);
|
|
1037
|
+
if (!options.dryrun) {
|
|
1038
|
+
renameSync2(cwd, restoreTarget);
|
|
1039
|
+
process.chdir(restoreTarget);
|
|
1040
|
+
logTitle(`Moved to ${restoreTarget}`);
|
|
1041
|
+
} else {
|
|
1042
|
+
logTitle(`Would move ${cwd} \u2192 ${restoreTarget}`);
|
|
1043
|
+
}
|
|
1044
|
+
if (!options.dryrun) {
|
|
1045
|
+
logTitle(`
|
|
1046
|
+
Building "${configName}" \u2026`);
|
|
1047
|
+
await build({
|
|
1048
|
+
localCore: false,
|
|
1049
|
+
analyze: false,
|
|
1050
|
+
https: false,
|
|
1051
|
+
serve: false,
|
|
1052
|
+
deploy: false,
|
|
1053
|
+
nolint: false,
|
|
1054
|
+
tag: DEFAULT_TAG,
|
|
1055
|
+
profile: options.profile,
|
|
1056
|
+
ci: options.ci,
|
|
1057
|
+
dryrun: options.dryrun
|
|
1058
|
+
});
|
|
1059
|
+
logSuccess(`
|
|
1060
|
+
\u2705 Built "${configName}" \u2026`);
|
|
1061
|
+
logTitle(`
|
|
1062
|
+
Deploying "${configName}" to tag "${DEFAULT_TAG}" \u2026`);
|
|
1063
|
+
await deploy({
|
|
1064
|
+
tag: DEFAULT_TAG,
|
|
1065
|
+
profile: options.profile,
|
|
1066
|
+
ci: options.ci,
|
|
1067
|
+
dryrun: options.dryrun
|
|
1068
|
+
});
|
|
1069
|
+
logSuccess(`
|
|
1070
|
+
\u2705 Deployed "${configName}" to tag "${DEFAULT_TAG}" \u2026`);
|
|
1071
|
+
logTitle(`
|
|
1072
|
+
Deploying email configuration for "${configName}" \u2026`);
|
|
1073
|
+
await deployEmailConfig({
|
|
1074
|
+
profile: options.profile,
|
|
1075
|
+
ci: options.ci,
|
|
1076
|
+
dryrun: options.dryrun,
|
|
1077
|
+
bucket: AWS_S3_BUCKET_TAMARO_EMAIL_CONFIG_PROD
|
|
1078
|
+
});
|
|
1079
|
+
logSuccess(`
|
|
1080
|
+
\u2705 Deployed email configuration for "${configName}" \u2026`);
|
|
1081
|
+
} else {
|
|
1082
|
+
logTitle('Would build, deploy to "latest", and deploy email configuration.');
|
|
1083
|
+
}
|
|
1084
|
+
logSuccess(`
|
|
1085
|
+
\u2705 "${configName}" has been unarchived and deployed.`);
|
|
1086
|
+
process.on("exit", () => {
|
|
1087
|
+
notify({
|
|
1088
|
+
title: "unarchive",
|
|
1089
|
+
message: `"${configName}" has been unarchived and deployed.`
|
|
1090
|
+
});
|
|
1091
|
+
});
|
|
1092
|
+
};
|
|
1093
|
+
var assertOptionsValid10 = (options) => {
|
|
1094
|
+
const { profile } = options;
|
|
1095
|
+
if (profile) {
|
|
1096
|
+
assertProfileValid(profile);
|
|
1097
|
+
}
|
|
1098
|
+
};
|
|
1099
|
+
var assertIsArchived = () => {
|
|
1100
|
+
const parentDirName = basename2(dirname2(process.cwd()));
|
|
1101
|
+
if (parentDirName !== "_archived") {
|
|
1102
|
+
halt(
|
|
1103
|
+
"This configuration is not archived. Only archived configurations can be unarchived."
|
|
1104
|
+
);
|
|
1105
|
+
}
|
|
1106
|
+
};
|
|
1107
|
+
var assertIsNotCore4 = (ifCore) => {
|
|
1108
|
+
if (ifCore()) {
|
|
1109
|
+
halt("You cannot unarchive Tamaro Core.");
|
|
1110
|
+
}
|
|
1111
|
+
};
|
|
1112
|
+
var assertRestoreTargetDoesNotExist = (restoreTarget) => {
|
|
1113
|
+
if (existsSync5(restoreTarget)) {
|
|
1114
|
+
halt(
|
|
1115
|
+
`Restore target already exists: ${restoreTarget}. Please remove it first.`
|
|
1116
|
+
);
|
|
1117
|
+
}
|
|
1118
|
+
};
|
|
1119
|
+
|
|
714
1120
|
// package.json
|
|
715
1121
|
var package_default = {
|
|
716
1122
|
name: "@raisenow/tamaro-cli",
|
|
717
|
-
version: "1.
|
|
1123
|
+
version: "1.6.0-beta.0",
|
|
718
1124
|
author: {
|
|
719
1125
|
name: "RaiseNow",
|
|
720
1126
|
email: "development@raisenow.com"
|
|
721
1127
|
},
|
|
722
1128
|
type: "module",
|
|
723
1129
|
bin: "dist/cli.js",
|
|
724
|
-
packageManager: "pnpm@10.
|
|
1130
|
+
packageManager: "pnpm@10.28.2",
|
|
725
1131
|
engines: {
|
|
726
|
-
node: ">=22",
|
|
727
|
-
pnpm: ">=10",
|
|
1132
|
+
node: ">=22.22.0",
|
|
1133
|
+
pnpm: ">=10.28.2",
|
|
728
1134
|
npm: "please-use-pnpm",
|
|
729
1135
|
yarn: "please-use-pnpm"
|
|
730
1136
|
},
|
|
@@ -733,6 +1139,7 @@ var package_default = {
|
|
|
733
1139
|
typecheck: "tsc --noEmit",
|
|
734
1140
|
build: "tsup src/cli.ts src/webpack.config.ts --clean --shims --format esm",
|
|
735
1141
|
"build:watch": "pnpm build --watch --ignore-watch .history --ignore-watch .idea",
|
|
1142
|
+
dev: "pnpm build:watch",
|
|
736
1143
|
readme: "pnpx http-server . --cors -o /readme.html",
|
|
737
1144
|
lint: "DEBUG=eslint:cli-engine eslint .",
|
|
738
1145
|
"lint:fix": "DEBUG=eslint:cli-engine eslint --fix .",
|
|
@@ -742,62 +1149,62 @@ var package_default = {
|
|
|
742
1149
|
"test:coverage": "vitest --coverage"
|
|
743
1150
|
},
|
|
744
1151
|
dependencies: {
|
|
745
|
-
"@babel/cli": "^7.28.
|
|
746
|
-
"@babel/core": "^7.
|
|
747
|
-
"@babel/plugin-proposal-decorators": "^7.
|
|
1152
|
+
"@babel/cli": "^7.28.6",
|
|
1153
|
+
"@babel/core": "^7.29.0",
|
|
1154
|
+
"@babel/plugin-proposal-decorators": "^7.29.0",
|
|
748
1155
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
749
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
750
|
-
"@babel/preset-env": "^7.
|
|
751
|
-
"@babel/preset-react": "^7.
|
|
752
|
-
"@babel/preset-typescript": "^7.
|
|
753
|
-
"@babel/runtime-corejs3": "^7.
|
|
754
|
-
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.
|
|
1156
|
+
"@babel/plugin-transform-runtime": "^7.29.0",
|
|
1157
|
+
"@babel/preset-env": "^7.29.0",
|
|
1158
|
+
"@babel/preset-react": "^7.28.5",
|
|
1159
|
+
"@babel/preset-typescript": "^7.28.5",
|
|
1160
|
+
"@babel/runtime-corejs3": "^7.29.0",
|
|
1161
|
+
"@pmmmwh/react-refresh-webpack-plugin": "^0.6.2",
|
|
755
1162
|
"@statoscope/webpack-plugin": "^5.29.0",
|
|
756
1163
|
"@types/columnify": "^1.5.4",
|
|
757
1164
|
"@types/handlebars-helpers": "^0.5.6",
|
|
758
|
-
"@types/lodash": "^4.17.
|
|
759
|
-
"@types/node": "^22.
|
|
1165
|
+
"@types/lodash": "^4.17.23",
|
|
1166
|
+
"@types/node": "^22.19.8",
|
|
760
1167
|
"@types/node-notifier": "^8.0.5",
|
|
761
1168
|
"@types/prompts": "^2.4.9",
|
|
762
1169
|
"@types/resolve-bin": "^0.4.3",
|
|
763
1170
|
"@types/webpack-config-utils": "^2.3.4",
|
|
764
1171
|
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
765
1172
|
"@typescript-eslint/parser": "^7.18.0",
|
|
766
|
-
autoprefixer: "^10.4.
|
|
1173
|
+
autoprefixer: "^10.4.24",
|
|
767
1174
|
"babel-loader": "^10.0.0",
|
|
768
1175
|
"babel-plugin-istanbul": "^7.0.1",
|
|
769
1176
|
"babel-plugin-lodash": "^3.3.4",
|
|
770
1177
|
chalk: "^5.6.2",
|
|
771
1178
|
"clean-webpack-plugin": "^4.0.0",
|
|
772
1179
|
columnify: "^1.6.0",
|
|
773
|
-
commander: "^14.0.
|
|
1180
|
+
commander: "^14.0.3",
|
|
774
1181
|
"copy-webpack-plugin": "^13.0.1",
|
|
775
|
-
"core-js": "^3.
|
|
776
|
-
"css-loader": "^7.1.
|
|
777
|
-
"css-minimizer-webpack-plugin": "^7.0.
|
|
778
|
-
dotenv: "^17.2.
|
|
1182
|
+
"core-js": "^3.48.0",
|
|
1183
|
+
"css-loader": "^7.1.3",
|
|
1184
|
+
"css-minimizer-webpack-plugin": "^7.0.4",
|
|
1185
|
+
dotenv: "^17.2.3",
|
|
779
1186
|
"escape-string-regexp": "^5.0.0",
|
|
780
1187
|
eslint: "^8.57.1",
|
|
781
1188
|
"eslint-config-prettier": "^10.1.8",
|
|
782
|
-
"eslint-import-resolver-typescript": "^3.
|
|
1189
|
+
"eslint-import-resolver-typescript": "^3.10.1",
|
|
783
1190
|
"eslint-plugin-deprecation": "^3.0.0",
|
|
784
1191
|
"eslint-plugin-import": "^2.32.0",
|
|
785
1192
|
"eslint-plugin-markdownlint": "^0.9.0",
|
|
786
1193
|
"eslint-plugin-promise": "^7.2.1",
|
|
787
1194
|
"eslint-plugin-unused-imports": "^3.2.0",
|
|
788
|
-
"eslint-plugin-yml": "^1.
|
|
1195
|
+
"eslint-plugin-yml": "^1.19.1",
|
|
789
1196
|
"eslint-webpack-plugin": "^5.0.2",
|
|
790
|
-
execa: "^9.6.
|
|
1197
|
+
execa: "^9.6.1",
|
|
791
1198
|
"file-loader": "^6.2.0",
|
|
792
1199
|
"fork-ts-checker-webpack-plugin": "^9.1.0",
|
|
793
|
-
glob: "^
|
|
1200
|
+
glob: "^13.0.1",
|
|
794
1201
|
handlebars: "^4.7.8",
|
|
795
1202
|
"handlebars-helpers": "^0.10.0",
|
|
796
1203
|
"html-loader": "^5.1.0",
|
|
797
|
-
"html-webpack-plugin": "^5.6.
|
|
1204
|
+
"html-webpack-plugin": "^5.6.6",
|
|
798
1205
|
"json-loader": "^0.5.7",
|
|
799
|
-
lodash: "^4.17.
|
|
800
|
-
"mini-css-extract-plugin": "^2.
|
|
1206
|
+
lodash: "^4.17.23",
|
|
1207
|
+
"mini-css-extract-plugin": "^2.10.0",
|
|
801
1208
|
"node-notifier": "^10.0.1",
|
|
802
1209
|
portfinder: "^1.0.38",
|
|
803
1210
|
postcss: "^8.5.6",
|
|
@@ -805,25 +1212,25 @@ var package_default = {
|
|
|
805
1212
|
"postcss-import": "^16.1.1",
|
|
806
1213
|
"postcss-loader": "^8.2.0",
|
|
807
1214
|
"postcss-nested": "^7.0.2",
|
|
808
|
-
prettier: "^3.
|
|
1215
|
+
prettier: "^3.8.1",
|
|
809
1216
|
prompts: "^2.4.2",
|
|
810
|
-
"react-refresh": "^0.
|
|
1217
|
+
"react-refresh": "^0.18.0",
|
|
811
1218
|
"resolve-url-loader": "^5.0.0",
|
|
812
|
-
sass: "^1.
|
|
813
|
-
"sass-loader": "^16.0.
|
|
814
|
-
"strip-indent": "^4.1.
|
|
1219
|
+
sass: "^1.97.3",
|
|
1220
|
+
"sass-loader": "^16.0.6",
|
|
1221
|
+
"strip-indent": "^4.1.1",
|
|
815
1222
|
"style-loader": "^4.0.0",
|
|
816
|
-
"terser-webpack-plugin": "^5.3.
|
|
1223
|
+
"terser-webpack-plugin": "^5.3.16",
|
|
817
1224
|
"tsconfig-paths-webpack-plugin": "^4.2.0",
|
|
818
|
-
tsup: "^8.5.
|
|
819
|
-
typescript: "^5.9.
|
|
1225
|
+
tsup: "^8.5.1",
|
|
1226
|
+
typescript: "^5.9.3",
|
|
820
1227
|
"url-loader": "^4.1.1",
|
|
821
|
-
vitest: "^
|
|
822
|
-
webpack: "^5.
|
|
1228
|
+
vitest: "^4.0.18",
|
|
1229
|
+
webpack: "^5.105.0",
|
|
823
1230
|
"webpack-cli": "^6.0.1",
|
|
824
1231
|
"webpack-config-utils": "^2.3.1",
|
|
825
|
-
"webpack-dev-server": "^5.2.
|
|
826
|
-
"yaml-loader": "^0.
|
|
1232
|
+
"webpack-dev-server": "^5.2.3",
|
|
1233
|
+
"yaml-loader": "^0.9.0"
|
|
827
1234
|
}
|
|
828
1235
|
};
|
|
829
1236
|
|
|
@@ -910,6 +1317,44 @@ cli.command("deploy-email-config").description("Deploy a widget's email configur
|
|
|
910
1317
|
).action(async (options) => {
|
|
911
1318
|
await deployEmailConfig(options);
|
|
912
1319
|
});
|
|
1320
|
+
cli.command("undeploy").description(
|
|
1321
|
+
"Undeploy a Tamaro Core or customer configuration bundle from AWS S3"
|
|
1322
|
+
).option("--profile <profile>", "AWS profile").option("--ci", "CI environment", false).option(
|
|
1323
|
+
"--tag <tag>",
|
|
1324
|
+
"Tag which should be undeployed",
|
|
1325
|
+
DEFAULT_TAG
|
|
1326
|
+
).option("--all", "Undeploy all tags", false).option(
|
|
1327
|
+
"--dryrun",
|
|
1328
|
+
"Displays the operations that would be performed without actually running them",
|
|
1329
|
+
false
|
|
1330
|
+
).option("-y, --yes", "Skip confirmation prompt", false).action(async (options) => {
|
|
1331
|
+
await undeploy(options);
|
|
1332
|
+
});
|
|
1333
|
+
cli.command("undeploy-email-config").description("Undeploy a widget's email configuration from AWS S3").option("--profile <profile>", "AWS profile").option("--ci", "CI environment", false).option("--bucket <bucket>", "AWS bucket for email configs").option(
|
|
1334
|
+
"--dryrun",
|
|
1335
|
+
"Displays the operations that would be performed without actually running them",
|
|
1336
|
+
false
|
|
1337
|
+
).option("-y, --yes", "Skip confirmation prompt", false).action(async (options) => {
|
|
1338
|
+
await undeployEmailConfig(options);
|
|
1339
|
+
});
|
|
1340
|
+
cli.command("archive").description(
|
|
1341
|
+
"Archive a customer configuration: moves to _archived folder and undeploys all tags and email configurations"
|
|
1342
|
+
).option("--profile <profile>", "AWS profile").option("--ci", "CI environment", false).option(
|
|
1343
|
+
"--dryrun",
|
|
1344
|
+
"Displays the operations that would be performed without actually running them",
|
|
1345
|
+
false
|
|
1346
|
+
).option("-y, --yes", "Skip confirmation prompt", false).action(async (options) => {
|
|
1347
|
+
await archive(options);
|
|
1348
|
+
});
|
|
1349
|
+
cli.command("unarchive").description(
|
|
1350
|
+
"Unarchive a customer configuration: restores from _archived folder, builds and deploys"
|
|
1351
|
+
).option("--profile <profile>", "AWS profile").option("--ci", "CI environment", false).option(
|
|
1352
|
+
"--dryrun",
|
|
1353
|
+
"Displays the operations that would be performed without actually running them",
|
|
1354
|
+
false
|
|
1355
|
+
).option("-y, --yes", "Skip confirmation prompt", false).action(async (options) => {
|
|
1356
|
+
await unarchive(options);
|
|
1357
|
+
});
|
|
913
1358
|
cli.command("validate").description(
|
|
914
1359
|
"Validate the current Tamaro configuration to avoid common errors"
|
|
915
1360
|
).action(async () => {
|