@awsless/awsless 0.0.44 → 0.0.46
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/README.MD +1 -0
- package/dist/bin.js +1142 -447
- package/dist/features/delete-bucket.js +86 -0
- package/dist/features/delete-hosted-zone.js +127 -0
- package/dist/features/global-exports.js +61 -0
- package/dist/features/upload-bucket-asset.js +28384 -0
- package/dist/index.d.ts +734 -205
- package/package.json +14 -4
package/dist/bin.js
CHANGED
|
@@ -75,13 +75,20 @@ var sub = (value, params) => {
|
|
|
75
75
|
}
|
|
76
76
|
return { "Fn::Sub": value };
|
|
77
77
|
};
|
|
78
|
+
var split = (seperator, value) => {
|
|
79
|
+
return { "Fn::Split": [seperator, value] };
|
|
80
|
+
};
|
|
81
|
+
var select = (index, value) => {
|
|
82
|
+
return { "Fn::Select": [index, value] };
|
|
83
|
+
};
|
|
78
84
|
var getAtt = (logicalId, attr) => {
|
|
79
85
|
return { "Fn::GetAtt": [logicalId, attr] };
|
|
80
86
|
};
|
|
87
|
+
var lazy = (cb) => {
|
|
88
|
+
return new Lazy(cb);
|
|
89
|
+
};
|
|
81
90
|
var importValue = (name) => {
|
|
82
|
-
return
|
|
83
|
-
"Fn::ImportValue": `${stack.app.name}-${name}`
|
|
84
|
-
}));
|
|
91
|
+
return { "Fn::ImportValue": name };
|
|
85
92
|
};
|
|
86
93
|
var formatLogicalId = (id) => {
|
|
87
94
|
return pascalCase(id).replaceAll("_", "");
|
|
@@ -107,6 +114,10 @@ var Resource = class {
|
|
|
107
114
|
tags = /* @__PURE__ */ new Map();
|
|
108
115
|
deps = /* @__PURE__ */ new Set();
|
|
109
116
|
stack;
|
|
117
|
+
addChild(...children) {
|
|
118
|
+
this.children.push(...children);
|
|
119
|
+
return this;
|
|
120
|
+
}
|
|
110
121
|
dependsOn(...dependencies) {
|
|
111
122
|
for (const dependency of dependencies) {
|
|
112
123
|
this.deps.add(dependency);
|
|
@@ -175,6 +186,25 @@ var Lazy = class {
|
|
|
175
186
|
}
|
|
176
187
|
};
|
|
177
188
|
|
|
189
|
+
// src/formation/resource/cloud-watch/log-group.ts
|
|
190
|
+
var LogGroup = class extends Resource {
|
|
191
|
+
constructor(logicalId, props) {
|
|
192
|
+
super("AWS::Logs::LogGroup", logicalId);
|
|
193
|
+
this.props = props;
|
|
194
|
+
}
|
|
195
|
+
get arn() {
|
|
196
|
+
return getAtt(this.logicalId, "Arn");
|
|
197
|
+
}
|
|
198
|
+
properties() {
|
|
199
|
+
return {
|
|
200
|
+
LogGroupName: this.props.name,
|
|
201
|
+
...this.attr("RetentionInDays", this.props.retention?.toDays())
|
|
202
|
+
// KmsKeyId: String
|
|
203
|
+
// DataProtectionPolicy : Json,
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
178
208
|
// src/formation/resource/iam/inline-policy.ts
|
|
179
209
|
var InlinePolicy = class {
|
|
180
210
|
name;
|
|
@@ -202,20 +232,6 @@ var InlinePolicy = class {
|
|
|
202
232
|
}
|
|
203
233
|
};
|
|
204
234
|
|
|
205
|
-
// src/formation/resource/iam/managed-policy.ts
|
|
206
|
-
var ManagedPolicy = class {
|
|
207
|
-
constructor(arn) {
|
|
208
|
-
this.arn = arn;
|
|
209
|
-
}
|
|
210
|
-
static fromAwsManagedPolicyName(name) {
|
|
211
|
-
const arn = sub("arn:${AWS::Partition}:iam::aws:policy/service-role/" + name);
|
|
212
|
-
return new ManagedPolicy(arn);
|
|
213
|
-
}
|
|
214
|
-
static fromManagedPolicyArn(arn) {
|
|
215
|
-
return new ManagedPolicy(arn);
|
|
216
|
-
}
|
|
217
|
-
};
|
|
218
|
-
|
|
219
235
|
// src/formation/resource/iam/role.ts
|
|
220
236
|
var Role = class extends Resource {
|
|
221
237
|
constructor(logicalId, props = {}) {
|
|
@@ -259,16 +275,44 @@ var Role = class extends Resource {
|
|
|
259
275
|
}
|
|
260
276
|
};
|
|
261
277
|
|
|
278
|
+
// src/formation/resource/lambda/url.ts
|
|
279
|
+
import { constantCase } from "change-case";
|
|
280
|
+
var Url = class extends Resource {
|
|
281
|
+
constructor(logicalId, props) {
|
|
282
|
+
super("AWS::Lambda::Url", logicalId);
|
|
283
|
+
this.props = props;
|
|
284
|
+
}
|
|
285
|
+
get url() {
|
|
286
|
+
return getAtt(this.logicalId, "FunctionUrl");
|
|
287
|
+
}
|
|
288
|
+
properties() {
|
|
289
|
+
return {
|
|
290
|
+
AuthType: constantCase(this.props.authType ?? "none"),
|
|
291
|
+
InvokeMode: constantCase(this.props.invokeMode ?? "buffered"),
|
|
292
|
+
TargetFunctionArn: this.props.target,
|
|
293
|
+
...this.attr("Qualifier", this.props.qualifier),
|
|
294
|
+
Cors: {
|
|
295
|
+
...this.attr("AllowCredentials", this.props.cors?.allow?.credentials),
|
|
296
|
+
...this.attr("AllowHeaders", this.props.cors?.allow?.headers),
|
|
297
|
+
...this.attr("AllowMethods", this.props.cors?.allow?.methods),
|
|
298
|
+
...this.attr("AllowOrigins", this.props.cors?.allow?.origins),
|
|
299
|
+
...this.attr("ExposeHeaders", this.props.cors?.expose?.headers),
|
|
300
|
+
...this.attr("MaxAge", this.props.cors?.maxAge?.toSeconds())
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
|
|
262
306
|
// src/formation/resource/lambda/function.ts
|
|
263
307
|
var Function = class extends Resource {
|
|
264
|
-
constructor(
|
|
265
|
-
const policy = new InlinePolicy(
|
|
266
|
-
const role = new Role(
|
|
308
|
+
constructor(_logicalId, props) {
|
|
309
|
+
const policy = new InlinePolicy(_logicalId);
|
|
310
|
+
const role = new Role(_logicalId, {
|
|
267
311
|
assumedBy: "lambda.amazonaws.com"
|
|
268
312
|
});
|
|
269
313
|
role.addInlinePolicy(policy);
|
|
270
|
-
|
|
271
|
-
|
|
314
|
+
super("AWS::Lambda::Function", _logicalId, [role]);
|
|
315
|
+
this._logicalId = _logicalId;
|
|
272
316
|
this.props = props;
|
|
273
317
|
if (props.code instanceof Asset) {
|
|
274
318
|
this.children.push(props.code);
|
|
@@ -276,7 +320,7 @@ var Function = class extends Resource {
|
|
|
276
320
|
this.dependsOn(role);
|
|
277
321
|
this.role = role;
|
|
278
322
|
this.policy = policy;
|
|
279
|
-
this.name = formatName(this.props.name ||
|
|
323
|
+
this.name = formatName(this.props.name || _logicalId);
|
|
280
324
|
this.environmentVariables = props.environment ? { ...props.environment } : {};
|
|
281
325
|
this.tag("name", this.name);
|
|
282
326
|
}
|
|
@@ -284,6 +328,29 @@ var Function = class extends Resource {
|
|
|
284
328
|
role;
|
|
285
329
|
policy;
|
|
286
330
|
environmentVariables;
|
|
331
|
+
enableLogs(retention) {
|
|
332
|
+
const logGroup = new LogGroup(this._logicalId, {
|
|
333
|
+
name: sub("/aws/lambda/${name}", {
|
|
334
|
+
name: this.name
|
|
335
|
+
}),
|
|
336
|
+
retention
|
|
337
|
+
});
|
|
338
|
+
this.addChild(logGroup);
|
|
339
|
+
this.addPermissions({
|
|
340
|
+
actions: ["logs:CreateLogStream"],
|
|
341
|
+
resources: [logGroup.arn]
|
|
342
|
+
}, {
|
|
343
|
+
actions: ["logs:PutLogEvents"],
|
|
344
|
+
resources: [sub("${arn}:*", { arn: logGroup.arn })]
|
|
345
|
+
});
|
|
346
|
+
return this;
|
|
347
|
+
}
|
|
348
|
+
addUrl(props = {}) {
|
|
349
|
+
return new Url(this._logicalId, {
|
|
350
|
+
...props,
|
|
351
|
+
target: this.arn
|
|
352
|
+
}).dependsOn(this);
|
|
353
|
+
}
|
|
287
354
|
addPermissions(...permissions) {
|
|
288
355
|
this.policy.addStatement(...permissions);
|
|
289
356
|
return this;
|
|
@@ -392,7 +459,12 @@ var Stack = class {
|
|
|
392
459
|
if (!this.exports.has(name)) {
|
|
393
460
|
throw new Error(`Undefined export value: ${name}`);
|
|
394
461
|
}
|
|
395
|
-
return
|
|
462
|
+
return lazy((stack) => {
|
|
463
|
+
if (stack === this) {
|
|
464
|
+
return this.exports.get(name);
|
|
465
|
+
}
|
|
466
|
+
return importValue(`${stack.app?.name ?? "default"}-${name}`);
|
|
467
|
+
});
|
|
396
468
|
}
|
|
397
469
|
tag(name, value) {
|
|
398
470
|
this.tags.set(name, value);
|
|
@@ -413,32 +485,33 @@ var Stack = class {
|
|
|
413
485
|
toJSON() {
|
|
414
486
|
const resources = {};
|
|
415
487
|
const outputs = {};
|
|
416
|
-
const walk = (
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
walk(value);
|
|
488
|
+
const walk = (node) => {
|
|
489
|
+
if (node instanceof Lazy) {
|
|
490
|
+
return walk(node.callback(this));
|
|
491
|
+
}
|
|
492
|
+
if (Array.isArray(node)) {
|
|
493
|
+
return node.map(walk);
|
|
494
|
+
}
|
|
495
|
+
if (typeof node === "object" && node !== null) {
|
|
496
|
+
const object = {};
|
|
497
|
+
for (const [key, value] of Object.entries(node)) {
|
|
498
|
+
object[key] = walk(value);
|
|
427
499
|
}
|
|
500
|
+
return object;
|
|
428
501
|
}
|
|
502
|
+
return node;
|
|
429
503
|
};
|
|
430
504
|
for (const resource of this.resources) {
|
|
431
|
-
const json2 = resource.toJSON();
|
|
432
|
-
walk(json2);
|
|
505
|
+
const json2 = walk(resource.toJSON());
|
|
433
506
|
Object.assign(resources, json2);
|
|
434
507
|
}
|
|
435
|
-
for (
|
|
508
|
+
for (let [name, value] of this.exports.entries()) {
|
|
436
509
|
Object.assign(outputs, {
|
|
437
510
|
[formatLogicalId(name)]: {
|
|
438
511
|
Export: {
|
|
439
|
-
Name: `${this.app?.name
|
|
512
|
+
Name: `${this.app?.name ?? "default"}-${name}`
|
|
440
513
|
},
|
|
441
|
-
Value: value
|
|
514
|
+
Value: walk(value)
|
|
442
515
|
}
|
|
443
516
|
});
|
|
444
517
|
}
|
|
@@ -638,15 +711,15 @@ var durationMax = (max) => {
|
|
|
638
711
|
};
|
|
639
712
|
|
|
640
713
|
// src/schema/local-file.ts
|
|
641
|
-
import {
|
|
714
|
+
import { stat } from "fs/promises";
|
|
642
715
|
import { z as z3 } from "zod";
|
|
643
716
|
var LocalFileSchema = z3.string().refine(async (path) => {
|
|
644
717
|
try {
|
|
645
|
-
await
|
|
718
|
+
const s = await stat(path);
|
|
719
|
+
return s.isFile();
|
|
646
720
|
} catch (error) {
|
|
647
721
|
return false;
|
|
648
722
|
}
|
|
649
|
-
return true;
|
|
650
723
|
}, `File doesn't exist`);
|
|
651
724
|
|
|
652
725
|
// src/schema/resource-id.ts
|
|
@@ -730,49 +803,54 @@ import json from "@rollup/plugin-json";
|
|
|
730
803
|
import commonjs from "@rollup/plugin-commonjs";
|
|
731
804
|
import nodeResolve from "@rollup/plugin-node-resolve";
|
|
732
805
|
import { dirname } from "path";
|
|
733
|
-
var rollupBundle =
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
minify
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
806
|
+
var rollupBundle = ({ format: format2 = "esm", minify = true, handler = "index.default" } = {}) => {
|
|
807
|
+
return async (input) => {
|
|
808
|
+
const bundle = await rollup({
|
|
809
|
+
input,
|
|
810
|
+
external: (importee) => {
|
|
811
|
+
return importee.startsWith("@aws-sdk") || importee.startsWith("aws-sdk");
|
|
812
|
+
},
|
|
813
|
+
onwarn: (error) => {
|
|
814
|
+
debugError(error.message);
|
|
815
|
+
},
|
|
816
|
+
treeshake: {
|
|
817
|
+
moduleSideEffects: (id) => input === id
|
|
818
|
+
},
|
|
819
|
+
plugins: [
|
|
820
|
+
// @ts-ignore
|
|
821
|
+
commonjs({ sourceMap: true }),
|
|
822
|
+
// @ts-ignore
|
|
823
|
+
nodeResolve({ preferBuiltins: true }),
|
|
824
|
+
swc({
|
|
825
|
+
minify,
|
|
826
|
+
jsc: {
|
|
827
|
+
baseUrl: dirname(input),
|
|
828
|
+
minify: { sourceMap: true }
|
|
829
|
+
},
|
|
830
|
+
sourceMaps: true
|
|
831
|
+
}),
|
|
832
|
+
// @ts-ignore
|
|
833
|
+
json()
|
|
834
|
+
]
|
|
835
|
+
});
|
|
836
|
+
const result = await bundle.generate({
|
|
837
|
+
format: format2,
|
|
838
|
+
sourcemap: "hidden",
|
|
839
|
+
exports: "auto"
|
|
840
|
+
});
|
|
841
|
+
const output = result.output[0];
|
|
842
|
+
const code = Buffer.from(output.code, "utf8");
|
|
843
|
+
const map = output.map ? Buffer.from(output.map.toString(), "utf8") : void 0;
|
|
844
|
+
const hash = createHash("sha1").update(code).digest("hex");
|
|
845
|
+
return {
|
|
846
|
+
handler,
|
|
847
|
+
hash,
|
|
848
|
+
files: [{
|
|
849
|
+
name: format2 === "esm" ? "index.mjs" : "index.js",
|
|
850
|
+
code,
|
|
851
|
+
map
|
|
852
|
+
}]
|
|
853
|
+
};
|
|
776
854
|
};
|
|
777
855
|
};
|
|
778
856
|
|
|
@@ -793,6 +871,8 @@ var zipFiles = (files) => {
|
|
|
793
871
|
};
|
|
794
872
|
|
|
795
873
|
// src/formation/resource/lambda/code.ts
|
|
874
|
+
import { fileURLToPath } from "url";
|
|
875
|
+
import { join } from "path";
|
|
796
876
|
var Code = class {
|
|
797
877
|
static fromFile(id, file, bundler) {
|
|
798
878
|
return new FileCode(id, file, bundler);
|
|
@@ -800,6 +880,29 @@ var Code = class {
|
|
|
800
880
|
static fromInline(code, handler) {
|
|
801
881
|
return new InlineCode(code, handler);
|
|
802
882
|
}
|
|
883
|
+
static fromInlineFile(id, file, bundler) {
|
|
884
|
+
return new InlineFileCode(id, file, bundler);
|
|
885
|
+
}
|
|
886
|
+
// static fromZipFile(id:string, file:string, hash:string, handler?:string) {
|
|
887
|
+
// return new ZipFileCode(id, file, hash, handler)
|
|
888
|
+
// }
|
|
889
|
+
static fromFeature(id) {
|
|
890
|
+
const root2 = fileURLToPath(new URL(".", import.meta.url));
|
|
891
|
+
const file = join(root2, `features/${id}.js`);
|
|
892
|
+
return new FileCode(id, file, rollupBundle({
|
|
893
|
+
minify: false,
|
|
894
|
+
handler: "index.handler"
|
|
895
|
+
}));
|
|
896
|
+
}
|
|
897
|
+
static fromInlineFeature(id) {
|
|
898
|
+
const root2 = fileURLToPath(new URL(".", import.meta.url));
|
|
899
|
+
const file = join(root2, `features/${id}.js`);
|
|
900
|
+
return new InlineFileCode(id, file, rollupBundle({
|
|
901
|
+
format: "cjs",
|
|
902
|
+
minify: false,
|
|
903
|
+
handler: "index.handler"
|
|
904
|
+
}));
|
|
905
|
+
}
|
|
803
906
|
};
|
|
804
907
|
var InlineCode = class {
|
|
805
908
|
constructor(code, handler = "index.default") {
|
|
@@ -815,6 +918,36 @@ var InlineCode = class {
|
|
|
815
918
|
};
|
|
816
919
|
}
|
|
817
920
|
};
|
|
921
|
+
var InlineFileCode = class extends Asset {
|
|
922
|
+
constructor(id, file, bundler) {
|
|
923
|
+
super("function", id);
|
|
924
|
+
this.file = file;
|
|
925
|
+
this.bundler = bundler;
|
|
926
|
+
}
|
|
927
|
+
code;
|
|
928
|
+
handler;
|
|
929
|
+
async build({ write }) {
|
|
930
|
+
const bundler = this.bundler ?? rollupBundle();
|
|
931
|
+
const { hash, files: [file], handler } = await bundler(this.file);
|
|
932
|
+
await Promise.all([
|
|
933
|
+
write("HASH", hash),
|
|
934
|
+
write("file.js", file.code)
|
|
935
|
+
]);
|
|
936
|
+
this.handler = handler;
|
|
937
|
+
this.code = file.code.toString("utf8");
|
|
938
|
+
return {
|
|
939
|
+
size: formatByteSize(file.code.byteLength)
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
toCodeJson() {
|
|
943
|
+
return {
|
|
944
|
+
Handler: this.handler ?? "",
|
|
945
|
+
Code: {
|
|
946
|
+
ZipFile: this.code ?? ""
|
|
947
|
+
}
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
};
|
|
818
951
|
var FileCode = class extends Asset {
|
|
819
952
|
constructor(id, file, bundler) {
|
|
820
953
|
super("function", id);
|
|
@@ -826,7 +959,7 @@ var FileCode = class extends Asset {
|
|
|
826
959
|
bundle;
|
|
827
960
|
s3;
|
|
828
961
|
async build({ write }) {
|
|
829
|
-
const bundler = this.bundler ?? rollupBundle;
|
|
962
|
+
const bundler = this.bundler ?? rollupBundle();
|
|
830
963
|
const { hash, files, handler } = await bundler(this.file);
|
|
831
964
|
const bundle = await zipFiles(files);
|
|
832
965
|
await Promise.all([
|
|
@@ -915,24 +1048,24 @@ import { camelCase as camelCase2 } from "change-case";
|
|
|
915
1048
|
|
|
916
1049
|
// src/util/path.ts
|
|
917
1050
|
import { lstat } from "fs/promises";
|
|
918
|
-
import { join, normalize } from "path";
|
|
1051
|
+
import { join as join2, normalize } from "path";
|
|
919
1052
|
var root = process.cwd();
|
|
920
1053
|
var directories = {
|
|
921
1054
|
root,
|
|
922
1055
|
get output() {
|
|
923
|
-
return
|
|
1056
|
+
return join2(this.root, ".awsless");
|
|
924
1057
|
},
|
|
925
1058
|
get cache() {
|
|
926
|
-
return
|
|
1059
|
+
return join2(this.output, "cache");
|
|
927
1060
|
},
|
|
928
1061
|
get asset() {
|
|
929
|
-
return
|
|
1062
|
+
return join2(this.output, "asset");
|
|
930
1063
|
},
|
|
931
1064
|
get types() {
|
|
932
|
-
return
|
|
1065
|
+
return join2(this.output, "types");
|
|
933
1066
|
},
|
|
934
1067
|
get template() {
|
|
935
|
-
return
|
|
1068
|
+
return join2(this.output, "template");
|
|
936
1069
|
}
|
|
937
1070
|
};
|
|
938
1071
|
var setRoot = (path = root) => {
|
|
@@ -942,17 +1075,17 @@ var findRootDir = async (path, configFile, level = 5) => {
|
|
|
942
1075
|
if (!level) {
|
|
943
1076
|
throw new TypeError("No awsless project found");
|
|
944
1077
|
}
|
|
945
|
-
const file =
|
|
1078
|
+
const file = join2(path, configFile);
|
|
946
1079
|
const exists = await fileExist(file);
|
|
947
1080
|
if (exists) {
|
|
948
1081
|
return path;
|
|
949
1082
|
}
|
|
950
|
-
return findRootDir(normalize(
|
|
1083
|
+
return findRootDir(normalize(join2(path, "..")), configFile, level - 1);
|
|
951
1084
|
};
|
|
952
1085
|
var fileExist = async (file) => {
|
|
953
1086
|
try {
|
|
954
|
-
const
|
|
955
|
-
if (
|
|
1087
|
+
const stat3 = await lstat(file);
|
|
1088
|
+
if (stat3.isFile()) {
|
|
956
1089
|
return true;
|
|
957
1090
|
}
|
|
958
1091
|
} catch (error) {
|
|
@@ -965,8 +1098,8 @@ import { relative as relative2 } from "path";
|
|
|
965
1098
|
|
|
966
1099
|
// src/util/type-gen.ts
|
|
967
1100
|
import { mkdir, writeFile } from "fs/promises";
|
|
968
|
-
import { join as
|
|
969
|
-
import { camelCase, constantCase } from "change-case";
|
|
1101
|
+
import { join as join3, relative } from "path";
|
|
1102
|
+
import { camelCase, constantCase as constantCase2 } from "change-case";
|
|
970
1103
|
var generateResourceTypes = async (config) => {
|
|
971
1104
|
const plugins = [
|
|
972
1105
|
...defaultPlugins,
|
|
@@ -976,7 +1109,7 @@ var generateResourceTypes = async (config) => {
|
|
|
976
1109
|
for (const plugin of plugins) {
|
|
977
1110
|
const code = plugin.onTypeGen?.({ config });
|
|
978
1111
|
if (code) {
|
|
979
|
-
const file =
|
|
1112
|
+
const file = join3(directories.types, `${plugin.name}.d.ts`);
|
|
980
1113
|
files.push(relative(directories.root, file));
|
|
981
1114
|
await mkdir(directories.types, { recursive: true });
|
|
982
1115
|
await writeFile(file, code);
|
|
@@ -984,7 +1117,7 @@ var generateResourceTypes = async (config) => {
|
|
|
984
1117
|
}
|
|
985
1118
|
if (files.length) {
|
|
986
1119
|
const code = files.map((file) => `/// <reference path='${file}' />`).join("\n");
|
|
987
|
-
await writeFile(
|
|
1120
|
+
await writeFile(join3(directories.root, `awsless.d.ts`), code);
|
|
988
1121
|
}
|
|
989
1122
|
};
|
|
990
1123
|
var TypeGen = class {
|
|
@@ -1012,7 +1145,7 @@ var TypeGen = class {
|
|
|
1012
1145
|
}
|
|
1013
1146
|
addConst(name, type) {
|
|
1014
1147
|
if (type) {
|
|
1015
|
-
this.types.set(
|
|
1148
|
+
this.types.set(constantCase2(name), type);
|
|
1016
1149
|
}
|
|
1017
1150
|
return this;
|
|
1018
1151
|
}
|
|
@@ -1063,7 +1196,7 @@ var TypeObject = class {
|
|
|
1063
1196
|
}
|
|
1064
1197
|
addConst(name, type) {
|
|
1065
1198
|
if (type) {
|
|
1066
|
-
this.types.set(
|
|
1199
|
+
this.types.set(constantCase2(name), type);
|
|
1067
1200
|
}
|
|
1068
1201
|
return this;
|
|
1069
1202
|
}
|
|
@@ -1090,18 +1223,28 @@ var EnvironmentSchema = z6.record(z6.string(), z6.string()).optional();
|
|
|
1090
1223
|
var ArchitectureSchema = z6.enum(["x86_64", "arm64"]);
|
|
1091
1224
|
var RetryAttemptsSchema = z6.number().int().min(0).max(2);
|
|
1092
1225
|
var RuntimeSchema = z6.enum([
|
|
1093
|
-
"nodejs16.x",
|
|
1094
1226
|
"nodejs18.x"
|
|
1095
1227
|
]);
|
|
1228
|
+
var LogSchema = z6.union([
|
|
1229
|
+
z6.boolean(),
|
|
1230
|
+
DurationSchema.refine(durationMin(Duration.days(1)), "Minimum log retention is 1 day")
|
|
1231
|
+
]);
|
|
1096
1232
|
var FunctionSchema = z6.union([
|
|
1097
1233
|
LocalFileSchema,
|
|
1098
1234
|
z6.object({
|
|
1099
1235
|
/** The file path of the function code. */
|
|
1100
1236
|
file: LocalFileSchema,
|
|
1237
|
+
// /** */
|
|
1238
|
+
// handler: z.string().optional(),
|
|
1101
1239
|
/** Put the function inside your global VPC.
|
|
1102
1240
|
* @default false
|
|
1103
1241
|
*/
|
|
1104
1242
|
vpc: z6.boolean().optional(),
|
|
1243
|
+
/** Enable logging to a CloudWatch log group.
|
|
1244
|
+
* Providing a duration value will set the log retention time.
|
|
1245
|
+
* @default false
|
|
1246
|
+
*/
|
|
1247
|
+
log: LogSchema.optional(),
|
|
1105
1248
|
/** The amount of time that Lambda allows a function to run before stopping it.
|
|
1106
1249
|
* You can specify a size value from 1 second to 15 minutes.
|
|
1107
1250
|
* @default '10 seconds'
|
|
@@ -1158,6 +1301,10 @@ var schema = z6.object({
|
|
|
1158
1301
|
* @default false
|
|
1159
1302
|
*/
|
|
1160
1303
|
vpc: z6.boolean().default(false),
|
|
1304
|
+
/** Enable logging to a CloudWatch log group.
|
|
1305
|
+
* @default false
|
|
1306
|
+
*/
|
|
1307
|
+
log: LogSchema.default(false),
|
|
1161
1308
|
/** The amount of time that Lambda allows a function to run before stopping it.
|
|
1162
1309
|
* You can specify a size value from 1 second to 15 minutes.
|
|
1163
1310
|
* @default '10 seconds'
|
|
@@ -1270,22 +1417,26 @@ var functionPlugin = definePlugin({
|
|
|
1270
1417
|
var toLambdaFunction = (ctx, id, fileOrProps) => {
|
|
1271
1418
|
const config = ctx.config;
|
|
1272
1419
|
const stack = ctx.stack;
|
|
1420
|
+
const bootstrap2 = ctx.bootstrap;
|
|
1273
1421
|
const props = typeof fileOrProps === "string" ? { ...config.defaults?.function, file: fileOrProps } : { ...config.defaults?.function, ...fileOrProps };
|
|
1274
1422
|
const lambda = new Function(id, {
|
|
1275
|
-
name: `${config.name}
|
|
1423
|
+
name: `${config.name}-${stack.name}-${id}`,
|
|
1276
1424
|
code: Code.fromFile(id, props.file),
|
|
1277
1425
|
...props,
|
|
1278
1426
|
vpc: void 0
|
|
1279
1427
|
});
|
|
1280
1428
|
lambda.addEnvironment("APP", config.name).addEnvironment("STAGE", config.stage).addEnvironment("STACK", stack.name);
|
|
1429
|
+
if (props.log) {
|
|
1430
|
+
lambda.enableLogs(props.log instanceof Duration ? props.log : void 0);
|
|
1431
|
+
}
|
|
1281
1432
|
if (props.vpc) {
|
|
1282
1433
|
lambda.setVpc({
|
|
1283
1434
|
securityGroupIds: [
|
|
1284
|
-
|
|
1435
|
+
bootstrap2.import(`vpc-security-group-id`)
|
|
1285
1436
|
],
|
|
1286
1437
|
subnetIds: [
|
|
1287
|
-
|
|
1288
|
-
|
|
1438
|
+
bootstrap2.import(`public-subnet-1`),
|
|
1439
|
+
bootstrap2.import(`public-subnet-2`)
|
|
1289
1440
|
]
|
|
1290
1441
|
}).addPermissions({
|
|
1291
1442
|
actions: [
|
|
@@ -1298,9 +1449,6 @@ var toLambdaFunction = (ctx, id, fileOrProps) => {
|
|
|
1298
1449
|
resources: ["*"]
|
|
1299
1450
|
});
|
|
1300
1451
|
}
|
|
1301
|
-
if (props.runtime.startsWith("nodejs")) {
|
|
1302
|
-
lambda.addEnvironment("AWS_NODEJS_CONNECTION_REUSE_ENABLED", "1");
|
|
1303
|
-
}
|
|
1304
1452
|
ctx.bind((other) => {
|
|
1305
1453
|
other.addPermissions(lambda.permissions);
|
|
1306
1454
|
});
|
|
@@ -1340,6 +1488,7 @@ var Rule = class extends Resource {
|
|
|
1340
1488
|
};
|
|
1341
1489
|
|
|
1342
1490
|
// src/formation/resource/lambda/permission.ts
|
|
1491
|
+
import { constantCase as constantCase3 } from "change-case";
|
|
1343
1492
|
var Permission2 = class extends Resource {
|
|
1344
1493
|
constructor(logicalId, props) {
|
|
1345
1494
|
super("AWS::Lambda::Permission", logicalId);
|
|
@@ -1350,6 +1499,7 @@ var Permission2 = class extends Resource {
|
|
|
1350
1499
|
FunctionName: this.props.functionArn,
|
|
1351
1500
|
Action: this.props.action || "lambda:InvokeFunction",
|
|
1352
1501
|
Principal: this.props.principal,
|
|
1502
|
+
...this.attr("FunctionUrlAuthType", this.props.urlAuthType && constantCase3(this.props.urlAuthType)),
|
|
1353
1503
|
...this.attr("SourceArn", this.props.sourceArn)
|
|
1354
1504
|
};
|
|
1355
1505
|
}
|
|
@@ -1476,7 +1626,7 @@ var Queue = class extends Resource {
|
|
|
1476
1626
|
};
|
|
1477
1627
|
|
|
1478
1628
|
// src/formation/resource/lambda/event-source-mapping.ts
|
|
1479
|
-
import { constantCase as
|
|
1629
|
+
import { constantCase as constantCase4 } from "change-case";
|
|
1480
1630
|
var EventSourceMapping = class extends Resource {
|
|
1481
1631
|
constructor(logicalId, props) {
|
|
1482
1632
|
super("AWS::Lambda::EventSourceMapping", logicalId);
|
|
@@ -1498,7 +1648,7 @@ var EventSourceMapping = class extends Resource {
|
|
|
1498
1648
|
...this.attr("ParallelizationFactor", this.props.parallelizationFactor),
|
|
1499
1649
|
...this.attr("TumblingWindowInSeconds", this.props.tumblingWindow?.toSeconds()),
|
|
1500
1650
|
...this.attr("BisectBatchOnFunctionError", this.props.bisectBatchOnError),
|
|
1501
|
-
...this.attr("StartingPosition", this.props.startingPosition &&
|
|
1651
|
+
...this.attr("StartingPosition", this.props.startingPosition && constantCase4(this.props.startingPosition)),
|
|
1502
1652
|
...this.attr("StartingPositionTimestamp", this.props.startingPositionTimestamp),
|
|
1503
1653
|
...this.props.maxConcurrency ? {
|
|
1504
1654
|
ScalingConfig: {
|
|
@@ -1539,7 +1689,7 @@ var SqsEventSource = class extends Group {
|
|
|
1539
1689
|
};
|
|
1540
1690
|
|
|
1541
1691
|
// src/plugins/queue.ts
|
|
1542
|
-
import { camelCase as camelCase3, constantCase as
|
|
1692
|
+
import { camelCase as camelCase3, constantCase as constantCase5 } from "change-case";
|
|
1543
1693
|
import { relative as relative3 } from "path";
|
|
1544
1694
|
var RetentionPeriodSchema = DurationSchema.refine(durationMin(Duration.minutes(1)), "Minimum retention period is 1 minute").refine(durationMax(Duration.days(14)), "Maximum retention period is 14 days");
|
|
1545
1695
|
var VisibilityTimeoutSchema = DurationSchema.refine(durationMax(Duration.hours(12)), "Maximum visibility timeout is 12 hours");
|
|
@@ -1694,7 +1844,7 @@ var queuePlugin = definePlugin({
|
|
|
1694
1844
|
stack.add(queue2, lambda, source);
|
|
1695
1845
|
bind((lambda2) => {
|
|
1696
1846
|
lambda2.addPermissions(queue2.permissions);
|
|
1697
|
-
lambda2.addEnvironment(`QUEUE_${
|
|
1847
|
+
lambda2.addEnvironment(`QUEUE_${constantCase5(stack.name)}_${constantCase5(id)}_URL`, queue2.url);
|
|
1698
1848
|
});
|
|
1699
1849
|
}
|
|
1700
1850
|
}
|
|
@@ -1704,7 +1854,7 @@ var queuePlugin = definePlugin({
|
|
|
1704
1854
|
import { z as z9 } from "zod";
|
|
1705
1855
|
|
|
1706
1856
|
// src/formation/resource/dynamodb/table.ts
|
|
1707
|
-
import { constantCase as
|
|
1857
|
+
import { constantCase as constantCase6 } from "change-case";
|
|
1708
1858
|
var Table = class extends Resource {
|
|
1709
1859
|
constructor(logicalId, props) {
|
|
1710
1860
|
super("AWS::DynamoDB::Table", logicalId);
|
|
@@ -1777,7 +1927,7 @@ var Table = class extends Resource {
|
|
|
1777
1927
|
return {
|
|
1778
1928
|
TableName: this.name,
|
|
1779
1929
|
BillingMode: "PAY_PER_REQUEST",
|
|
1780
|
-
TableClass:
|
|
1930
|
+
TableClass: constantCase6(this.props.class || "standard"),
|
|
1781
1931
|
PointInTimeRecoverySpecification: {
|
|
1782
1932
|
PointInTimeRecoveryEnabled: this.props.pointInTimeRecovery || false
|
|
1783
1933
|
},
|
|
@@ -1788,7 +1938,7 @@ var Table = class extends Resource {
|
|
|
1788
1938
|
AttributeDefinitions: this.attributeDefinitions(),
|
|
1789
1939
|
...this.props.stream ? {
|
|
1790
1940
|
StreamSpecification: {
|
|
1791
|
-
StreamViewType:
|
|
1941
|
+
StreamViewType: constantCase6(this.props.stream)
|
|
1792
1942
|
}
|
|
1793
1943
|
} : {},
|
|
1794
1944
|
...this.props.timeToLiveAttribute ? {
|
|
@@ -1805,7 +1955,7 @@ var Table = class extends Resource {
|
|
|
1805
1955
|
...props.sort ? [{ KeyType: "RANGE", AttributeName: props.sort }] : []
|
|
1806
1956
|
],
|
|
1807
1957
|
Projection: {
|
|
1808
|
-
ProjectionType:
|
|
1958
|
+
ProjectionType: constantCase6(props.projection || "all")
|
|
1809
1959
|
}
|
|
1810
1960
|
}))
|
|
1811
1961
|
} : {}
|
|
@@ -1931,21 +2081,6 @@ var tablePlugin = definePlugin({
|
|
|
1931
2081
|
projection: z9.enum(["all", "keys-only"]).default("all")
|
|
1932
2082
|
})).optional()
|
|
1933
2083
|
})
|
|
1934
|
-
// .refine(props => {
|
|
1935
|
-
// return (
|
|
1936
|
-
// // Check the hash key
|
|
1937
|
-
// props.fields.hasOwnProperty(props.hash) &&
|
|
1938
|
-
// // Check the sort key
|
|
1939
|
-
// (!props.sort || props.fields.hasOwnProperty(props.sort)) &&
|
|
1940
|
-
// // Check all indexes
|
|
1941
|
-
// !Object.values(props.indexes || {}).map(index => (
|
|
1942
|
-
// // Check the index hash key
|
|
1943
|
-
// props.fields.hasOwnProperty(index.hash) &&
|
|
1944
|
-
// // Check the index sort key
|
|
1945
|
-
// (!index.sort || props.fields.hasOwnProperty(index.sort))
|
|
1946
|
-
// )).includes(false)
|
|
1947
|
-
// )
|
|
1948
|
-
// }, 'Hash & Sort keys must be defined inside the table fields')
|
|
1949
2084
|
).optional()
|
|
1950
2085
|
}).array()
|
|
1951
2086
|
}),
|
|
@@ -2000,11 +2135,20 @@ var Bucket = class extends Resource {
|
|
|
2000
2135
|
}
|
|
2001
2136
|
name;
|
|
2002
2137
|
get arn() {
|
|
2003
|
-
return
|
|
2138
|
+
return getAtt(this.logicalId, "Arn");
|
|
2004
2139
|
}
|
|
2005
2140
|
get domainName() {
|
|
2006
2141
|
return getAtt(this.logicalId, "DomainName");
|
|
2007
2142
|
}
|
|
2143
|
+
get dealStackDomainName() {
|
|
2144
|
+
return getAtt(this.logicalId, "DualStackDomainName");
|
|
2145
|
+
}
|
|
2146
|
+
get regionalDomainName() {
|
|
2147
|
+
return getAtt(this.logicalId, "RegionalDomainName");
|
|
2148
|
+
}
|
|
2149
|
+
get url() {
|
|
2150
|
+
return getAtt(this.logicalId, "WebsiteURL");
|
|
2151
|
+
}
|
|
2008
2152
|
get permissions() {
|
|
2009
2153
|
return {
|
|
2010
2154
|
actions: [
|
|
@@ -2026,15 +2170,38 @@ var Bucket = class extends Resource {
|
|
|
2026
2170
|
return {
|
|
2027
2171
|
BucketName: this.name,
|
|
2028
2172
|
AccessControl: pascalCase2(this.props.accessControl ?? "private"),
|
|
2029
|
-
...this.props.
|
|
2173
|
+
...this.props.versioning ? {
|
|
2030
2174
|
VersioningConfiguration: {
|
|
2031
2175
|
Status: "Enabled"
|
|
2032
2176
|
}
|
|
2177
|
+
} : {},
|
|
2178
|
+
...this.props.website ? {
|
|
2179
|
+
WebsiteConfiguration: {
|
|
2180
|
+
...this.attr("IndexDocument", this.props.website.indexDocument),
|
|
2181
|
+
...this.attr("ErrorDocument", this.props.website.errorDocument)
|
|
2182
|
+
}
|
|
2033
2183
|
} : {}
|
|
2034
2184
|
};
|
|
2035
2185
|
}
|
|
2036
2186
|
};
|
|
2037
2187
|
|
|
2188
|
+
// src/formation/resource/cloud-formation/custom-resource.ts
|
|
2189
|
+
var CustomResource = class extends Resource {
|
|
2190
|
+
constructor(logicalId, props) {
|
|
2191
|
+
super("AWS::CloudFormation::CustomResource", logicalId);
|
|
2192
|
+
this.props = props;
|
|
2193
|
+
}
|
|
2194
|
+
getAtt(name) {
|
|
2195
|
+
return getAtt(this.logicalId, name);
|
|
2196
|
+
}
|
|
2197
|
+
properties() {
|
|
2198
|
+
return {
|
|
2199
|
+
ServiceToken: this.props.serviceToken,
|
|
2200
|
+
...this.props.properties
|
|
2201
|
+
};
|
|
2202
|
+
}
|
|
2203
|
+
};
|
|
2204
|
+
|
|
2038
2205
|
// src/plugins/store.ts
|
|
2039
2206
|
var storePlugin = definePlugin({
|
|
2040
2207
|
name: "store",
|
|
@@ -2061,13 +2228,19 @@ var storePlugin = definePlugin({
|
|
|
2061
2228
|
}
|
|
2062
2229
|
return types2.toString();
|
|
2063
2230
|
},
|
|
2064
|
-
onStack({ config, stack, stackConfig, bind }) {
|
|
2231
|
+
onStack({ config, stack, stackConfig, bootstrap: bootstrap2, bind }) {
|
|
2065
2232
|
for (const id of stackConfig.stores || []) {
|
|
2066
2233
|
const bucket = new Bucket(id, {
|
|
2067
|
-
name:
|
|
2234
|
+
name: `store-${config.name}-${stack.name}-${id}`,
|
|
2068
2235
|
accessControl: "private"
|
|
2069
2236
|
});
|
|
2070
|
-
|
|
2237
|
+
const custom = new CustomResource(id, {
|
|
2238
|
+
serviceToken: bootstrap2.import("feature-delete-bucket"),
|
|
2239
|
+
properties: {
|
|
2240
|
+
bucketName: bucket.name
|
|
2241
|
+
}
|
|
2242
|
+
}).dependsOn(bucket);
|
|
2243
|
+
stack.add(bucket, custom);
|
|
2071
2244
|
bind((lambda) => {
|
|
2072
2245
|
lambda.addPermissions(bucket.permissions);
|
|
2073
2246
|
});
|
|
@@ -2371,7 +2544,7 @@ var toArray = (value) => {
|
|
|
2371
2544
|
import { paramCase as paramCase4 } from "change-case";
|
|
2372
2545
|
|
|
2373
2546
|
// src/formation/resource/appsync/graphql-api.ts
|
|
2374
|
-
import { constantCase as
|
|
2547
|
+
import { constantCase as constantCase7 } from "change-case";
|
|
2375
2548
|
var GraphQLApi = class extends Resource {
|
|
2376
2549
|
constructor(logicalId, props) {
|
|
2377
2550
|
super("AWS::AppSync::GraphQLApi", logicalId);
|
|
@@ -2403,7 +2576,7 @@ var GraphQLApi = class extends Resource {
|
|
|
2403
2576
|
properties() {
|
|
2404
2577
|
return {
|
|
2405
2578
|
Name: this.name,
|
|
2406
|
-
AuthenticationType:
|
|
2579
|
+
AuthenticationType: constantCase7(this.props.authenticationType || "api-key"),
|
|
2407
2580
|
AdditionalAuthenticationProviders: this.lambdaAuthProviders.map((provider) => ({
|
|
2408
2581
|
AuthenticationType: "AWS_LAMBDA",
|
|
2409
2582
|
LambdaAuthorizerConfig: {
|
|
@@ -2750,7 +2923,7 @@ var graphqlPlugin = definePlugin({
|
|
|
2750
2923
|
}).array()
|
|
2751
2924
|
}),
|
|
2752
2925
|
onApp(ctx) {
|
|
2753
|
-
const { config, bootstrap: bootstrap2
|
|
2926
|
+
const { config, bootstrap: bootstrap2 } = ctx;
|
|
2754
2927
|
const apis = /* @__PURE__ */ new Set();
|
|
2755
2928
|
for (const stackConfig of config.stacks) {
|
|
2756
2929
|
for (const id of Object.keys(stackConfig.graphql || {})) {
|
|
@@ -2783,8 +2956,9 @@ var graphqlPlugin = definePlugin({
|
|
|
2783
2956
|
}
|
|
2784
2957
|
if (props.domain) {
|
|
2785
2958
|
const domainName = props.subDomain ? `${props.subDomain}.${props.domain}` : props.domain;
|
|
2786
|
-
const hostedZoneId =
|
|
2787
|
-
const certificateArn =
|
|
2959
|
+
const hostedZoneId = bootstrap2.import(`hosted-zone-${props.domain}-id`);
|
|
2960
|
+
const certificateArn = bootstrap2.import(`us-east-certificate-${props.domain}-arn`);
|
|
2961
|
+
debug("DEBUG CERT", certificateArn);
|
|
2788
2962
|
const domain = new DomainName(id, {
|
|
2789
2963
|
domainName,
|
|
2790
2964
|
certificateArn
|
|
@@ -2900,132 +3074,31 @@ var RecordSetGroup = class extends Resource {
|
|
|
2900
3074
|
}
|
|
2901
3075
|
};
|
|
2902
3076
|
|
|
2903
|
-
// src/custom/
|
|
2904
|
-
var
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
port: 443,
|
|
2923
|
-
body,
|
|
2924
|
-
headers: {
|
|
2925
|
-
'content-type': '',
|
|
2926
|
-
'content-length': Buffer.from(body).byteLength,
|
|
2927
|
-
},
|
|
2928
|
-
})
|
|
2929
|
-
}
|
|
2930
|
-
|
|
2931
|
-
`
|
|
2932
|
-
);
|
|
2933
|
-
|
|
2934
|
-
// src/custom/delete-hosted-zone/handler.ts
|
|
2935
|
-
var deleteHostedZoneRecordsHandlerCode = (
|
|
2936
|
-
/* JS */
|
|
2937
|
-
`
|
|
2938
|
-
|
|
2939
|
-
const { Route53Client, ListResourceRecordSetsCommand, ChangeResourceRecordSetsCommand } = require('@aws-sdk/client-route-53')
|
|
2940
|
-
|
|
2941
|
-
const client = new Route53Client({})
|
|
2942
|
-
|
|
2943
|
-
${sendCode}
|
|
2944
|
-
|
|
2945
|
-
exports.handler = async (event) => {
|
|
2946
|
-
const type = event.RequestType
|
|
2947
|
-
const hostedZoneId = event.ResourceProperties.hostedZoneId
|
|
2948
|
-
|
|
2949
|
-
try {
|
|
2950
|
-
if(type === 'Delete') {
|
|
2951
|
-
const records = await listHostedZoneRecords(hostedZoneId)
|
|
2952
|
-
console.log(records)
|
|
2953
|
-
|
|
2954
|
-
await deleteHostedZoneRecords(hostedZoneId, records)
|
|
2955
|
-
}
|
|
2956
|
-
|
|
2957
|
-
await send(event, hostedZoneId, 'SUCCESS')
|
|
2958
|
-
}
|
|
2959
|
-
catch(error) {
|
|
2960
|
-
if (error instanceof Error) {
|
|
2961
|
-
await send(event, hostedZoneId, 'FAILED', {}, error.message)
|
|
2962
|
-
} else {
|
|
2963
|
-
await send(event, hostedZoneId, 'FAILED', {}, 'Unknown error')
|
|
2964
|
-
}
|
|
2965
|
-
}
|
|
2966
|
-
}
|
|
2967
|
-
|
|
2968
|
-
const deleteHostedZoneRecords = async (hostedZoneId, records) => {
|
|
2969
|
-
records = records.filter(record => ![ 'SOA', 'NS' ].includes(record.Type))
|
|
2970
|
-
if(records.length === 0) {
|
|
2971
|
-
return
|
|
2972
|
-
}
|
|
2973
|
-
|
|
2974
|
-
const chunkSize = 100;
|
|
2975
|
-
for (let i = 0; i < records.length; i += chunkSize) {
|
|
2976
|
-
const chunk = records.slice(i, i + chunkSize);
|
|
2977
|
-
|
|
2978
|
-
await client.send(new ChangeResourceRecordSetsCommand({
|
|
2979
|
-
HostedZoneId: hostedZoneId,
|
|
2980
|
-
ChangeBatch: {
|
|
2981
|
-
Changes: chunk.map(record => ({
|
|
2982
|
-
Action: 'DELETE',
|
|
2983
|
-
ResourceRecordSet: record
|
|
2984
|
-
}))
|
|
2985
|
-
}
|
|
2986
|
-
}))
|
|
2987
|
-
}
|
|
2988
|
-
}
|
|
2989
|
-
|
|
2990
|
-
const listHostedZoneRecords = async (hostedZoneId) => {
|
|
2991
|
-
|
|
2992
|
-
const records = []
|
|
2993
|
-
let token
|
|
2994
|
-
|
|
2995
|
-
while(true) {
|
|
2996
|
-
const result = await client.send(new ListResourceRecordSetsCommand({
|
|
2997
|
-
HostedZoneId: hostedZoneId,
|
|
2998
|
-
NextRecordName: token
|
|
2999
|
-
}))
|
|
3000
|
-
|
|
3001
|
-
if(result.ResourceRecordSets && result.ResourceRecordSets.length) {
|
|
3002
|
-
records.push(...result.ResourceRecordSets)
|
|
3003
|
-
}
|
|
3004
|
-
|
|
3005
|
-
if(result.NextRecordName) {
|
|
3006
|
-
token = result.NextRecordName
|
|
3007
|
-
} else {
|
|
3008
|
-
return records
|
|
3009
|
-
}
|
|
3010
|
-
}
|
|
3011
|
-
}
|
|
3012
|
-
`
|
|
3013
|
-
);
|
|
3014
|
-
|
|
3015
|
-
// src/formation/resource/cloud-formation/custom-resource.ts
|
|
3016
|
-
var CustomResource = class extends Resource {
|
|
3017
|
-
constructor(logicalId, props) {
|
|
3018
|
-
super("AWS::CloudFormation::CustomResource", logicalId);
|
|
3019
|
-
this.props = props;
|
|
3020
|
-
}
|
|
3021
|
-
getAtt(name) {
|
|
3022
|
-
return getAtt(this.logicalId, name);
|
|
3077
|
+
// src/custom/global-exports.ts
|
|
3078
|
+
var GlobalExports = class extends Group {
|
|
3079
|
+
resource;
|
|
3080
|
+
constructor(id, props) {
|
|
3081
|
+
const lambda = new Function(id, {
|
|
3082
|
+
code: Code.fromFeature("global-exports")
|
|
3083
|
+
});
|
|
3084
|
+
lambda.addPermissions({
|
|
3085
|
+
actions: ["cloudformation:ListExports"],
|
|
3086
|
+
resources: ["*"]
|
|
3087
|
+
});
|
|
3088
|
+
const resource = new CustomResource(id, {
|
|
3089
|
+
serviceToken: lambda.arn,
|
|
3090
|
+
properties: {
|
|
3091
|
+
region: props.region
|
|
3092
|
+
}
|
|
3093
|
+
});
|
|
3094
|
+
super([lambda, resource]);
|
|
3095
|
+
this.resource = resource;
|
|
3023
3096
|
}
|
|
3024
|
-
|
|
3025
|
-
return {
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
};
|
|
3097
|
+
import(name) {
|
|
3098
|
+
return lazy((stack) => {
|
|
3099
|
+
const attr = formatName(`${stack.app?.name ?? "default"}-${name}`);
|
|
3100
|
+
return this.resource.getAtt(attr);
|
|
3101
|
+
});
|
|
3029
3102
|
}
|
|
3030
3103
|
};
|
|
3031
3104
|
|
|
@@ -3067,36 +3140,39 @@ var domainPlugin = definePlugin({
|
|
|
3067
3140
|
if (domains.length === 0) {
|
|
3068
3141
|
return;
|
|
3069
3142
|
}
|
|
3070
|
-
const
|
|
3143
|
+
const deleteHostedZoneLambda = new Function("delete-hosted-zone", {
|
|
3071
3144
|
name: `${config.name}-delete-hosted-zone`,
|
|
3072
|
-
code: Code.
|
|
3073
|
-
})
|
|
3074
|
-
lambda.addPermissions({
|
|
3145
|
+
code: Code.fromInlineFeature("delete-hosted-zone")
|
|
3146
|
+
}).enableLogs(Duration.days(3)).addPermissions({
|
|
3075
3147
|
actions: [
|
|
3076
3148
|
"route53:ListResourceRecordSets",
|
|
3077
3149
|
"route53:ChangeResourceRecordSets"
|
|
3078
3150
|
],
|
|
3079
3151
|
resources: ["*"]
|
|
3080
3152
|
});
|
|
3081
|
-
usEastBootstrap.add(
|
|
3153
|
+
usEastBootstrap.add(deleteHostedZoneLambda);
|
|
3154
|
+
const usEastExports = new GlobalExports("us-east-exports", {
|
|
3155
|
+
region: usEastBootstrap.region
|
|
3156
|
+
});
|
|
3157
|
+
bootstrap2.add(usEastExports);
|
|
3082
3158
|
for (const [domain, records] of domains) {
|
|
3083
3159
|
const hostedZone = new HostedZone(domain);
|
|
3084
3160
|
const usEastCertificate = new Certificate(domain, {
|
|
3085
3161
|
hostedZoneId: hostedZone.id,
|
|
3086
3162
|
alternativeNames: [`*.${domain}`]
|
|
3087
3163
|
});
|
|
3088
|
-
const
|
|
3089
|
-
serviceToken:
|
|
3164
|
+
const deleteHostedZone = new CustomResource(domain, {
|
|
3165
|
+
serviceToken: deleteHostedZoneLambda.arn,
|
|
3090
3166
|
properties: {
|
|
3091
3167
|
hostedZoneId: hostedZone.id
|
|
3092
3168
|
}
|
|
3093
|
-
}).dependsOn(hostedZone);
|
|
3094
|
-
usEastBootstrap.add(
|
|
3169
|
+
}).dependsOn(deleteHostedZoneLambda, hostedZone);
|
|
3170
|
+
usEastBootstrap.add(hostedZone).add(deleteHostedZone).add(usEastCertificate).export(`certificate-${domain}-arn`, usEastCertificate.arn).export(`hosted-zone-${domain}-id`, hostedZone.id);
|
|
3095
3171
|
const certificate = new Certificate(domain, {
|
|
3096
|
-
hostedZoneId:
|
|
3172
|
+
hostedZoneId: usEastExports.import(`hosted-zone-${domain}-id`),
|
|
3097
3173
|
alternativeNames: [`*.${domain}`]
|
|
3098
3174
|
});
|
|
3099
|
-
bootstrap2.add(certificate).export(`certificate-${domain}-arn`, certificate.arn);
|
|
3175
|
+
bootstrap2.add(certificate).export(`certificate-${domain}-arn`, certificate.arn).export(`hosted-zone-${domain}-id`, usEastExports.import(`hosted-zone-${domain}-id`)).export(`us-east-certificate-${domain}-arn`, usEastExports.import(`certificate-${domain}-arn`));
|
|
3100
3176
|
if (records.length > 0) {
|
|
3101
3177
|
const group = new RecordSetGroup(domain, {
|
|
3102
3178
|
hostedZoneId: hostedZone.id,
|
|
@@ -3508,7 +3584,7 @@ var LoadBalancer = class extends Resource {
|
|
|
3508
3584
|
};
|
|
3509
3585
|
|
|
3510
3586
|
// src/formation/resource/elb/listener.ts
|
|
3511
|
-
import { constantCase as
|
|
3587
|
+
import { constantCase as constantCase8 } from "change-case";
|
|
3512
3588
|
var Listener = class extends Resource {
|
|
3513
3589
|
constructor(logicalId, props) {
|
|
3514
3590
|
super("AWS::ElasticLoadBalancingV2::Listener", logicalId);
|
|
@@ -3524,7 +3600,7 @@ var Listener = class extends Resource {
|
|
|
3524
3600
|
return {
|
|
3525
3601
|
LoadBalancerArn: this.props.loadBalancerArn,
|
|
3526
3602
|
Port: this.props.port,
|
|
3527
|
-
Protocol:
|
|
3603
|
+
Protocol: constantCase8(this.props.protocol),
|
|
3528
3604
|
Certificates: this.props.certificates.map((arn) => ({
|
|
3529
3605
|
CertificateArn: arn
|
|
3530
3606
|
})),
|
|
@@ -3750,7 +3826,7 @@ var httpPlugin = definePlugin({
|
|
|
3750
3826
|
).optional()
|
|
3751
3827
|
}).array()
|
|
3752
3828
|
}),
|
|
3753
|
-
onApp({ config, bootstrap: bootstrap2
|
|
3829
|
+
onApp({ config, bootstrap: bootstrap2 }) {
|
|
3754
3830
|
if (Object.keys(config.defaults?.http || {}).length === 0) {
|
|
3755
3831
|
return;
|
|
3756
3832
|
}
|
|
@@ -3789,7 +3865,7 @@ var httpPlugin = definePlugin({
|
|
|
3789
3865
|
]
|
|
3790
3866
|
}).dependsOn(loadBalancer);
|
|
3791
3867
|
const record = new RecordSet(`${id}-http`, {
|
|
3792
|
-
hostedZoneId:
|
|
3868
|
+
hostedZoneId: bootstrap2.import(`hosted-zone-${props.domain}-id`),
|
|
3793
3869
|
name: props.subDomain ? `${props.subDomain}.${props.domain}` : props.domain,
|
|
3794
3870
|
type: "A",
|
|
3795
3871
|
alias: {
|
|
@@ -3963,7 +4039,7 @@ var SubnetGroup = class extends Resource {
|
|
|
3963
4039
|
};
|
|
3964
4040
|
|
|
3965
4041
|
// src/plugins/cache.ts
|
|
3966
|
-
import { constantCase as
|
|
4042
|
+
import { constantCase as constantCase9 } from "change-case";
|
|
3967
4043
|
var TypeSchema = z19.enum([
|
|
3968
4044
|
"t4g.small",
|
|
3969
4045
|
"t4g.medium",
|
|
@@ -4049,7 +4125,7 @@ var cachePlugin = definePlugin({
|
|
|
4049
4125
|
}).dependsOn(subnetGroup, securityGroup);
|
|
4050
4126
|
stack.add(subnetGroup, securityGroup, cluster);
|
|
4051
4127
|
bind((lambda) => {
|
|
4052
|
-
lambda.addEnvironment(`CACHE_${
|
|
4128
|
+
lambda.addEnvironment(`CACHE_${constantCase9(stack.name)}_${constantCase9(id)}_HOST`, cluster.address).addEnvironment(`CACHE_${constantCase9(stack.name)}_${constantCase9(id)}_PORT`, props.port.toString());
|
|
4053
4129
|
});
|
|
4054
4130
|
}
|
|
4055
4131
|
}
|
|
@@ -4267,7 +4343,7 @@ var restPlugin = definePlugin({
|
|
|
4267
4343
|
).optional()
|
|
4268
4344
|
}).array()
|
|
4269
4345
|
}),
|
|
4270
|
-
onApp({ config, bootstrap: bootstrap2
|
|
4346
|
+
onApp({ config, bootstrap: bootstrap2 }) {
|
|
4271
4347
|
for (const [id, props] of Object.entries(config.defaults?.rest || {})) {
|
|
4272
4348
|
const api = new Api(id, {
|
|
4273
4349
|
name: `${config.name}-${id}`,
|
|
@@ -4280,7 +4356,7 @@ var restPlugin = definePlugin({
|
|
|
4280
4356
|
bootstrap2.add(api, stage).export(`rest-${id}-id`, api.id);
|
|
4281
4357
|
if (props.domain) {
|
|
4282
4358
|
const domainName = props.subDomain ? `${props.subDomain}.${props.domain}` : props.domain;
|
|
4283
|
-
const hostedZoneId =
|
|
4359
|
+
const hostedZoneId = bootstrap2.import(`hosted-zone-${props.domain}-id`);
|
|
4284
4360
|
const certificateArn = bootstrap2.import(`certificate-${props.domain}-arn`);
|
|
4285
4361
|
const domain = new DomainName2(id, {
|
|
4286
4362
|
name: domainName,
|
|
@@ -4291,7 +4367,7 @@ var restPlugin = definePlugin({
|
|
|
4291
4367
|
domainName: domain.name,
|
|
4292
4368
|
stage: stage.name
|
|
4293
4369
|
}).dependsOn(api, domain, stage);
|
|
4294
|
-
const record = new RecordSet(
|
|
4370
|
+
const record = new RecordSet(`rest-${id}`, {
|
|
4295
4371
|
hostedZoneId,
|
|
4296
4372
|
type: "A",
|
|
4297
4373
|
name: domainName,
|
|
@@ -4466,131 +4542,717 @@ var configPlugin = definePlugin({
|
|
|
4466
4542
|
}
|
|
4467
4543
|
});
|
|
4468
4544
|
|
|
4469
|
-
// src/plugins/
|
|
4470
|
-
|
|
4471
|
-
extendPlugin,
|
|
4472
|
-
vpcPlugin,
|
|
4473
|
-
functionPlugin,
|
|
4474
|
-
configPlugin,
|
|
4475
|
-
cachePlugin,
|
|
4476
|
-
cronPlugin,
|
|
4477
|
-
queuePlugin,
|
|
4478
|
-
tablePlugin,
|
|
4479
|
-
storePlugin,
|
|
4480
|
-
topicPlugin,
|
|
4481
|
-
pubsubPlugin,
|
|
4482
|
-
searchPlugin,
|
|
4483
|
-
domainPlugin,
|
|
4484
|
-
graphqlPlugin,
|
|
4485
|
-
httpPlugin,
|
|
4486
|
-
restPlugin,
|
|
4487
|
-
onFailurePlugin
|
|
4488
|
-
];
|
|
4545
|
+
// src/plugins/site.ts
|
|
4546
|
+
import { z as z24 } from "zod";
|
|
4489
4547
|
|
|
4490
|
-
// src/formation/
|
|
4491
|
-
var
|
|
4492
|
-
constructor(
|
|
4493
|
-
|
|
4548
|
+
// src/formation/resource/cloud-front/distribution.ts
|
|
4549
|
+
var Distribution = class extends Resource {
|
|
4550
|
+
constructor(logicalId, props) {
|
|
4551
|
+
super("AWS::CloudFront::Distribution", logicalId);
|
|
4552
|
+
this.props = props;
|
|
4553
|
+
this.name = formatName(this.props.name || logicalId);
|
|
4554
|
+
this.tag("name", this.name);
|
|
4494
4555
|
}
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
this.list.set(stack.name, stack);
|
|
4499
|
-
stack.setApp(this);
|
|
4500
|
-
});
|
|
4501
|
-
return this;
|
|
4556
|
+
name;
|
|
4557
|
+
get id() {
|
|
4558
|
+
return getAtt(this.logicalId, "Id");
|
|
4502
4559
|
}
|
|
4503
|
-
|
|
4504
|
-
return
|
|
4560
|
+
get arn() {
|
|
4561
|
+
return sub("arn:${AWS::Partition}:cloudfront::${AWS::AccountId}:distribution/${id}", {
|
|
4562
|
+
id: this.id
|
|
4563
|
+
});
|
|
4505
4564
|
}
|
|
4506
|
-
|
|
4507
|
-
return this.
|
|
4565
|
+
get domainName() {
|
|
4566
|
+
return getAtt(this.logicalId, "DomainName");
|
|
4508
4567
|
}
|
|
4509
|
-
|
|
4510
|
-
return
|
|
4568
|
+
properties() {
|
|
4569
|
+
return {
|
|
4570
|
+
DistributionConfig: {
|
|
4571
|
+
Enabled: true,
|
|
4572
|
+
Aliases: this.props.aliases ?? [],
|
|
4573
|
+
PriceClass: "PriceClass_" + (this.props.priceClass ?? "All"),
|
|
4574
|
+
HttpVersion: this.props.httpVersion ?? "http2and3",
|
|
4575
|
+
ViewerCertificate: this.props.certificateArn ? {
|
|
4576
|
+
SslSupportMethod: "sni-only",
|
|
4577
|
+
AcmCertificateArn: this.props.certificateArn
|
|
4578
|
+
} : {},
|
|
4579
|
+
Origins: this.props.origins?.map((origin) => origin.toJSON()) ?? [],
|
|
4580
|
+
OriginGroups: {
|
|
4581
|
+
Quantity: this.props.originGroups?.length ?? 0,
|
|
4582
|
+
Items: this.props.originGroups?.map((originGroup) => originGroup.toJSON()) ?? []
|
|
4583
|
+
},
|
|
4584
|
+
DefaultCacheBehavior: {
|
|
4585
|
+
TargetOriginId: this.props.targetOriginId,
|
|
4586
|
+
ViewerProtocolPolicy: this.props.viewerProtocol ?? "redirect-to-https",
|
|
4587
|
+
AllowedMethods: this.props.allowMethod ?? ["GET", "HEAD", "OPTIONS"],
|
|
4588
|
+
Compress: this.props.compress ?? false,
|
|
4589
|
+
FunctionAssociations: this.props.associations?.map((association) => ({
|
|
4590
|
+
EventType: association.type,
|
|
4591
|
+
FunctionARN: association.functionArn
|
|
4592
|
+
})) ?? [],
|
|
4593
|
+
LambdaFunctionAssociations: this.props.lambdaAssociations?.map((association) => ({
|
|
4594
|
+
EventType: association.type,
|
|
4595
|
+
IncludeBody: association.includeBody ?? false,
|
|
4596
|
+
FunctionARN: association.functionArn
|
|
4597
|
+
})) ?? [],
|
|
4598
|
+
...this.attr("CachePolicyId", this.props.cachePolicyId),
|
|
4599
|
+
...this.attr("OriginRequestPolicyId", this.props.originRequestPolicyId),
|
|
4600
|
+
...this.attr("ResponseHeadersPolicyId", this.props.responseHeadersPolicyId)
|
|
4601
|
+
}
|
|
4602
|
+
}
|
|
4603
|
+
};
|
|
4604
|
+
}
|
|
4605
|
+
};
|
|
4606
|
+
var Origin = class {
|
|
4607
|
+
constructor(props) {
|
|
4608
|
+
this.props = props;
|
|
4609
|
+
}
|
|
4610
|
+
toJSON() {
|
|
4611
|
+
return {
|
|
4612
|
+
Id: this.props.id,
|
|
4613
|
+
DomainName: this.props.domainName,
|
|
4614
|
+
OriginCustomHeaders: Object.entries(this.props.headers ?? {}).map(([name, value]) => ({
|
|
4615
|
+
HeaderName: name,
|
|
4616
|
+
HeaderValue: value
|
|
4617
|
+
})),
|
|
4618
|
+
...this.props.path ? {
|
|
4619
|
+
OriginPath: this.props.path
|
|
4620
|
+
} : {},
|
|
4621
|
+
...this.props.protocol ? {
|
|
4622
|
+
CustomOriginConfig: {
|
|
4623
|
+
OriginProtocolPolicy: this.props.protocol
|
|
4624
|
+
}
|
|
4625
|
+
} : {},
|
|
4626
|
+
...this.props.originAccessIdentityId ? {
|
|
4627
|
+
S3OriginConfig: {
|
|
4628
|
+
OriginAccessIdentity: sub("origin-access-identity/cloudfront/${id}", {
|
|
4629
|
+
id: this.props.originAccessIdentityId
|
|
4630
|
+
})
|
|
4631
|
+
}
|
|
4632
|
+
} : {},
|
|
4633
|
+
...this.props.originAccessControlId ? {
|
|
4634
|
+
OriginAccessControlId: this.props.originAccessControlId,
|
|
4635
|
+
S3OriginConfig: {
|
|
4636
|
+
OriginAccessIdentity: ""
|
|
4637
|
+
}
|
|
4638
|
+
} : {}
|
|
4639
|
+
};
|
|
4640
|
+
}
|
|
4641
|
+
};
|
|
4642
|
+
var OriginGroup = class {
|
|
4643
|
+
constructor(props) {
|
|
4644
|
+
this.props = props;
|
|
4645
|
+
}
|
|
4646
|
+
toJSON() {
|
|
4647
|
+
return {
|
|
4648
|
+
Id: this.props.id,
|
|
4649
|
+
Members: {
|
|
4650
|
+
Quantity: this.props.members.length,
|
|
4651
|
+
Items: this.props.members.map((member) => ({
|
|
4652
|
+
OriginId: member
|
|
4653
|
+
}))
|
|
4654
|
+
},
|
|
4655
|
+
FailoverCriteria: {
|
|
4656
|
+
StatusCodes: {
|
|
4657
|
+
Quantity: this.props.statusCodes.length,
|
|
4658
|
+
Items: this.props.statusCodes
|
|
4659
|
+
}
|
|
4660
|
+
}
|
|
4661
|
+
};
|
|
4511
4662
|
}
|
|
4512
|
-
// get resources() {
|
|
4513
|
-
// return this.stacks.map(stack => stack.resources).flat()
|
|
4514
|
-
// }
|
|
4515
4663
|
};
|
|
4516
4664
|
|
|
4517
|
-
// src/
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
const
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
try {
|
|
4530
|
-
const data = await listExports(region)
|
|
4665
|
+
// src/schema/local-directory.ts
|
|
4666
|
+
import { stat as stat2 } from "fs/promises";
|
|
4667
|
+
import { z as z23 } from "zod";
|
|
4668
|
+
var LocalDirectorySchema = z23.string().refine(async (path) => {
|
|
4669
|
+
try {
|
|
4670
|
+
const s = await stat2(path);
|
|
4671
|
+
return s.isDirectory();
|
|
4672
|
+
} catch (error) {
|
|
4673
|
+
return false;
|
|
4674
|
+
}
|
|
4675
|
+
}, `Directory doesn't exist`);
|
|
4531
4676
|
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4677
|
+
// src/formation/resource/cloud-front/origin-request-policy.ts
|
|
4678
|
+
import { camelCase as camelCase4 } from "change-case";
|
|
4679
|
+
var OriginRequestPolicy = class extends Resource {
|
|
4680
|
+
constructor(logicalId, props = {}) {
|
|
4681
|
+
super("AWS::CloudFront::OriginRequestPolicy", logicalId);
|
|
4682
|
+
this.props = props;
|
|
4683
|
+
this.name = formatName(this.props.name || logicalId);
|
|
4684
|
+
}
|
|
4685
|
+
name;
|
|
4686
|
+
get id() {
|
|
4687
|
+
return getAtt(this.logicalId, "Id");
|
|
4688
|
+
}
|
|
4689
|
+
properties() {
|
|
4690
|
+
return {
|
|
4691
|
+
OriginRequestPolicyConfig: {
|
|
4692
|
+
Name: this.name,
|
|
4693
|
+
CookiesConfig: {
|
|
4694
|
+
CookieBehavior: camelCase4(this.props.cookie?.behavior ?? "all"),
|
|
4695
|
+
...this.attr("Cookies", this.props.cookie?.values)
|
|
4696
|
+
},
|
|
4697
|
+
HeadersConfig: {
|
|
4698
|
+
HeaderBehavior: camelCase4(this.props.header?.behavior ?? "allViewer"),
|
|
4699
|
+
...this.attr("Headers", this.props.header?.values)
|
|
4700
|
+
},
|
|
4701
|
+
QueryStringsConfig: {
|
|
4702
|
+
QueryStringBehavior: camelCase4(this.props.query?.behavior ?? "all"),
|
|
4703
|
+
...this.attr("QueryStrings", this.props.query?.values)
|
|
4704
|
+
}
|
|
4705
|
+
}
|
|
4706
|
+
};
|
|
4707
|
+
}
|
|
4708
|
+
};
|
|
4541
4709
|
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4710
|
+
// src/formation/resource/cloud-front/cache-policy.ts
|
|
4711
|
+
var CachePolicy = class extends Resource {
|
|
4712
|
+
constructor(logicalId, props) {
|
|
4713
|
+
super("AWS::CloudFront::CachePolicy", logicalId);
|
|
4714
|
+
this.props = props;
|
|
4715
|
+
this.name = formatName(this.props.name || logicalId);
|
|
4716
|
+
}
|
|
4717
|
+
name;
|
|
4718
|
+
get id() {
|
|
4719
|
+
return getAtt(this.logicalId, "Id");
|
|
4720
|
+
}
|
|
4721
|
+
properties() {
|
|
4722
|
+
return {
|
|
4723
|
+
CachePolicyConfig: {
|
|
4724
|
+
Name: this.name,
|
|
4725
|
+
MinTTL: this.props.minTtl.toSeconds(),
|
|
4726
|
+
MaxTTL: this.props.maxTtl.toSeconds(),
|
|
4727
|
+
DefaultTTL: this.props.defaultTtl.toSeconds(),
|
|
4728
|
+
ParametersInCacheKeyAndForwardedToOrigin: {
|
|
4729
|
+
EnableAcceptEncodingGzip: this.props.acceptGzip ?? false,
|
|
4730
|
+
EnableAcceptEncodingBrotli: this.props.acceptBrotli ?? false,
|
|
4731
|
+
CookiesConfig: {
|
|
4732
|
+
CookieBehavior: this.props.cookies ? "whitelist" : "none",
|
|
4733
|
+
...this.attr("Cookies", this.props.cookies)
|
|
4734
|
+
},
|
|
4735
|
+
HeadersConfig: {
|
|
4736
|
+
HeaderBehavior: this.props.headers ? "whitelist" : "none",
|
|
4737
|
+
...this.attr("Headers", this.props.headers)
|
|
4738
|
+
},
|
|
4739
|
+
QueryStringsConfig: {
|
|
4740
|
+
QueryStringBehavior: this.props.queries ? "whitelist" : "none",
|
|
4741
|
+
...this.attr("QueryStrings", this.props.queries)
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4744
|
+
}
|
|
4745
|
+
};
|
|
4746
|
+
}
|
|
4747
|
+
};
|
|
4545
4748
|
|
|
4546
|
-
|
|
4749
|
+
// src/formation/resource/s3/files.ts
|
|
4750
|
+
import { Glob } from "glob";
|
|
4751
|
+
import JSZip2 from "jszip";
|
|
4752
|
+
import { createHash as createHash2 } from "crypto";
|
|
4753
|
+
import { createReadStream } from "fs";
|
|
4754
|
+
import { join as join4 } from "path";
|
|
4755
|
+
var Files = class extends Asset {
|
|
4756
|
+
constructor(id, props) {
|
|
4757
|
+
super("bucket", id);
|
|
4758
|
+
this.props = props;
|
|
4759
|
+
}
|
|
4760
|
+
hash;
|
|
4761
|
+
bundle;
|
|
4762
|
+
s3;
|
|
4763
|
+
async build({ write }) {
|
|
4764
|
+
const glob = new Glob(this.props.pattern ?? "**/*", {
|
|
4765
|
+
nodir: true,
|
|
4766
|
+
cwd: this.props.directory
|
|
4767
|
+
});
|
|
4768
|
+
const zip = new JSZip2();
|
|
4769
|
+
const hashes = [];
|
|
4770
|
+
let count = 0;
|
|
4771
|
+
for await (const path of glob) {
|
|
4772
|
+
const file = join4(this.props.directory, path);
|
|
4773
|
+
const stream = createReadStream(file);
|
|
4774
|
+
const hash2 = createHash2("sha1");
|
|
4775
|
+
stream.pipe(hash2);
|
|
4776
|
+
hashes.push(hash2);
|
|
4777
|
+
zip.file(path, stream);
|
|
4778
|
+
count++;
|
|
4779
|
+
}
|
|
4780
|
+
this.bundle = await zip.generateAsync({
|
|
4781
|
+
type: "nodebuffer",
|
|
4782
|
+
compression: "DEFLATE",
|
|
4783
|
+
compressionOptions: {
|
|
4784
|
+
level: 9
|
|
4785
|
+
}
|
|
4786
|
+
});
|
|
4787
|
+
const hash = createHash2("sha1");
|
|
4788
|
+
for (const item of hashes) {
|
|
4789
|
+
hash.update(item.digest());
|
|
4790
|
+
}
|
|
4791
|
+
this.hash = hash.digest("hex");
|
|
4792
|
+
await write("HASH", this.hash);
|
|
4793
|
+
await write("bundle.zip", this.bundle);
|
|
4794
|
+
return {
|
|
4795
|
+
files: style.success(String(count)),
|
|
4796
|
+
size: formatByteSize(this.bundle.byteLength)
|
|
4797
|
+
};
|
|
4798
|
+
}
|
|
4799
|
+
async publish({ publish }) {
|
|
4800
|
+
this.s3 = await publish(
|
|
4801
|
+
`${this.id}.zip`,
|
|
4802
|
+
this.bundle,
|
|
4803
|
+
this.hash
|
|
4804
|
+
);
|
|
4805
|
+
}
|
|
4806
|
+
get source() {
|
|
4807
|
+
return this.s3;
|
|
4808
|
+
}
|
|
4809
|
+
};
|
|
4547
4810
|
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4811
|
+
// src/formation/resource/s3/bucket-policy.ts
|
|
4812
|
+
import { capitalCase } from "change-case";
|
|
4813
|
+
var BucketPolicy = class extends Resource {
|
|
4814
|
+
constructor(logicalId, props) {
|
|
4815
|
+
super("AWS::S3::BucketPolicy", logicalId);
|
|
4816
|
+
this.props = props;
|
|
4817
|
+
}
|
|
4818
|
+
properties() {
|
|
4819
|
+
return {
|
|
4820
|
+
Bucket: formatName(this.props.bucketName),
|
|
4821
|
+
PolicyDocument: {
|
|
4822
|
+
Version: this.props.version ?? "2012-10-17",
|
|
4823
|
+
Statement: this.props.statements.map((statement) => ({
|
|
4824
|
+
Effect: capitalCase(statement.effect ?? "allow"),
|
|
4825
|
+
...statement.principal ? {
|
|
4826
|
+
Principal: {
|
|
4827
|
+
Service: statement.principal
|
|
4828
|
+
}
|
|
4829
|
+
} : {},
|
|
4830
|
+
Action: statement.actions,
|
|
4831
|
+
Resource: statement.resources,
|
|
4832
|
+
...statement.sourceArn ? {
|
|
4833
|
+
Condition: {
|
|
4834
|
+
StringEquals: {
|
|
4835
|
+
"AWS:SourceArn": statement.sourceArn
|
|
4836
|
+
}
|
|
4837
|
+
}
|
|
4838
|
+
} : {}
|
|
4839
|
+
}))
|
|
4840
|
+
}
|
|
4841
|
+
};
|
|
4842
|
+
}
|
|
4843
|
+
};
|
|
4552
4844
|
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4845
|
+
// src/formation/resource/cloud-front/origin-access-control.ts
|
|
4846
|
+
var OriginAccessControl = class extends Resource {
|
|
4847
|
+
constructor(logicalId, props) {
|
|
4848
|
+
super("AWS::CloudFront::OriginAccessControl", logicalId);
|
|
4849
|
+
this.props = props;
|
|
4850
|
+
this.name = formatName(this.props.name || logicalId);
|
|
4851
|
+
}
|
|
4852
|
+
name;
|
|
4853
|
+
get id() {
|
|
4854
|
+
return getAtt(this.logicalId, "Id");
|
|
4855
|
+
}
|
|
4856
|
+
properties() {
|
|
4857
|
+
return {
|
|
4858
|
+
OriginAccessControlConfig: {
|
|
4859
|
+
Name: this.name,
|
|
4860
|
+
OriginAccessControlOriginType: this.props.type,
|
|
4861
|
+
SigningBehavior: this.props.behavior ?? "always",
|
|
4862
|
+
SigningProtocol: this.props.protocol ?? "sigv4"
|
|
4863
|
+
}
|
|
4864
|
+
};
|
|
4865
|
+
}
|
|
4866
|
+
};
|
|
4556
4867
|
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
}
|
|
4564
|
-
|
|
4565
|
-
)
|
|
4868
|
+
// src/formation/resource/cloud-front/response-headers-policy.ts
|
|
4869
|
+
var ResponseHeadersPolicy = class extends Resource {
|
|
4870
|
+
constructor(logicalId, props) {
|
|
4871
|
+
super("AWS::CloudFront::ResponseHeadersPolicy", logicalId);
|
|
4872
|
+
this.props = props;
|
|
4873
|
+
this.name = formatName(this.props.name || logicalId);
|
|
4874
|
+
}
|
|
4875
|
+
name;
|
|
4876
|
+
get id() {
|
|
4877
|
+
return getAtt(this.logicalId, "Id");
|
|
4878
|
+
}
|
|
4879
|
+
properties() {
|
|
4880
|
+
return {
|
|
4881
|
+
ResponseHeadersPolicyConfig: {
|
|
4882
|
+
Name: this.name,
|
|
4883
|
+
...this.props.remove && this.props.remove.length > 0 ? {
|
|
4884
|
+
RemoveHeadersConfig: {
|
|
4885
|
+
Items: this.props.remove?.map((value) => ({
|
|
4886
|
+
Header: value
|
|
4887
|
+
}))
|
|
4888
|
+
}
|
|
4889
|
+
} : {},
|
|
4890
|
+
CorsConfig: {
|
|
4891
|
+
OriginOverride: this.props.cors?.override ?? false,
|
|
4892
|
+
AccessControlAllowCredentials: this.props.cors?.credentials ?? false,
|
|
4893
|
+
AccessControlMaxAgeSec: this.props.cors?.maxAge?.toSeconds() ?? Duration.days(365).toSeconds(),
|
|
4894
|
+
AccessControlAllowHeaders: {
|
|
4895
|
+
Items: this.props.cors?.headers ?? ["*"]
|
|
4896
|
+
},
|
|
4897
|
+
AccessControlAllowMethods: {
|
|
4898
|
+
Items: this.props.cors?.methods ?? ["ALL"]
|
|
4899
|
+
},
|
|
4900
|
+
AccessControlAllowOrigins: {
|
|
4901
|
+
Items: this.props.cors?.origins ?? ["*"]
|
|
4902
|
+
},
|
|
4903
|
+
AccessControlExposeHeaders: {
|
|
4904
|
+
Items: this.props.cors?.exposeHeaders ?? ["*"]
|
|
4905
|
+
}
|
|
4906
|
+
},
|
|
4907
|
+
SecurityHeadersConfig: {
|
|
4908
|
+
...this.props.contentSecurityPolicy ? {
|
|
4909
|
+
ContentSecurityPolicy: {
|
|
4910
|
+
Override: this.props.contentSecurityPolicy?.override ?? false,
|
|
4911
|
+
ContentSecurityPolicy: this.props.contentSecurityPolicy?.contentSecurityPolicy
|
|
4912
|
+
}
|
|
4913
|
+
} : {},
|
|
4914
|
+
ContentTypeOptions: {
|
|
4915
|
+
Override: this.props.contentTypeOptions?.override ?? false
|
|
4916
|
+
},
|
|
4917
|
+
FrameOptions: {
|
|
4918
|
+
Override: this.props.frameOptions?.override ?? false,
|
|
4919
|
+
FrameOption: (this.props.frameOptions?.frameOption ?? "same-origin") === "same-origin" ? "SAMEORIGIN" : "DENY"
|
|
4920
|
+
},
|
|
4921
|
+
ReferrerPolicy: {
|
|
4922
|
+
Override: this.props.referrerPolicy?.override ?? false,
|
|
4923
|
+
ReferrerPolicy: this.props.referrerPolicy?.referrerPolicy ?? "same-origin"
|
|
4924
|
+
},
|
|
4925
|
+
StrictTransportSecurity: {
|
|
4926
|
+
Override: this.props.strictTransportSecurity?.override ?? false,
|
|
4927
|
+
Preload: this.props.strictTransportSecurity?.preload ?? true,
|
|
4928
|
+
AccessControlMaxAgeSec: this.props.strictTransportSecurity?.maxAge?.toSeconds() ?? 31536e3,
|
|
4929
|
+
IncludeSubdomains: this.props.strictTransportSecurity?.includeSubdomains ?? true
|
|
4930
|
+
},
|
|
4931
|
+
XSSProtection: {
|
|
4932
|
+
Override: this.props.xssProtection?.override ?? false,
|
|
4933
|
+
ModeBlock: this.props.xssProtection?.modeBlock ?? true,
|
|
4934
|
+
Protection: this.props.xssProtection?.enable ?? true,
|
|
4935
|
+
...this.attr("ReportUri", this.props.xssProtection?.reportUri)
|
|
4936
|
+
}
|
|
4937
|
+
}
|
|
4938
|
+
}
|
|
4939
|
+
};
|
|
4940
|
+
}
|
|
4941
|
+
};
|
|
4566
4942
|
|
|
4567
|
-
// src/
|
|
4568
|
-
var
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4943
|
+
// src/plugins/site.ts
|
|
4944
|
+
var sitePlugin = definePlugin({
|
|
4945
|
+
name: "site",
|
|
4946
|
+
schema: z24.object({
|
|
4947
|
+
stacks: z24.object({
|
|
4948
|
+
/** Define the sites in your stack.
|
|
4949
|
+
* @example
|
|
4950
|
+
* {
|
|
4951
|
+
* sites: {
|
|
4952
|
+
* SITE_NAME: {
|
|
4953
|
+
* static: 'dist/client'
|
|
4954
|
+
* ssr: 'dist/server/index.js'
|
|
4955
|
+
* }
|
|
4956
|
+
* }
|
|
4957
|
+
* }
|
|
4958
|
+
* */
|
|
4959
|
+
sites: z24.record(
|
|
4960
|
+
ResourceIdSchema,
|
|
4961
|
+
z24.object({
|
|
4962
|
+
/** The domain to link your site with. */
|
|
4963
|
+
domain: z24.string(),
|
|
4964
|
+
subDomain: z24.string().optional(),
|
|
4965
|
+
/** Specifies the path to the static files directory. */
|
|
4966
|
+
static: LocalDirectorySchema.optional(),
|
|
4967
|
+
/** Specifies the ssr file. */
|
|
4968
|
+
ssr: FunctionSchema.optional(),
|
|
4969
|
+
/** Define the cors headers. */
|
|
4970
|
+
cors: z24.object({
|
|
4971
|
+
override: z24.boolean().default(false),
|
|
4972
|
+
maxAge: DurationSchema.default("365 days"),
|
|
4973
|
+
exposeHeaders: z24.string().array().optional(),
|
|
4974
|
+
credentials: z24.boolean().default(false),
|
|
4975
|
+
headers: z24.string().array().default(["*"]),
|
|
4976
|
+
origins: z24.string().array().default(["*"]),
|
|
4977
|
+
methods: z24.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
|
|
4978
|
+
}).optional(),
|
|
4979
|
+
/** Define the cors headers. */
|
|
4980
|
+
security: z24.object({
|
|
4981
|
+
// contentSecurityPolicy: z.object({
|
|
4982
|
+
// override: z.boolean().default(false),
|
|
4983
|
+
// policy: z.string(),
|
|
4984
|
+
// })
|
|
4985
|
+
// contentSecurityPolicy?: {
|
|
4986
|
+
// override?: boolean
|
|
4987
|
+
// contentSecurityPolicy: string
|
|
4988
|
+
// }
|
|
4989
|
+
// contentTypeOptions?: {
|
|
4990
|
+
// override?: boolean
|
|
4991
|
+
// }
|
|
4992
|
+
// frameOptions?: {
|
|
4993
|
+
// override?: boolean
|
|
4994
|
+
// frameOption?: 'deny' | 'same-origin'
|
|
4995
|
+
// }
|
|
4996
|
+
// referrerPolicy?: {
|
|
4997
|
+
// override?: boolean
|
|
4998
|
+
// referrerPolicy?: (
|
|
4999
|
+
// 'no-referrer' |
|
|
5000
|
+
// 'no-referrer-when-downgrade' |
|
|
5001
|
+
// 'origin' |
|
|
5002
|
+
// 'origin-when-cross-origin' |
|
|
5003
|
+
// 'same-origin' |
|
|
5004
|
+
// 'strict-origin' |
|
|
5005
|
+
// 'strict-origin-when-cross-origin' |
|
|
5006
|
+
// 'unsafe-url'
|
|
5007
|
+
// )
|
|
5008
|
+
// }
|
|
5009
|
+
// strictTransportSecurity?: {
|
|
5010
|
+
// maxAge?: Duration
|
|
5011
|
+
// includeSubdomains?: boolean
|
|
5012
|
+
// override?: boolean
|
|
5013
|
+
// preload?: boolean
|
|
5014
|
+
// }
|
|
5015
|
+
// xssProtection?: {
|
|
5016
|
+
// override?: boolean
|
|
5017
|
+
// enable?: boolean
|
|
5018
|
+
// modeBlock?: boolean
|
|
5019
|
+
// reportUri?: string
|
|
5020
|
+
// }
|
|
5021
|
+
}).optional(),
|
|
5022
|
+
/** Specifies the cookies, headers, and query values that CloudFront includes in the cache key. */
|
|
5023
|
+
cache: z24.object({
|
|
5024
|
+
/** Specifies the cookies that CloudFront includes in the cache key. */
|
|
5025
|
+
cookies: z24.string().array().optional(),
|
|
5026
|
+
/** Specifies the headers that CloudFront includes in the cache key. */
|
|
5027
|
+
headers: z24.string().array().optional(),
|
|
5028
|
+
/** Specifies the query values that CloudFront includes in the cache key. */
|
|
5029
|
+
queries: z24.string().array().optional()
|
|
5030
|
+
}).optional()
|
|
5031
|
+
})
|
|
5032
|
+
).optional()
|
|
5033
|
+
}).array()
|
|
5034
|
+
}),
|
|
5035
|
+
onStack(ctx) {
|
|
5036
|
+
const { config, stack, stackConfig, bootstrap: bootstrap2 } = ctx;
|
|
5037
|
+
for (const [id, props] of Object.entries(stackConfig.sites || {})) {
|
|
5038
|
+
const origins = [];
|
|
5039
|
+
const originGroups = [];
|
|
5040
|
+
const deps = [];
|
|
5041
|
+
let bucket;
|
|
5042
|
+
if (props.ssr) {
|
|
5043
|
+
const lambda = toLambdaFunction(ctx, `site-${id}`, props.ssr);
|
|
5044
|
+
const permissions = new Permission2(`site-${id}`, {
|
|
5045
|
+
principal: "*",
|
|
5046
|
+
// principal: 'cloudfront.amazonaws.com',
|
|
5047
|
+
action: "lambda:InvokeFunctionUrl",
|
|
5048
|
+
functionArn: lambda.arn,
|
|
5049
|
+
urlAuthType: "none"
|
|
5050
|
+
// sourceArn: distribution.arn,
|
|
5051
|
+
}).dependsOn(lambda);
|
|
5052
|
+
const url = lambda.addUrl();
|
|
5053
|
+
stack.add(url, lambda, permissions);
|
|
5054
|
+
origins.push(new Origin({
|
|
5055
|
+
id: "lambda",
|
|
5056
|
+
domainName: select(2, split("/", url.url)),
|
|
5057
|
+
protocol: "https-only"
|
|
5058
|
+
}));
|
|
5059
|
+
deps.push(lambda, url, permissions);
|
|
5060
|
+
}
|
|
5061
|
+
if (props.static) {
|
|
5062
|
+
bucket = new Bucket(`site-${id}`, {
|
|
5063
|
+
// name: props.domain,
|
|
5064
|
+
name: `site-${config.name}-${stack.name}-${id}`,
|
|
5065
|
+
accessControl: "private",
|
|
5066
|
+
website: {
|
|
5067
|
+
indexDocument: "index.html",
|
|
5068
|
+
errorDocument: props.ssr ? void 0 : "error.html"
|
|
5069
|
+
}
|
|
5070
|
+
});
|
|
5071
|
+
const accessControl = new OriginAccessControl(`site-${id}`, {
|
|
5072
|
+
type: "s3"
|
|
5073
|
+
});
|
|
5074
|
+
const files = new Files(`site-${id}`, {
|
|
5075
|
+
directory: props.static
|
|
5076
|
+
});
|
|
5077
|
+
const uploadBucketAsset = new CustomResource(`site-${id}-upload-bucket-asset`, {
|
|
5078
|
+
serviceToken: bootstrap2.import("feature-upload-bucket-asset"),
|
|
5079
|
+
properties: {
|
|
5080
|
+
sourceBucketName: lazy(() => files.source?.bucket ?? ""),
|
|
5081
|
+
sourceObjectKey: lazy(() => files.source?.key ?? ""),
|
|
5082
|
+
sourceObjectVersion: lazy(() => files.source?.version ?? ""),
|
|
5083
|
+
destinationBucketName: bucket.name
|
|
5084
|
+
}
|
|
5085
|
+
}).dependsOn(bucket);
|
|
5086
|
+
const deleteBucket = new CustomResource(id, {
|
|
5087
|
+
serviceToken: bootstrap2.import("feature-delete-bucket"),
|
|
5088
|
+
properties: {
|
|
5089
|
+
bucketName: bucket.name
|
|
5090
|
+
}
|
|
5091
|
+
}).dependsOn(bucket);
|
|
5092
|
+
stack.add(bucket, files, uploadBucketAsset, deleteBucket, accessControl);
|
|
5093
|
+
origins.push(new Origin({
|
|
5094
|
+
id: "bucket",
|
|
5095
|
+
// domainName: select(2, split('/', bucket.url)),
|
|
5096
|
+
domainName: bucket.domainName,
|
|
5097
|
+
originAccessControlId: accessControl.id
|
|
5098
|
+
}));
|
|
5099
|
+
deps.push(bucket, accessControl);
|
|
5100
|
+
}
|
|
5101
|
+
if (props.ssr && props.static) {
|
|
5102
|
+
originGroups.push(new OriginGroup({
|
|
5103
|
+
id: "group",
|
|
5104
|
+
members: ["lambda", "bucket"],
|
|
5105
|
+
statusCodes: [403, 404]
|
|
5106
|
+
}));
|
|
5107
|
+
}
|
|
5108
|
+
const cache = new CachePolicy(id, {
|
|
5109
|
+
name: `site-${config.name}-${stack.name}-${id}`,
|
|
5110
|
+
minTtl: Duration.seconds(1),
|
|
5111
|
+
maxTtl: Duration.days(365),
|
|
5112
|
+
defaultTtl: Duration.days(1),
|
|
5113
|
+
...props.cache
|
|
4583
5114
|
});
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
5115
|
+
const originRequest = new OriginRequestPolicy(id, {
|
|
5116
|
+
name: `site-${config.name}-${stack.name}-${id}`,
|
|
5117
|
+
header: {
|
|
5118
|
+
behavior: "all-except",
|
|
5119
|
+
values: ["HOST"]
|
|
4588
5120
|
}
|
|
4589
5121
|
});
|
|
4590
|
-
|
|
5122
|
+
const domainName = props.subDomain ? `${props.subDomain}.${props.domain}` : props.domain;
|
|
5123
|
+
const hostedZoneId = bootstrap2.import(`hosted-zone-${props.domain}-id`);
|
|
5124
|
+
const certificateArn = bootstrap2.import(`us-east-certificate-${props.domain}-arn`);
|
|
5125
|
+
const responseHeaders = new ResponseHeadersPolicy(id, {
|
|
5126
|
+
name: `site-${config.name}-${stack.name}-${id}`,
|
|
5127
|
+
cors: props.cors,
|
|
5128
|
+
remove: ["server"]
|
|
5129
|
+
});
|
|
5130
|
+
const distribution = new Distribution(id, {
|
|
5131
|
+
name: `site-${config.name}-${stack.name}-${id}`,
|
|
5132
|
+
certificateArn,
|
|
5133
|
+
compress: true,
|
|
5134
|
+
aliases: [domainName],
|
|
5135
|
+
origins,
|
|
5136
|
+
originGroups,
|
|
5137
|
+
targetOriginId: props.ssr && props.static ? "group" : props.ssr ? "lambda" : "bucket",
|
|
5138
|
+
originRequestPolicyId: originRequest.id,
|
|
5139
|
+
cachePolicyId: cache.id,
|
|
5140
|
+
responseHeadersPolicyId: responseHeaders.id
|
|
5141
|
+
}).dependsOn(originRequest, responseHeaders, cache, ...deps);
|
|
5142
|
+
if (props.static) {
|
|
5143
|
+
const bucketPolicy = new BucketPolicy(`site-${id}`, {
|
|
5144
|
+
bucketName: bucket.name,
|
|
5145
|
+
statements: [
|
|
5146
|
+
{
|
|
5147
|
+
principal: "cloudfront.amazonaws.com",
|
|
5148
|
+
actions: ["s3:GetObject"],
|
|
5149
|
+
resources: [sub("${arn}/*", { arn: bucket.arn })],
|
|
5150
|
+
sourceArn: distribution.arn
|
|
5151
|
+
}
|
|
5152
|
+
// {
|
|
5153
|
+
// principal: distribution.id,
|
|
5154
|
+
// actions: [ 's3:GetObject' ],
|
|
5155
|
+
// resources: [ oac.attrId ]
|
|
5156
|
+
// }
|
|
5157
|
+
]
|
|
5158
|
+
}).dependsOn(bucket, distribution);
|
|
5159
|
+
stack.add(bucketPolicy);
|
|
5160
|
+
}
|
|
5161
|
+
const record = new RecordSet(`site-${id}`, {
|
|
5162
|
+
hostedZoneId,
|
|
5163
|
+
type: "A",
|
|
5164
|
+
name: domainName,
|
|
5165
|
+
alias: {
|
|
5166
|
+
dnsName: distribution.domainName,
|
|
5167
|
+
hostedZoneId: "Z2FDTNDATAQYW2"
|
|
5168
|
+
}
|
|
5169
|
+
}).dependsOn(distribution);
|
|
5170
|
+
stack.add(
|
|
5171
|
+
distribution,
|
|
5172
|
+
responseHeaders,
|
|
5173
|
+
originRequest,
|
|
5174
|
+
cache,
|
|
5175
|
+
record
|
|
5176
|
+
);
|
|
4591
5177
|
}
|
|
4592
|
-
|
|
4593
|
-
|
|
5178
|
+
}
|
|
5179
|
+
});
|
|
5180
|
+
|
|
5181
|
+
// src/plugins/feature.ts
|
|
5182
|
+
var featurePlugin = definePlugin({
|
|
5183
|
+
name: "feature",
|
|
5184
|
+
onApp({ config, bootstrap: bootstrap2 }) {
|
|
5185
|
+
const deleteBucketLambda = new Function("delete-bucket", {
|
|
5186
|
+
name: `${config.name}-delete-bucket`,
|
|
5187
|
+
code: Code.fromFeature("delete-bucket")
|
|
5188
|
+
}).enableLogs(Duration.days(3)).addPermissions({
|
|
5189
|
+
actions: ["s3:*"],
|
|
5190
|
+
resources: ["*"]
|
|
5191
|
+
});
|
|
5192
|
+
const uploadBucketAssetLambda = new Function("upload-bucket-asset", {
|
|
5193
|
+
name: `${config.name}-upload-bucket-asset`,
|
|
5194
|
+
code: Code.fromFeature("upload-bucket-asset"),
|
|
5195
|
+
memorySize: Size.gigaBytes(2)
|
|
5196
|
+
}).enableLogs(Duration.days(3)).addPermissions({
|
|
5197
|
+
actions: ["s3:*"],
|
|
5198
|
+
resources: ["*"]
|
|
5199
|
+
});
|
|
5200
|
+
bootstrap2.add(
|
|
5201
|
+
deleteBucketLambda,
|
|
5202
|
+
uploadBucketAssetLambda
|
|
5203
|
+
);
|
|
5204
|
+
bootstrap2.export("feature-delete-bucket", deleteBucketLambda.arn).export("feature-upload-bucket-asset", uploadBucketAssetLambda.arn);
|
|
5205
|
+
}
|
|
5206
|
+
});
|
|
5207
|
+
|
|
5208
|
+
// src/plugins/index.ts
|
|
5209
|
+
var defaultPlugins = [
|
|
5210
|
+
extendPlugin,
|
|
5211
|
+
featurePlugin,
|
|
5212
|
+
vpcPlugin,
|
|
5213
|
+
domainPlugin,
|
|
5214
|
+
functionPlugin,
|
|
5215
|
+
configPlugin,
|
|
5216
|
+
cachePlugin,
|
|
5217
|
+
cronPlugin,
|
|
5218
|
+
queuePlugin,
|
|
5219
|
+
tablePlugin,
|
|
5220
|
+
storePlugin,
|
|
5221
|
+
topicPlugin,
|
|
5222
|
+
pubsubPlugin,
|
|
5223
|
+
searchPlugin,
|
|
5224
|
+
graphqlPlugin,
|
|
5225
|
+
httpPlugin,
|
|
5226
|
+
restPlugin,
|
|
5227
|
+
sitePlugin,
|
|
5228
|
+
onFailurePlugin
|
|
5229
|
+
];
|
|
5230
|
+
|
|
5231
|
+
// src/formation/app.ts
|
|
5232
|
+
var App = class {
|
|
5233
|
+
constructor(name) {
|
|
5234
|
+
this.name = name;
|
|
5235
|
+
}
|
|
5236
|
+
list = /* @__PURE__ */ new Map();
|
|
5237
|
+
add(...stacks) {
|
|
5238
|
+
stacks.forEach((stack) => {
|
|
5239
|
+
this.list.set(stack.name, stack);
|
|
5240
|
+
stack.setApp(this);
|
|
5241
|
+
});
|
|
5242
|
+
return this;
|
|
5243
|
+
}
|
|
5244
|
+
find(resourceType) {
|
|
5245
|
+
return this.stacks.map((stack) => stack.find(resourceType)).flat();
|
|
5246
|
+
}
|
|
5247
|
+
[Symbol.iterator]() {
|
|
5248
|
+
return this.list.values();
|
|
5249
|
+
}
|
|
5250
|
+
get stacks() {
|
|
5251
|
+
return [...this.list.values()];
|
|
5252
|
+
}
|
|
5253
|
+
// get resources() {
|
|
5254
|
+
// return this.stacks.map(stack => stack.resources).flat()
|
|
5255
|
+
// }
|
|
4594
5256
|
};
|
|
4595
5257
|
|
|
4596
5258
|
// src/app.ts
|
|
@@ -4615,7 +5277,6 @@ var toApp = async (config, filters) => {
|
|
|
4615
5277
|
debug("Plugins detected:", plugins.map((plugin) => style.info(plugin.name)).join(", "));
|
|
4616
5278
|
const bootstrap2 = new Stack("bootstrap", config.region);
|
|
4617
5279
|
const usEastBootstrap = new Stack("us-east-bootstrap", "us-east-1");
|
|
4618
|
-
extendWithGlobalExports(config.name, usEastBootstrap, bootstrap2);
|
|
4619
5280
|
app.add(bootstrap2, usEastBootstrap);
|
|
4620
5281
|
debug("Run plugin onApp listeners");
|
|
4621
5282
|
const bindings = [];
|
|
@@ -4697,7 +5358,7 @@ var toApp = async (config, filters) => {
|
|
|
4697
5358
|
};
|
|
4698
5359
|
|
|
4699
5360
|
// src/config.ts
|
|
4700
|
-
import { join as
|
|
5361
|
+
import { join as join6 } from "path";
|
|
4701
5362
|
|
|
4702
5363
|
// src/util/account.ts
|
|
4703
5364
|
import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";
|
|
@@ -4716,17 +5377,17 @@ var getCredentials = (profile) => {
|
|
|
4716
5377
|
};
|
|
4717
5378
|
|
|
4718
5379
|
// src/schema/app.ts
|
|
4719
|
-
import { z as
|
|
5380
|
+
import { z as z28 } from "zod";
|
|
4720
5381
|
|
|
4721
5382
|
// src/schema/stack.ts
|
|
4722
|
-
import { z as
|
|
4723
|
-
var StackSchema =
|
|
5383
|
+
import { z as z25 } from "zod";
|
|
5384
|
+
var StackSchema = z25.object({
|
|
4724
5385
|
name: ResourceIdSchema,
|
|
4725
|
-
depends:
|
|
5386
|
+
depends: z25.array(z25.lazy(() => StackSchema)).optional()
|
|
4726
5387
|
});
|
|
4727
5388
|
|
|
4728
5389
|
// src/schema/region.ts
|
|
4729
|
-
import { z as
|
|
5390
|
+
import { z as z26 } from "zod";
|
|
4730
5391
|
var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
|
|
4731
5392
|
var AF = ["af-south-1"];
|
|
4732
5393
|
var AP = ["ap-east-1", "ap-south-2", "ap-southeast-3", "ap-southeast-4", "ap-south-1", "ap-northeast-3", "ap-northeast-2", "ap-southeast-1", "ap-southeast-2", "ap-northeast-1"];
|
|
@@ -4743,41 +5404,41 @@ var regions = [
|
|
|
4743
5404
|
...ME,
|
|
4744
5405
|
...SA
|
|
4745
5406
|
];
|
|
4746
|
-
var RegionSchema =
|
|
5407
|
+
var RegionSchema = z26.enum(regions);
|
|
4747
5408
|
|
|
4748
5409
|
// src/schema/plugin.ts
|
|
4749
|
-
import { z as
|
|
4750
|
-
var PluginSchema =
|
|
4751
|
-
name:
|
|
4752
|
-
schema:
|
|
5410
|
+
import { z as z27 } from "zod";
|
|
5411
|
+
var PluginSchema = z27.object({
|
|
5412
|
+
name: z27.string(),
|
|
5413
|
+
schema: z27.custom().optional(),
|
|
4753
5414
|
// depends: z.array(z.lazy(() => PluginSchema)).optional(),
|
|
4754
|
-
onApp:
|
|
4755
|
-
onStack:
|
|
4756
|
-
onResource:
|
|
5415
|
+
onApp: z27.function().returns(z27.void()).optional(),
|
|
5416
|
+
onStack: z27.function().returns(z27.any()).optional(),
|
|
5417
|
+
onResource: z27.function().returns(z27.any()).optional()
|
|
4757
5418
|
// bind: z.function().optional(),
|
|
4758
5419
|
});
|
|
4759
5420
|
|
|
4760
5421
|
// src/schema/app.ts
|
|
4761
|
-
var AppSchema =
|
|
5422
|
+
var AppSchema = z28.object({
|
|
4762
5423
|
/** App name */
|
|
4763
5424
|
name: ResourceIdSchema,
|
|
4764
5425
|
/** The AWS region to deploy to. */
|
|
4765
5426
|
region: RegionSchema,
|
|
4766
5427
|
/** The AWS profile to deploy to. */
|
|
4767
|
-
profile:
|
|
5428
|
+
profile: z28.string(),
|
|
4768
5429
|
/** The deployment stage.
|
|
4769
5430
|
* @default 'prod'
|
|
4770
5431
|
*/
|
|
4771
|
-
stage:
|
|
5432
|
+
stage: z28.string().regex(/^[a-z]+$/).default("prod"),
|
|
4772
5433
|
/** Default properties. */
|
|
4773
|
-
defaults:
|
|
5434
|
+
defaults: z28.object({}).default({}),
|
|
4774
5435
|
/** The application stacks. */
|
|
4775
|
-
stacks:
|
|
5436
|
+
stacks: z28.array(StackSchema).min(1).refine((stacks) => {
|
|
4776
5437
|
const unique = new Set(stacks.map((stack) => stack.name));
|
|
4777
5438
|
return unique.size === stacks.length;
|
|
4778
5439
|
}, "Must be an array of unique stacks"),
|
|
4779
5440
|
/** Custom plugins. */
|
|
4780
|
-
plugins:
|
|
5441
|
+
plugins: z28.array(PluginSchema).optional()
|
|
4781
5442
|
});
|
|
4782
5443
|
|
|
4783
5444
|
// src/util/import.ts
|
|
@@ -4785,7 +5446,7 @@ import { rollup as rollup2, watch } from "rollup";
|
|
|
4785
5446
|
import { swc as swc2 } from "rollup-plugin-swc3";
|
|
4786
5447
|
import replace from "rollup-plugin-replace";
|
|
4787
5448
|
import { EventIterator } from "event-iterator";
|
|
4788
|
-
import { dirname as dirname2, join as
|
|
5449
|
+
import { dirname as dirname2, join as join5 } from "path";
|
|
4789
5450
|
import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
4790
5451
|
var importFile = async (path) => {
|
|
4791
5452
|
const bundle = await rollup2({
|
|
@@ -4805,7 +5466,7 @@ var importFile = async (path) => {
|
|
|
4805
5466
|
})
|
|
4806
5467
|
]
|
|
4807
5468
|
});
|
|
4808
|
-
const outputFile =
|
|
5469
|
+
const outputFile = join5(directories.cache, "config.js");
|
|
4809
5470
|
const result = await bundle.generate({
|
|
4810
5471
|
format: "esm",
|
|
4811
5472
|
exports: "default"
|
|
@@ -4856,7 +5517,7 @@ var watchFile = (path) => {
|
|
|
4856
5517
|
event.result.close();
|
|
4857
5518
|
const output = result.output[0];
|
|
4858
5519
|
const code = output.code;
|
|
4859
|
-
const outputFile =
|
|
5520
|
+
const outputFile = join5(directories.cache, "config.js");
|
|
4860
5521
|
await mkdir2(directories.cache, { recursive: true });
|
|
4861
5522
|
await writeFile2(outputFile, code);
|
|
4862
5523
|
debug("Save config file:", style.info(outputFile));
|
|
@@ -4874,7 +5535,7 @@ var watchFile = (path) => {
|
|
|
4874
5535
|
};
|
|
4875
5536
|
|
|
4876
5537
|
// src/config.ts
|
|
4877
|
-
import { z as
|
|
5538
|
+
import { z as z29 } from "zod";
|
|
4878
5539
|
var ConfigError = class extends Error {
|
|
4879
5540
|
constructor(error, data) {
|
|
4880
5541
|
super(error.message);
|
|
@@ -4889,7 +5550,7 @@ var importConfig = async (options) => {
|
|
|
4889
5550
|
setRoot(root2);
|
|
4890
5551
|
debug("CWD:", style.info(root2));
|
|
4891
5552
|
debug("Import config file");
|
|
4892
|
-
const fileName =
|
|
5553
|
+
const fileName = join6(root2, configFile);
|
|
4893
5554
|
const module = await importFile(fileName);
|
|
4894
5555
|
const appConfig = typeof module.default === "function" ? await module.default(options) : module.default;
|
|
4895
5556
|
debug("Validate config file");
|
|
@@ -4907,7 +5568,7 @@ var importConfig = async (options) => {
|
|
|
4907
5568
|
try {
|
|
4908
5569
|
config = await schema2.parseAsync(appConfig);
|
|
4909
5570
|
} catch (error) {
|
|
4910
|
-
if (error instanceof
|
|
5571
|
+
if (error instanceof z29.ZodError) {
|
|
4911
5572
|
throw new ConfigError(error, appConfig);
|
|
4912
5573
|
}
|
|
4913
5574
|
throw error;
|
|
@@ -4930,7 +5591,7 @@ var watchConfig = async function* (options) {
|
|
|
4930
5591
|
setRoot(root2);
|
|
4931
5592
|
debug("CWD:", style.info(root2));
|
|
4932
5593
|
debug("Import config file");
|
|
4933
|
-
const fileName =
|
|
5594
|
+
const fileName = join6(root2, configFile);
|
|
4934
5595
|
for await (const module of watchFile(fileName)) {
|
|
4935
5596
|
const appConfig = typeof module.default === "function" ? await module.default(options) : module.default;
|
|
4936
5597
|
debug("Validate config file");
|
|
@@ -4948,7 +5609,7 @@ var watchConfig = async function* (options) {
|
|
|
4948
5609
|
try {
|
|
4949
5610
|
config = await schema2.parseAsync(appConfig);
|
|
4950
5611
|
} catch (error) {
|
|
4951
|
-
if (error instanceof
|
|
5612
|
+
if (error instanceof z29.ZodError) {
|
|
4952
5613
|
throw new ConfigError(error, appConfig);
|
|
4953
5614
|
}
|
|
4954
5615
|
throw error;
|
|
@@ -5545,7 +6206,7 @@ var flexLine = (term, left, right, reserveSpace = 0) => {
|
|
|
5545
6206
|
};
|
|
5546
6207
|
|
|
5547
6208
|
// src/cli/ui/complex/builder.ts
|
|
5548
|
-
import { dirname as dirname3, join as
|
|
6209
|
+
import { dirname as dirname3, join as join7 } from "path";
|
|
5549
6210
|
var assetBuilder = (app) => {
|
|
5550
6211
|
return async (term) => {
|
|
5551
6212
|
const assets = [];
|
|
@@ -5608,7 +6269,7 @@ var assetBuilder = (app) => {
|
|
|
5608
6269
|
try {
|
|
5609
6270
|
const data = await asset.build({
|
|
5610
6271
|
async write(file, data2) {
|
|
5611
|
-
const fullpath =
|
|
6272
|
+
const fullpath = join7(directories.asset, asset.type, app.name, stack.name, asset.id, file);
|
|
5612
6273
|
const basepath = dirname3(fullpath);
|
|
5613
6274
|
await mkdir3(basepath, { recursive: true });
|
|
5614
6275
|
await writeFile3(fullpath, data2);
|
|
@@ -5656,14 +6317,14 @@ var cleanUp = async () => {
|
|
|
5656
6317
|
|
|
5657
6318
|
// src/cli/ui/complex/template.ts
|
|
5658
6319
|
import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
|
|
5659
|
-
import { join as
|
|
6320
|
+
import { join as join8 } from "path";
|
|
5660
6321
|
var templateBuilder = (app) => {
|
|
5661
6322
|
return async (term) => {
|
|
5662
6323
|
const done = term.out.write(loadingDialog("Building stack templates..."));
|
|
5663
6324
|
await Promise.all(app.stacks.map(async (stack) => {
|
|
5664
6325
|
const template = stack.toString(true);
|
|
5665
|
-
const path =
|
|
5666
|
-
const file =
|
|
6326
|
+
const path = join8(directories.template, app.name);
|
|
6327
|
+
const file = join8(path, `${stack.name}.json`);
|
|
5667
6328
|
await mkdir5(path, { recursive: true });
|
|
5668
6329
|
await writeFile4(file, template);
|
|
5669
6330
|
}));
|
|
@@ -5708,7 +6369,7 @@ var bootstrapStack = (account, region) => {
|
|
|
5708
6369
|
stack.add(new Bucket("assets", {
|
|
5709
6370
|
name: assetBucketName(account, region),
|
|
5710
6371
|
accessControl: "private",
|
|
5711
|
-
|
|
6372
|
+
versioning: true
|
|
5712
6373
|
}));
|
|
5713
6374
|
stack.export("version", version);
|
|
5714
6375
|
app.add(stack);
|
|
@@ -5878,6 +6539,7 @@ var StackClient = class {
|
|
|
5878
6539
|
});
|
|
5879
6540
|
debug("Status for:", style.info(name), "is", style.attr(stack.StackStatus));
|
|
5880
6541
|
return {
|
|
6542
|
+
id: stack.StackId,
|
|
5881
6543
|
status: stack.StackStatus,
|
|
5882
6544
|
reason: stack.StackStatusReason,
|
|
5883
6545
|
outputs,
|
|
@@ -5924,10 +6586,10 @@ var StackClient = class {
|
|
|
5924
6586
|
maxWaitTime: this.maxWaitTime,
|
|
5925
6587
|
maxDelay: this.maxDelay
|
|
5926
6588
|
}, {
|
|
5927
|
-
StackName:
|
|
6589
|
+
StackName: data.id
|
|
5928
6590
|
});
|
|
5929
6591
|
} catch (_) {
|
|
5930
|
-
const reason = await this.getFailureReason(
|
|
6592
|
+
const reason = await this.getFailureReason(data.id, region);
|
|
5931
6593
|
throw new Error(reason);
|
|
5932
6594
|
}
|
|
5933
6595
|
}
|
|
@@ -6185,7 +6847,7 @@ var status = (program2) => {
|
|
|
6185
6847
|
|
|
6186
6848
|
// src/cli/ui/complex/publisher.ts
|
|
6187
6849
|
import { readFile as readFile3 } from "fs/promises";
|
|
6188
|
-
import { join as
|
|
6850
|
+
import { join as join9 } from "path";
|
|
6189
6851
|
import { GetObjectCommand, ObjectCannedACL as ObjectCannedACL2, PutObjectCommand as PutObjectCommand2, S3Client as S3Client2, StorageClass as StorageClass2 } from "@aws-sdk/client-s3";
|
|
6190
6852
|
var assetPublisher = (config, app) => {
|
|
6191
6853
|
const client = new S3Client2({
|
|
@@ -6199,12 +6861,12 @@ var assetPublisher = (config, app) => {
|
|
|
6199
6861
|
await Promise.all([...stack.assets].map(async (asset) => {
|
|
6200
6862
|
await asset.publish?.({
|
|
6201
6863
|
async read(file) {
|
|
6202
|
-
const path =
|
|
6864
|
+
const path = join9(directories.asset, asset.type, app.name, stack.name, asset.id, file);
|
|
6203
6865
|
const data = await readFile3(path);
|
|
6204
6866
|
return data;
|
|
6205
6867
|
},
|
|
6206
6868
|
async publish(name, data, hash) {
|
|
6207
|
-
const key = `${app.name}/${stack.name}
|
|
6869
|
+
const key = `${app.name}/${stack.name}/${asset.type}/${name}`;
|
|
6208
6870
|
const bucket = assetBucketName(config.account, config.region);
|
|
6209
6871
|
let getResult;
|
|
6210
6872
|
try {
|
|
@@ -6444,16 +7106,6 @@ var secrets = (program2) => {
|
|
|
6444
7106
|
commands.forEach((cb) => cb(command));
|
|
6445
7107
|
};
|
|
6446
7108
|
|
|
6447
|
-
// src/cli/command/test.ts
|
|
6448
|
-
var test = (program2) => {
|
|
6449
|
-
program2.command("test").action(async () => {
|
|
6450
|
-
await layout(async (config) => {
|
|
6451
|
-
const app = new App("test");
|
|
6452
|
-
const name = "test5";
|
|
6453
|
-
});
|
|
6454
|
-
});
|
|
6455
|
-
};
|
|
6456
|
-
|
|
6457
7109
|
// src/cli/command/types.ts
|
|
6458
7110
|
var types = (program2) => {
|
|
6459
7111
|
program2.command("types").description("Generate type definition files").action(async () => {
|
|
@@ -6477,6 +7129,48 @@ var dev = (program2) => {
|
|
|
6477
7129
|
});
|
|
6478
7130
|
};
|
|
6479
7131
|
|
|
7132
|
+
// src/cli/command/delete.ts
|
|
7133
|
+
var del2 = (program2) => {
|
|
7134
|
+
program2.command("delete").argument("[stacks...]", "Optionally filter stacks to delete").description("Delete your app from AWS").action(async (filters) => {
|
|
7135
|
+
await layout(async (config, write) => {
|
|
7136
|
+
const { app, deploymentLine } = await toApp(config, filters);
|
|
7137
|
+
const deletingLine = deploymentLine.reverse();
|
|
7138
|
+
const stackNames = app.stacks.map((stack) => stack.name);
|
|
7139
|
+
const formattedFilter = stackNames.map((i) => style.info(i)).join(style.placeholder(", "));
|
|
7140
|
+
debug("Stacks to delete", formattedFilter);
|
|
7141
|
+
const deployAll = filters.length === 0;
|
|
7142
|
+
const deploySingle = filters.length === 1;
|
|
7143
|
+
const confirm = await write(confirmPrompt(deployAll ? `Are you sure you want to ${style.error("delete")} ${style.warning("all")} stacks?` : deploySingle ? `Are you sure you want to ${style.error("delete")} the ${formattedFilter} stack?` : `Are you sure you want to ${style.error("delete")} the [ ${formattedFilter} ] stacks?`));
|
|
7144
|
+
if (!confirm) {
|
|
7145
|
+
throw new Cancelled();
|
|
7146
|
+
}
|
|
7147
|
+
const doneDeploying = write(loadingDialog("Deleting stacks from AWS..."));
|
|
7148
|
+
const client = new StackClient(app, config.account, config.region, config.credentials);
|
|
7149
|
+
const ui = write(stacksDeployer(deletingLine));
|
|
7150
|
+
for (const line2 of deletingLine) {
|
|
7151
|
+
const results = await Promise.allSettled(line2.map(async (stack) => {
|
|
7152
|
+
const item = ui[stack.name];
|
|
7153
|
+
item.start("deleting");
|
|
7154
|
+
try {
|
|
7155
|
+
await client.delete(stack.name, stack.region);
|
|
7156
|
+
} catch (error) {
|
|
7157
|
+
debugError(error);
|
|
7158
|
+
item.fail("failed");
|
|
7159
|
+
throw error;
|
|
7160
|
+
}
|
|
7161
|
+
item.done("deleted");
|
|
7162
|
+
}));
|
|
7163
|
+
for (const result of results) {
|
|
7164
|
+
if (result.status === "rejected") {
|
|
7165
|
+
throw result.reason;
|
|
7166
|
+
}
|
|
7167
|
+
}
|
|
7168
|
+
}
|
|
7169
|
+
doneDeploying("Done deleting stacks from AWS");
|
|
7170
|
+
});
|
|
7171
|
+
});
|
|
7172
|
+
};
|
|
7173
|
+
|
|
6480
7174
|
// src/cli/program.ts
|
|
6481
7175
|
var program = new Command();
|
|
6482
7176
|
program.name(logo().join("").replace(/\s+/, ""));
|
|
@@ -6498,9 +7192,10 @@ var commands2 = [
|
|
|
6498
7192
|
types,
|
|
6499
7193
|
build,
|
|
6500
7194
|
deploy,
|
|
7195
|
+
del2,
|
|
6501
7196
|
dev,
|
|
6502
|
-
secrets
|
|
6503
|
-
test
|
|
7197
|
+
secrets
|
|
7198
|
+
// test,
|
|
6504
7199
|
// diff,
|
|
6505
7200
|
// remove,
|
|
6506
7201
|
];
|