@awsless/awsless 0.0.44 → 0.0.45
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 +1140 -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,9 +1223,12 @@ 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({
|
|
@@ -1102,6 +1238,11 @@ var FunctionSchema = z6.union([
|
|
|
1102
1238
|
* @default false
|
|
1103
1239
|
*/
|
|
1104
1240
|
vpc: z6.boolean().optional(),
|
|
1241
|
+
/** Enable logging to a CloudWatch log group.
|
|
1242
|
+
* Providing a duration value will set the log retention time.
|
|
1243
|
+
* @default false
|
|
1244
|
+
*/
|
|
1245
|
+
log: LogSchema.optional(),
|
|
1105
1246
|
/** The amount of time that Lambda allows a function to run before stopping it.
|
|
1106
1247
|
* You can specify a size value from 1 second to 15 minutes.
|
|
1107
1248
|
* @default '10 seconds'
|
|
@@ -1158,6 +1299,10 @@ var schema = z6.object({
|
|
|
1158
1299
|
* @default false
|
|
1159
1300
|
*/
|
|
1160
1301
|
vpc: z6.boolean().default(false),
|
|
1302
|
+
/** Enable logging to a CloudWatch log group.
|
|
1303
|
+
* @default false
|
|
1304
|
+
*/
|
|
1305
|
+
log: LogSchema.default(false),
|
|
1161
1306
|
/** The amount of time that Lambda allows a function to run before stopping it.
|
|
1162
1307
|
* You can specify a size value from 1 second to 15 minutes.
|
|
1163
1308
|
* @default '10 seconds'
|
|
@@ -1270,22 +1415,26 @@ var functionPlugin = definePlugin({
|
|
|
1270
1415
|
var toLambdaFunction = (ctx, id, fileOrProps) => {
|
|
1271
1416
|
const config = ctx.config;
|
|
1272
1417
|
const stack = ctx.stack;
|
|
1418
|
+
const bootstrap2 = ctx.bootstrap;
|
|
1273
1419
|
const props = typeof fileOrProps === "string" ? { ...config.defaults?.function, file: fileOrProps } : { ...config.defaults?.function, ...fileOrProps };
|
|
1274
1420
|
const lambda = new Function(id, {
|
|
1275
|
-
name: `${config.name}
|
|
1421
|
+
name: `${config.name}-${stack.name}-${id}`,
|
|
1276
1422
|
code: Code.fromFile(id, props.file),
|
|
1277
1423
|
...props,
|
|
1278
1424
|
vpc: void 0
|
|
1279
1425
|
});
|
|
1280
1426
|
lambda.addEnvironment("APP", config.name).addEnvironment("STAGE", config.stage).addEnvironment("STACK", stack.name);
|
|
1427
|
+
if (props.log) {
|
|
1428
|
+
lambda.enableLogs(props.log instanceof Duration ? props.log : void 0);
|
|
1429
|
+
}
|
|
1281
1430
|
if (props.vpc) {
|
|
1282
1431
|
lambda.setVpc({
|
|
1283
1432
|
securityGroupIds: [
|
|
1284
|
-
|
|
1433
|
+
bootstrap2.import(`vpc-security-group-id`)
|
|
1285
1434
|
],
|
|
1286
1435
|
subnetIds: [
|
|
1287
|
-
|
|
1288
|
-
|
|
1436
|
+
bootstrap2.import(`public-subnet-1`),
|
|
1437
|
+
bootstrap2.import(`public-subnet-2`)
|
|
1289
1438
|
]
|
|
1290
1439
|
}).addPermissions({
|
|
1291
1440
|
actions: [
|
|
@@ -1298,9 +1447,6 @@ var toLambdaFunction = (ctx, id, fileOrProps) => {
|
|
|
1298
1447
|
resources: ["*"]
|
|
1299
1448
|
});
|
|
1300
1449
|
}
|
|
1301
|
-
if (props.runtime.startsWith("nodejs")) {
|
|
1302
|
-
lambda.addEnvironment("AWS_NODEJS_CONNECTION_REUSE_ENABLED", "1");
|
|
1303
|
-
}
|
|
1304
1450
|
ctx.bind((other) => {
|
|
1305
1451
|
other.addPermissions(lambda.permissions);
|
|
1306
1452
|
});
|
|
@@ -1340,6 +1486,7 @@ var Rule = class extends Resource {
|
|
|
1340
1486
|
};
|
|
1341
1487
|
|
|
1342
1488
|
// src/formation/resource/lambda/permission.ts
|
|
1489
|
+
import { constantCase as constantCase3 } from "change-case";
|
|
1343
1490
|
var Permission2 = class extends Resource {
|
|
1344
1491
|
constructor(logicalId, props) {
|
|
1345
1492
|
super("AWS::Lambda::Permission", logicalId);
|
|
@@ -1350,6 +1497,7 @@ var Permission2 = class extends Resource {
|
|
|
1350
1497
|
FunctionName: this.props.functionArn,
|
|
1351
1498
|
Action: this.props.action || "lambda:InvokeFunction",
|
|
1352
1499
|
Principal: this.props.principal,
|
|
1500
|
+
...this.attr("FunctionUrlAuthType", this.props.urlAuthType && constantCase3(this.props.urlAuthType)),
|
|
1353
1501
|
...this.attr("SourceArn", this.props.sourceArn)
|
|
1354
1502
|
};
|
|
1355
1503
|
}
|
|
@@ -1476,7 +1624,7 @@ var Queue = class extends Resource {
|
|
|
1476
1624
|
};
|
|
1477
1625
|
|
|
1478
1626
|
// src/formation/resource/lambda/event-source-mapping.ts
|
|
1479
|
-
import { constantCase as
|
|
1627
|
+
import { constantCase as constantCase4 } from "change-case";
|
|
1480
1628
|
var EventSourceMapping = class extends Resource {
|
|
1481
1629
|
constructor(logicalId, props) {
|
|
1482
1630
|
super("AWS::Lambda::EventSourceMapping", logicalId);
|
|
@@ -1498,7 +1646,7 @@ var EventSourceMapping = class extends Resource {
|
|
|
1498
1646
|
...this.attr("ParallelizationFactor", this.props.parallelizationFactor),
|
|
1499
1647
|
...this.attr("TumblingWindowInSeconds", this.props.tumblingWindow?.toSeconds()),
|
|
1500
1648
|
...this.attr("BisectBatchOnFunctionError", this.props.bisectBatchOnError),
|
|
1501
|
-
...this.attr("StartingPosition", this.props.startingPosition &&
|
|
1649
|
+
...this.attr("StartingPosition", this.props.startingPosition && constantCase4(this.props.startingPosition)),
|
|
1502
1650
|
...this.attr("StartingPositionTimestamp", this.props.startingPositionTimestamp),
|
|
1503
1651
|
...this.props.maxConcurrency ? {
|
|
1504
1652
|
ScalingConfig: {
|
|
@@ -1539,7 +1687,7 @@ var SqsEventSource = class extends Group {
|
|
|
1539
1687
|
};
|
|
1540
1688
|
|
|
1541
1689
|
// src/plugins/queue.ts
|
|
1542
|
-
import { camelCase as camelCase3, constantCase as
|
|
1690
|
+
import { camelCase as camelCase3, constantCase as constantCase5 } from "change-case";
|
|
1543
1691
|
import { relative as relative3 } from "path";
|
|
1544
1692
|
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
1693
|
var VisibilityTimeoutSchema = DurationSchema.refine(durationMax(Duration.hours(12)), "Maximum visibility timeout is 12 hours");
|
|
@@ -1694,7 +1842,7 @@ var queuePlugin = definePlugin({
|
|
|
1694
1842
|
stack.add(queue2, lambda, source);
|
|
1695
1843
|
bind((lambda2) => {
|
|
1696
1844
|
lambda2.addPermissions(queue2.permissions);
|
|
1697
|
-
lambda2.addEnvironment(`QUEUE_${
|
|
1845
|
+
lambda2.addEnvironment(`QUEUE_${constantCase5(stack.name)}_${constantCase5(id)}_URL`, queue2.url);
|
|
1698
1846
|
});
|
|
1699
1847
|
}
|
|
1700
1848
|
}
|
|
@@ -1704,7 +1852,7 @@ var queuePlugin = definePlugin({
|
|
|
1704
1852
|
import { z as z9 } from "zod";
|
|
1705
1853
|
|
|
1706
1854
|
// src/formation/resource/dynamodb/table.ts
|
|
1707
|
-
import { constantCase as
|
|
1855
|
+
import { constantCase as constantCase6 } from "change-case";
|
|
1708
1856
|
var Table = class extends Resource {
|
|
1709
1857
|
constructor(logicalId, props) {
|
|
1710
1858
|
super("AWS::DynamoDB::Table", logicalId);
|
|
@@ -1777,7 +1925,7 @@ var Table = class extends Resource {
|
|
|
1777
1925
|
return {
|
|
1778
1926
|
TableName: this.name,
|
|
1779
1927
|
BillingMode: "PAY_PER_REQUEST",
|
|
1780
|
-
TableClass:
|
|
1928
|
+
TableClass: constantCase6(this.props.class || "standard"),
|
|
1781
1929
|
PointInTimeRecoverySpecification: {
|
|
1782
1930
|
PointInTimeRecoveryEnabled: this.props.pointInTimeRecovery || false
|
|
1783
1931
|
},
|
|
@@ -1788,7 +1936,7 @@ var Table = class extends Resource {
|
|
|
1788
1936
|
AttributeDefinitions: this.attributeDefinitions(),
|
|
1789
1937
|
...this.props.stream ? {
|
|
1790
1938
|
StreamSpecification: {
|
|
1791
|
-
StreamViewType:
|
|
1939
|
+
StreamViewType: constantCase6(this.props.stream)
|
|
1792
1940
|
}
|
|
1793
1941
|
} : {},
|
|
1794
1942
|
...this.props.timeToLiveAttribute ? {
|
|
@@ -1805,7 +1953,7 @@ var Table = class extends Resource {
|
|
|
1805
1953
|
...props.sort ? [{ KeyType: "RANGE", AttributeName: props.sort }] : []
|
|
1806
1954
|
],
|
|
1807
1955
|
Projection: {
|
|
1808
|
-
ProjectionType:
|
|
1956
|
+
ProjectionType: constantCase6(props.projection || "all")
|
|
1809
1957
|
}
|
|
1810
1958
|
}))
|
|
1811
1959
|
} : {}
|
|
@@ -1931,21 +2079,6 @@ var tablePlugin = definePlugin({
|
|
|
1931
2079
|
projection: z9.enum(["all", "keys-only"]).default("all")
|
|
1932
2080
|
})).optional()
|
|
1933
2081
|
})
|
|
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
2082
|
).optional()
|
|
1950
2083
|
}).array()
|
|
1951
2084
|
}),
|
|
@@ -2000,11 +2133,20 @@ var Bucket = class extends Resource {
|
|
|
2000
2133
|
}
|
|
2001
2134
|
name;
|
|
2002
2135
|
get arn() {
|
|
2003
|
-
return
|
|
2136
|
+
return getAtt(this.logicalId, "Arn");
|
|
2004
2137
|
}
|
|
2005
2138
|
get domainName() {
|
|
2006
2139
|
return getAtt(this.logicalId, "DomainName");
|
|
2007
2140
|
}
|
|
2141
|
+
get dealStackDomainName() {
|
|
2142
|
+
return getAtt(this.logicalId, "DualStackDomainName");
|
|
2143
|
+
}
|
|
2144
|
+
get regionalDomainName() {
|
|
2145
|
+
return getAtt(this.logicalId, "RegionalDomainName");
|
|
2146
|
+
}
|
|
2147
|
+
get url() {
|
|
2148
|
+
return getAtt(this.logicalId, "WebsiteURL");
|
|
2149
|
+
}
|
|
2008
2150
|
get permissions() {
|
|
2009
2151
|
return {
|
|
2010
2152
|
actions: [
|
|
@@ -2026,15 +2168,38 @@ var Bucket = class extends Resource {
|
|
|
2026
2168
|
return {
|
|
2027
2169
|
BucketName: this.name,
|
|
2028
2170
|
AccessControl: pascalCase2(this.props.accessControl ?? "private"),
|
|
2029
|
-
...this.props.
|
|
2171
|
+
...this.props.versioning ? {
|
|
2030
2172
|
VersioningConfiguration: {
|
|
2031
2173
|
Status: "Enabled"
|
|
2032
2174
|
}
|
|
2175
|
+
} : {},
|
|
2176
|
+
...this.props.website ? {
|
|
2177
|
+
WebsiteConfiguration: {
|
|
2178
|
+
...this.attr("IndexDocument", this.props.website.indexDocument),
|
|
2179
|
+
...this.attr("ErrorDocument", this.props.website.errorDocument)
|
|
2180
|
+
}
|
|
2033
2181
|
} : {}
|
|
2034
2182
|
};
|
|
2035
2183
|
}
|
|
2036
2184
|
};
|
|
2037
2185
|
|
|
2186
|
+
// src/formation/resource/cloud-formation/custom-resource.ts
|
|
2187
|
+
var CustomResource = class extends Resource {
|
|
2188
|
+
constructor(logicalId, props) {
|
|
2189
|
+
super("AWS::CloudFormation::CustomResource", logicalId);
|
|
2190
|
+
this.props = props;
|
|
2191
|
+
}
|
|
2192
|
+
getAtt(name) {
|
|
2193
|
+
return getAtt(this.logicalId, name);
|
|
2194
|
+
}
|
|
2195
|
+
properties() {
|
|
2196
|
+
return {
|
|
2197
|
+
ServiceToken: this.props.serviceToken,
|
|
2198
|
+
...this.props.properties
|
|
2199
|
+
};
|
|
2200
|
+
}
|
|
2201
|
+
};
|
|
2202
|
+
|
|
2038
2203
|
// src/plugins/store.ts
|
|
2039
2204
|
var storePlugin = definePlugin({
|
|
2040
2205
|
name: "store",
|
|
@@ -2061,13 +2226,19 @@ var storePlugin = definePlugin({
|
|
|
2061
2226
|
}
|
|
2062
2227
|
return types2.toString();
|
|
2063
2228
|
},
|
|
2064
|
-
onStack({ config, stack, stackConfig, bind }) {
|
|
2229
|
+
onStack({ config, stack, stackConfig, bootstrap: bootstrap2, bind }) {
|
|
2065
2230
|
for (const id of stackConfig.stores || []) {
|
|
2066
2231
|
const bucket = new Bucket(id, {
|
|
2067
|
-
name:
|
|
2232
|
+
name: `store-${config.name}-${stack.name}-${id}`,
|
|
2068
2233
|
accessControl: "private"
|
|
2069
2234
|
});
|
|
2070
|
-
|
|
2235
|
+
const custom = new CustomResource(id, {
|
|
2236
|
+
serviceToken: bootstrap2.import("feature-delete-bucket"),
|
|
2237
|
+
properties: {
|
|
2238
|
+
bucketName: bucket.name
|
|
2239
|
+
}
|
|
2240
|
+
}).dependsOn(bucket);
|
|
2241
|
+
stack.add(bucket, custom);
|
|
2071
2242
|
bind((lambda) => {
|
|
2072
2243
|
lambda.addPermissions(bucket.permissions);
|
|
2073
2244
|
});
|
|
@@ -2371,7 +2542,7 @@ var toArray = (value) => {
|
|
|
2371
2542
|
import { paramCase as paramCase4 } from "change-case";
|
|
2372
2543
|
|
|
2373
2544
|
// src/formation/resource/appsync/graphql-api.ts
|
|
2374
|
-
import { constantCase as
|
|
2545
|
+
import { constantCase as constantCase7 } from "change-case";
|
|
2375
2546
|
var GraphQLApi = class extends Resource {
|
|
2376
2547
|
constructor(logicalId, props) {
|
|
2377
2548
|
super("AWS::AppSync::GraphQLApi", logicalId);
|
|
@@ -2403,7 +2574,7 @@ var GraphQLApi = class extends Resource {
|
|
|
2403
2574
|
properties() {
|
|
2404
2575
|
return {
|
|
2405
2576
|
Name: this.name,
|
|
2406
|
-
AuthenticationType:
|
|
2577
|
+
AuthenticationType: constantCase7(this.props.authenticationType || "api-key"),
|
|
2407
2578
|
AdditionalAuthenticationProviders: this.lambdaAuthProviders.map((provider) => ({
|
|
2408
2579
|
AuthenticationType: "AWS_LAMBDA",
|
|
2409
2580
|
LambdaAuthorizerConfig: {
|
|
@@ -2750,7 +2921,7 @@ var graphqlPlugin = definePlugin({
|
|
|
2750
2921
|
}).array()
|
|
2751
2922
|
}),
|
|
2752
2923
|
onApp(ctx) {
|
|
2753
|
-
const { config, bootstrap: bootstrap2
|
|
2924
|
+
const { config, bootstrap: bootstrap2 } = ctx;
|
|
2754
2925
|
const apis = /* @__PURE__ */ new Set();
|
|
2755
2926
|
for (const stackConfig of config.stacks) {
|
|
2756
2927
|
for (const id of Object.keys(stackConfig.graphql || {})) {
|
|
@@ -2783,8 +2954,9 @@ var graphqlPlugin = definePlugin({
|
|
|
2783
2954
|
}
|
|
2784
2955
|
if (props.domain) {
|
|
2785
2956
|
const domainName = props.subDomain ? `${props.subDomain}.${props.domain}` : props.domain;
|
|
2786
|
-
const hostedZoneId =
|
|
2787
|
-
const certificateArn =
|
|
2957
|
+
const hostedZoneId = bootstrap2.import(`hosted-zone-${props.domain}-id`);
|
|
2958
|
+
const certificateArn = bootstrap2.import(`us-east-certificate-${props.domain}-arn`);
|
|
2959
|
+
debug("DEBUG CERT", certificateArn);
|
|
2788
2960
|
const domain = new DomainName(id, {
|
|
2789
2961
|
domainName,
|
|
2790
2962
|
certificateArn
|
|
@@ -2900,132 +3072,31 @@ var RecordSetGroup = class extends Resource {
|
|
|
2900
3072
|
}
|
|
2901
3073
|
};
|
|
2902
3074
|
|
|
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);
|
|
3075
|
+
// src/custom/global-exports.ts
|
|
3076
|
+
var GlobalExports = class extends Group {
|
|
3077
|
+
resource;
|
|
3078
|
+
constructor(id, props) {
|
|
3079
|
+
const lambda = new Function(id, {
|
|
3080
|
+
code: Code.fromFeature("global-exports")
|
|
3081
|
+
});
|
|
3082
|
+
lambda.addPermissions({
|
|
3083
|
+
actions: ["cloudformation:ListExports"],
|
|
3084
|
+
resources: ["*"]
|
|
3085
|
+
});
|
|
3086
|
+
const resource = new CustomResource(id, {
|
|
3087
|
+
serviceToken: lambda.arn,
|
|
3088
|
+
properties: {
|
|
3089
|
+
region: props.region
|
|
3090
|
+
}
|
|
3091
|
+
});
|
|
3092
|
+
super([lambda, resource]);
|
|
3093
|
+
this.resource = resource;
|
|
3023
3094
|
}
|
|
3024
|
-
|
|
3025
|
-
return {
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
};
|
|
3095
|
+
import(name) {
|
|
3096
|
+
return lazy((stack) => {
|
|
3097
|
+
const attr = formatName(`${stack.app?.name ?? "default"}-${name}`);
|
|
3098
|
+
return this.resource.getAtt(attr);
|
|
3099
|
+
});
|
|
3029
3100
|
}
|
|
3030
3101
|
};
|
|
3031
3102
|
|
|
@@ -3067,36 +3138,39 @@ var domainPlugin = definePlugin({
|
|
|
3067
3138
|
if (domains.length === 0) {
|
|
3068
3139
|
return;
|
|
3069
3140
|
}
|
|
3070
|
-
const
|
|
3141
|
+
const deleteHostedZoneLambda = new Function("delete-hosted-zone", {
|
|
3071
3142
|
name: `${config.name}-delete-hosted-zone`,
|
|
3072
|
-
code: Code.
|
|
3073
|
-
})
|
|
3074
|
-
lambda.addPermissions({
|
|
3143
|
+
code: Code.fromInlineFeature("delete-hosted-zone")
|
|
3144
|
+
}).enableLogs(Duration.days(3)).addPermissions({
|
|
3075
3145
|
actions: [
|
|
3076
3146
|
"route53:ListResourceRecordSets",
|
|
3077
3147
|
"route53:ChangeResourceRecordSets"
|
|
3078
3148
|
],
|
|
3079
3149
|
resources: ["*"]
|
|
3080
3150
|
});
|
|
3081
|
-
usEastBootstrap.add(
|
|
3151
|
+
usEastBootstrap.add(deleteHostedZoneLambda);
|
|
3152
|
+
const usEastExports = new GlobalExports("us-east-exports", {
|
|
3153
|
+
region: usEastBootstrap.region
|
|
3154
|
+
});
|
|
3155
|
+
bootstrap2.add(usEastExports);
|
|
3082
3156
|
for (const [domain, records] of domains) {
|
|
3083
3157
|
const hostedZone = new HostedZone(domain);
|
|
3084
3158
|
const usEastCertificate = new Certificate(domain, {
|
|
3085
3159
|
hostedZoneId: hostedZone.id,
|
|
3086
3160
|
alternativeNames: [`*.${domain}`]
|
|
3087
3161
|
});
|
|
3088
|
-
const
|
|
3089
|
-
serviceToken:
|
|
3162
|
+
const deleteHostedZone = new CustomResource(domain, {
|
|
3163
|
+
serviceToken: deleteHostedZoneLambda.arn,
|
|
3090
3164
|
properties: {
|
|
3091
3165
|
hostedZoneId: hostedZone.id
|
|
3092
3166
|
}
|
|
3093
|
-
}).dependsOn(hostedZone);
|
|
3094
|
-
usEastBootstrap.add(
|
|
3167
|
+
}).dependsOn(deleteHostedZoneLambda, hostedZone);
|
|
3168
|
+
usEastBootstrap.add(hostedZone).add(deleteHostedZone).add(usEastCertificate).export(`certificate-${domain}-arn`, usEastCertificate.arn).export(`hosted-zone-${domain}-id`, hostedZone.id);
|
|
3095
3169
|
const certificate = new Certificate(domain, {
|
|
3096
|
-
hostedZoneId:
|
|
3170
|
+
hostedZoneId: usEastExports.import(`hosted-zone-${domain}-id`),
|
|
3097
3171
|
alternativeNames: [`*.${domain}`]
|
|
3098
3172
|
});
|
|
3099
|
-
bootstrap2.add(certificate).export(`certificate-${domain}-arn`, certificate.arn);
|
|
3173
|
+
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
3174
|
if (records.length > 0) {
|
|
3101
3175
|
const group = new RecordSetGroup(domain, {
|
|
3102
3176
|
hostedZoneId: hostedZone.id,
|
|
@@ -3508,7 +3582,7 @@ var LoadBalancer = class extends Resource {
|
|
|
3508
3582
|
};
|
|
3509
3583
|
|
|
3510
3584
|
// src/formation/resource/elb/listener.ts
|
|
3511
|
-
import { constantCase as
|
|
3585
|
+
import { constantCase as constantCase8 } from "change-case";
|
|
3512
3586
|
var Listener = class extends Resource {
|
|
3513
3587
|
constructor(logicalId, props) {
|
|
3514
3588
|
super("AWS::ElasticLoadBalancingV2::Listener", logicalId);
|
|
@@ -3524,7 +3598,7 @@ var Listener = class extends Resource {
|
|
|
3524
3598
|
return {
|
|
3525
3599
|
LoadBalancerArn: this.props.loadBalancerArn,
|
|
3526
3600
|
Port: this.props.port,
|
|
3527
|
-
Protocol:
|
|
3601
|
+
Protocol: constantCase8(this.props.protocol),
|
|
3528
3602
|
Certificates: this.props.certificates.map((arn) => ({
|
|
3529
3603
|
CertificateArn: arn
|
|
3530
3604
|
})),
|
|
@@ -3750,7 +3824,7 @@ var httpPlugin = definePlugin({
|
|
|
3750
3824
|
).optional()
|
|
3751
3825
|
}).array()
|
|
3752
3826
|
}),
|
|
3753
|
-
onApp({ config, bootstrap: bootstrap2
|
|
3827
|
+
onApp({ config, bootstrap: bootstrap2 }) {
|
|
3754
3828
|
if (Object.keys(config.defaults?.http || {}).length === 0) {
|
|
3755
3829
|
return;
|
|
3756
3830
|
}
|
|
@@ -3789,7 +3863,7 @@ var httpPlugin = definePlugin({
|
|
|
3789
3863
|
]
|
|
3790
3864
|
}).dependsOn(loadBalancer);
|
|
3791
3865
|
const record = new RecordSet(`${id}-http`, {
|
|
3792
|
-
hostedZoneId:
|
|
3866
|
+
hostedZoneId: bootstrap2.import(`hosted-zone-${props.domain}-id`),
|
|
3793
3867
|
name: props.subDomain ? `${props.subDomain}.${props.domain}` : props.domain,
|
|
3794
3868
|
type: "A",
|
|
3795
3869
|
alias: {
|
|
@@ -3963,7 +4037,7 @@ var SubnetGroup = class extends Resource {
|
|
|
3963
4037
|
};
|
|
3964
4038
|
|
|
3965
4039
|
// src/plugins/cache.ts
|
|
3966
|
-
import { constantCase as
|
|
4040
|
+
import { constantCase as constantCase9 } from "change-case";
|
|
3967
4041
|
var TypeSchema = z19.enum([
|
|
3968
4042
|
"t4g.small",
|
|
3969
4043
|
"t4g.medium",
|
|
@@ -4049,7 +4123,7 @@ var cachePlugin = definePlugin({
|
|
|
4049
4123
|
}).dependsOn(subnetGroup, securityGroup);
|
|
4050
4124
|
stack.add(subnetGroup, securityGroup, cluster);
|
|
4051
4125
|
bind((lambda) => {
|
|
4052
|
-
lambda.addEnvironment(`CACHE_${
|
|
4126
|
+
lambda.addEnvironment(`CACHE_${constantCase9(stack.name)}_${constantCase9(id)}_HOST`, cluster.address).addEnvironment(`CACHE_${constantCase9(stack.name)}_${constantCase9(id)}_PORT`, props.port.toString());
|
|
4053
4127
|
});
|
|
4054
4128
|
}
|
|
4055
4129
|
}
|
|
@@ -4267,7 +4341,7 @@ var restPlugin = definePlugin({
|
|
|
4267
4341
|
).optional()
|
|
4268
4342
|
}).array()
|
|
4269
4343
|
}),
|
|
4270
|
-
onApp({ config, bootstrap: bootstrap2
|
|
4344
|
+
onApp({ config, bootstrap: bootstrap2 }) {
|
|
4271
4345
|
for (const [id, props] of Object.entries(config.defaults?.rest || {})) {
|
|
4272
4346
|
const api = new Api(id, {
|
|
4273
4347
|
name: `${config.name}-${id}`,
|
|
@@ -4280,7 +4354,7 @@ var restPlugin = definePlugin({
|
|
|
4280
4354
|
bootstrap2.add(api, stage).export(`rest-${id}-id`, api.id);
|
|
4281
4355
|
if (props.domain) {
|
|
4282
4356
|
const domainName = props.subDomain ? `${props.subDomain}.${props.domain}` : props.domain;
|
|
4283
|
-
const hostedZoneId =
|
|
4357
|
+
const hostedZoneId = bootstrap2.import(`hosted-zone-${props.domain}-id`);
|
|
4284
4358
|
const certificateArn = bootstrap2.import(`certificate-${props.domain}-arn`);
|
|
4285
4359
|
const domain = new DomainName2(id, {
|
|
4286
4360
|
name: domainName,
|
|
@@ -4291,7 +4365,7 @@ var restPlugin = definePlugin({
|
|
|
4291
4365
|
domainName: domain.name,
|
|
4292
4366
|
stage: stage.name
|
|
4293
4367
|
}).dependsOn(api, domain, stage);
|
|
4294
|
-
const record = new RecordSet(
|
|
4368
|
+
const record = new RecordSet(`rest-${id}`, {
|
|
4295
4369
|
hostedZoneId,
|
|
4296
4370
|
type: "A",
|
|
4297
4371
|
name: domainName,
|
|
@@ -4466,131 +4540,717 @@ var configPlugin = definePlugin({
|
|
|
4466
4540
|
}
|
|
4467
4541
|
});
|
|
4468
4542
|
|
|
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
|
-
];
|
|
4543
|
+
// src/plugins/site.ts
|
|
4544
|
+
import { z as z24 } from "zod";
|
|
4489
4545
|
|
|
4490
|
-
// src/formation/
|
|
4491
|
-
var
|
|
4492
|
-
constructor(
|
|
4493
|
-
|
|
4546
|
+
// src/formation/resource/cloud-front/distribution.ts
|
|
4547
|
+
var Distribution = class extends Resource {
|
|
4548
|
+
constructor(logicalId, props) {
|
|
4549
|
+
super("AWS::CloudFront::Distribution", logicalId);
|
|
4550
|
+
this.props = props;
|
|
4551
|
+
this.name = formatName(this.props.name || logicalId);
|
|
4552
|
+
this.tag("name", this.name);
|
|
4494
4553
|
}
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
this.list.set(stack.name, stack);
|
|
4499
|
-
stack.setApp(this);
|
|
4500
|
-
});
|
|
4501
|
-
return this;
|
|
4554
|
+
name;
|
|
4555
|
+
get id() {
|
|
4556
|
+
return getAtt(this.logicalId, "Id");
|
|
4502
4557
|
}
|
|
4503
|
-
|
|
4504
|
-
return
|
|
4558
|
+
get arn() {
|
|
4559
|
+
return sub("arn:${AWS::Partition}:cloudfront::${AWS::AccountId}:distribution/${id}", {
|
|
4560
|
+
id: this.id
|
|
4561
|
+
});
|
|
4505
4562
|
}
|
|
4506
|
-
|
|
4507
|
-
return this.
|
|
4563
|
+
get domainName() {
|
|
4564
|
+
return getAtt(this.logicalId, "DomainName");
|
|
4508
4565
|
}
|
|
4509
|
-
|
|
4510
|
-
return
|
|
4566
|
+
properties() {
|
|
4567
|
+
return {
|
|
4568
|
+
DistributionConfig: {
|
|
4569
|
+
Enabled: true,
|
|
4570
|
+
Aliases: this.props.aliases ?? [],
|
|
4571
|
+
PriceClass: "PriceClass_" + (this.props.priceClass ?? "All"),
|
|
4572
|
+
HttpVersion: this.props.httpVersion ?? "http2and3",
|
|
4573
|
+
ViewerCertificate: this.props.certificateArn ? {
|
|
4574
|
+
SslSupportMethod: "sni-only",
|
|
4575
|
+
AcmCertificateArn: this.props.certificateArn
|
|
4576
|
+
} : {},
|
|
4577
|
+
Origins: this.props.origins?.map((origin) => origin.toJSON()) ?? [],
|
|
4578
|
+
OriginGroups: {
|
|
4579
|
+
Quantity: this.props.originGroups?.length ?? 0,
|
|
4580
|
+
Items: this.props.originGroups?.map((originGroup) => originGroup.toJSON()) ?? []
|
|
4581
|
+
},
|
|
4582
|
+
DefaultCacheBehavior: {
|
|
4583
|
+
TargetOriginId: this.props.targetOriginId,
|
|
4584
|
+
ViewerProtocolPolicy: this.props.viewerProtocol ?? "redirect-to-https",
|
|
4585
|
+
AllowedMethods: this.props.allowMethod ?? ["GET", "HEAD", "OPTIONS"],
|
|
4586
|
+
Compress: this.props.compress ?? false,
|
|
4587
|
+
FunctionAssociations: this.props.associations?.map((association) => ({
|
|
4588
|
+
EventType: association.type,
|
|
4589
|
+
FunctionARN: association.functionArn
|
|
4590
|
+
})) ?? [],
|
|
4591
|
+
LambdaFunctionAssociations: this.props.lambdaAssociations?.map((association) => ({
|
|
4592
|
+
EventType: association.type,
|
|
4593
|
+
IncludeBody: association.includeBody ?? false,
|
|
4594
|
+
FunctionARN: association.functionArn
|
|
4595
|
+
})) ?? [],
|
|
4596
|
+
...this.attr("CachePolicyId", this.props.cachePolicyId),
|
|
4597
|
+
...this.attr("OriginRequestPolicyId", this.props.originRequestPolicyId),
|
|
4598
|
+
...this.attr("ResponseHeadersPolicyId", this.props.responseHeadersPolicyId)
|
|
4599
|
+
}
|
|
4600
|
+
}
|
|
4601
|
+
};
|
|
4602
|
+
}
|
|
4603
|
+
};
|
|
4604
|
+
var Origin = class {
|
|
4605
|
+
constructor(props) {
|
|
4606
|
+
this.props = props;
|
|
4607
|
+
}
|
|
4608
|
+
toJSON() {
|
|
4609
|
+
return {
|
|
4610
|
+
Id: this.props.id,
|
|
4611
|
+
DomainName: this.props.domainName,
|
|
4612
|
+
OriginCustomHeaders: Object.entries(this.props.headers ?? {}).map(([name, value]) => ({
|
|
4613
|
+
HeaderName: name,
|
|
4614
|
+
HeaderValue: value
|
|
4615
|
+
})),
|
|
4616
|
+
...this.props.path ? {
|
|
4617
|
+
OriginPath: this.props.path
|
|
4618
|
+
} : {},
|
|
4619
|
+
...this.props.protocol ? {
|
|
4620
|
+
CustomOriginConfig: {
|
|
4621
|
+
OriginProtocolPolicy: this.props.protocol
|
|
4622
|
+
}
|
|
4623
|
+
} : {},
|
|
4624
|
+
...this.props.originAccessIdentityId ? {
|
|
4625
|
+
S3OriginConfig: {
|
|
4626
|
+
OriginAccessIdentity: sub("origin-access-identity/cloudfront/${id}", {
|
|
4627
|
+
id: this.props.originAccessIdentityId
|
|
4628
|
+
})
|
|
4629
|
+
}
|
|
4630
|
+
} : {},
|
|
4631
|
+
...this.props.originAccessControlId ? {
|
|
4632
|
+
OriginAccessControlId: this.props.originAccessControlId,
|
|
4633
|
+
S3OriginConfig: {
|
|
4634
|
+
OriginAccessIdentity: ""
|
|
4635
|
+
}
|
|
4636
|
+
} : {}
|
|
4637
|
+
};
|
|
4638
|
+
}
|
|
4639
|
+
};
|
|
4640
|
+
var OriginGroup = class {
|
|
4641
|
+
constructor(props) {
|
|
4642
|
+
this.props = props;
|
|
4643
|
+
}
|
|
4644
|
+
toJSON() {
|
|
4645
|
+
return {
|
|
4646
|
+
Id: this.props.id,
|
|
4647
|
+
Members: {
|
|
4648
|
+
Quantity: this.props.members.length,
|
|
4649
|
+
Items: this.props.members.map((member) => ({
|
|
4650
|
+
OriginId: member
|
|
4651
|
+
}))
|
|
4652
|
+
},
|
|
4653
|
+
FailoverCriteria: {
|
|
4654
|
+
StatusCodes: {
|
|
4655
|
+
Quantity: this.props.statusCodes.length,
|
|
4656
|
+
Items: this.props.statusCodes
|
|
4657
|
+
}
|
|
4658
|
+
}
|
|
4659
|
+
};
|
|
4511
4660
|
}
|
|
4512
|
-
// get resources() {
|
|
4513
|
-
// return this.stacks.map(stack => stack.resources).flat()
|
|
4514
|
-
// }
|
|
4515
4661
|
};
|
|
4516
4662
|
|
|
4517
|
-
// src/
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
const
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
try {
|
|
4530
|
-
const data = await listExports(region)
|
|
4663
|
+
// src/schema/local-directory.ts
|
|
4664
|
+
import { stat as stat2 } from "fs/promises";
|
|
4665
|
+
import { z as z23 } from "zod";
|
|
4666
|
+
var LocalDirectorySchema = z23.string().refine(async (path) => {
|
|
4667
|
+
try {
|
|
4668
|
+
const s = await stat2(path);
|
|
4669
|
+
return s.isDirectory();
|
|
4670
|
+
} catch (error) {
|
|
4671
|
+
return false;
|
|
4672
|
+
}
|
|
4673
|
+
}, `Directory doesn't exist`);
|
|
4531
4674
|
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4675
|
+
// src/formation/resource/cloud-front/origin-request-policy.ts
|
|
4676
|
+
import { camelCase as camelCase4 } from "change-case";
|
|
4677
|
+
var OriginRequestPolicy = class extends Resource {
|
|
4678
|
+
constructor(logicalId, props = {}) {
|
|
4679
|
+
super("AWS::CloudFront::OriginRequestPolicy", logicalId);
|
|
4680
|
+
this.props = props;
|
|
4681
|
+
this.name = formatName(this.props.name || logicalId);
|
|
4682
|
+
}
|
|
4683
|
+
name;
|
|
4684
|
+
get id() {
|
|
4685
|
+
return getAtt(this.logicalId, "Id");
|
|
4686
|
+
}
|
|
4687
|
+
properties() {
|
|
4688
|
+
return {
|
|
4689
|
+
OriginRequestPolicyConfig: {
|
|
4690
|
+
Name: this.name,
|
|
4691
|
+
CookiesConfig: {
|
|
4692
|
+
CookieBehavior: camelCase4(this.props.cookie?.behavior ?? "all"),
|
|
4693
|
+
...this.attr("Cookies", this.props.cookie?.values)
|
|
4694
|
+
},
|
|
4695
|
+
HeadersConfig: {
|
|
4696
|
+
HeaderBehavior: camelCase4(this.props.header?.behavior ?? "allViewer"),
|
|
4697
|
+
...this.attr("Headers", this.props.header?.values)
|
|
4698
|
+
},
|
|
4699
|
+
QueryStringsConfig: {
|
|
4700
|
+
QueryStringBehavior: camelCase4(this.props.query?.behavior ?? "all"),
|
|
4701
|
+
...this.attr("QueryStrings", this.props.query?.values)
|
|
4702
|
+
}
|
|
4703
|
+
}
|
|
4704
|
+
};
|
|
4705
|
+
}
|
|
4706
|
+
};
|
|
4541
4707
|
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4708
|
+
// src/formation/resource/cloud-front/cache-policy.ts
|
|
4709
|
+
var CachePolicy = class extends Resource {
|
|
4710
|
+
constructor(logicalId, props) {
|
|
4711
|
+
super("AWS::CloudFront::CachePolicy", logicalId);
|
|
4712
|
+
this.props = props;
|
|
4713
|
+
this.name = formatName(this.props.name || logicalId);
|
|
4714
|
+
}
|
|
4715
|
+
name;
|
|
4716
|
+
get id() {
|
|
4717
|
+
return getAtt(this.logicalId, "Id");
|
|
4718
|
+
}
|
|
4719
|
+
properties() {
|
|
4720
|
+
return {
|
|
4721
|
+
CachePolicyConfig: {
|
|
4722
|
+
Name: this.name,
|
|
4723
|
+
MinTTL: this.props.minTtl.toSeconds(),
|
|
4724
|
+
MaxTTL: this.props.maxTtl.toSeconds(),
|
|
4725
|
+
DefaultTTL: this.props.defaultTtl.toSeconds(),
|
|
4726
|
+
ParametersInCacheKeyAndForwardedToOrigin: {
|
|
4727
|
+
EnableAcceptEncodingGzip: this.props.acceptGzip ?? false,
|
|
4728
|
+
EnableAcceptEncodingBrotli: this.props.acceptBrotli ?? false,
|
|
4729
|
+
CookiesConfig: {
|
|
4730
|
+
CookieBehavior: this.props.cookies ? "whitelist" : "none",
|
|
4731
|
+
...this.attr("Cookies", this.props.cookies)
|
|
4732
|
+
},
|
|
4733
|
+
HeadersConfig: {
|
|
4734
|
+
HeaderBehavior: this.props.headers ? "whitelist" : "none",
|
|
4735
|
+
...this.attr("Headers", this.props.headers)
|
|
4736
|
+
},
|
|
4737
|
+
QueryStringsConfig: {
|
|
4738
|
+
QueryStringBehavior: this.props.queries ? "whitelist" : "none",
|
|
4739
|
+
...this.attr("QueryStrings", this.props.queries)
|
|
4740
|
+
}
|
|
4741
|
+
}
|
|
4742
|
+
}
|
|
4743
|
+
};
|
|
4744
|
+
}
|
|
4745
|
+
};
|
|
4545
4746
|
|
|
4546
|
-
|
|
4747
|
+
// src/formation/resource/s3/files.ts
|
|
4748
|
+
import { Glob } from "glob";
|
|
4749
|
+
import JSZip2 from "jszip";
|
|
4750
|
+
import { createHash as createHash2 } from "crypto";
|
|
4751
|
+
import { createReadStream } from "fs";
|
|
4752
|
+
import { join as join4 } from "path";
|
|
4753
|
+
var Files = class extends Asset {
|
|
4754
|
+
constructor(id, props) {
|
|
4755
|
+
super("bucket", id);
|
|
4756
|
+
this.props = props;
|
|
4757
|
+
}
|
|
4758
|
+
hash;
|
|
4759
|
+
bundle;
|
|
4760
|
+
s3;
|
|
4761
|
+
async build({ write }) {
|
|
4762
|
+
const glob = new Glob(this.props.pattern ?? "**/*", {
|
|
4763
|
+
nodir: true,
|
|
4764
|
+
cwd: this.props.directory
|
|
4765
|
+
});
|
|
4766
|
+
const zip = new JSZip2();
|
|
4767
|
+
const hashes = [];
|
|
4768
|
+
let count = 0;
|
|
4769
|
+
for await (const path of glob) {
|
|
4770
|
+
const file = join4(this.props.directory, path);
|
|
4771
|
+
const stream = createReadStream(file);
|
|
4772
|
+
const hash2 = createHash2("sha1");
|
|
4773
|
+
stream.pipe(hash2);
|
|
4774
|
+
hashes.push(hash2);
|
|
4775
|
+
zip.file(path, stream);
|
|
4776
|
+
count++;
|
|
4777
|
+
}
|
|
4778
|
+
this.bundle = await zip.generateAsync({
|
|
4779
|
+
type: "nodebuffer",
|
|
4780
|
+
compression: "DEFLATE",
|
|
4781
|
+
compressionOptions: {
|
|
4782
|
+
level: 9
|
|
4783
|
+
}
|
|
4784
|
+
});
|
|
4785
|
+
const hash = createHash2("sha1");
|
|
4786
|
+
for (const item of hashes) {
|
|
4787
|
+
hash.update(item.digest());
|
|
4788
|
+
}
|
|
4789
|
+
this.hash = hash.digest("hex");
|
|
4790
|
+
await write("HASH", this.hash);
|
|
4791
|
+
await write("bundle.zip", this.bundle);
|
|
4792
|
+
return {
|
|
4793
|
+
files: style.success(String(count)),
|
|
4794
|
+
size: formatByteSize(this.bundle.byteLength)
|
|
4795
|
+
};
|
|
4796
|
+
}
|
|
4797
|
+
async publish({ publish }) {
|
|
4798
|
+
this.s3 = await publish(
|
|
4799
|
+
`${this.id}.zip`,
|
|
4800
|
+
this.bundle,
|
|
4801
|
+
this.hash
|
|
4802
|
+
);
|
|
4803
|
+
}
|
|
4804
|
+
get source() {
|
|
4805
|
+
return this.s3;
|
|
4806
|
+
}
|
|
4807
|
+
};
|
|
4547
4808
|
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4809
|
+
// src/formation/resource/s3/bucket-policy.ts
|
|
4810
|
+
import { capitalCase } from "change-case";
|
|
4811
|
+
var BucketPolicy = class extends Resource {
|
|
4812
|
+
constructor(logicalId, props) {
|
|
4813
|
+
super("AWS::S3::BucketPolicy", logicalId);
|
|
4814
|
+
this.props = props;
|
|
4815
|
+
}
|
|
4816
|
+
properties() {
|
|
4817
|
+
return {
|
|
4818
|
+
Bucket: formatName(this.props.bucketName),
|
|
4819
|
+
PolicyDocument: {
|
|
4820
|
+
Version: this.props.version ?? "2012-10-17",
|
|
4821
|
+
Statement: this.props.statements.map((statement) => ({
|
|
4822
|
+
Effect: capitalCase(statement.effect ?? "allow"),
|
|
4823
|
+
...statement.principal ? {
|
|
4824
|
+
Principal: {
|
|
4825
|
+
Service: statement.principal
|
|
4826
|
+
}
|
|
4827
|
+
} : {},
|
|
4828
|
+
Action: statement.actions,
|
|
4829
|
+
Resource: statement.resources,
|
|
4830
|
+
...statement.sourceArn ? {
|
|
4831
|
+
Condition: {
|
|
4832
|
+
StringEquals: {
|
|
4833
|
+
"AWS:SourceArn": statement.sourceArn
|
|
4834
|
+
}
|
|
4835
|
+
}
|
|
4836
|
+
} : {}
|
|
4837
|
+
}))
|
|
4838
|
+
}
|
|
4839
|
+
};
|
|
4840
|
+
}
|
|
4841
|
+
};
|
|
4552
4842
|
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4843
|
+
// src/formation/resource/cloud-front/origin-access-control.ts
|
|
4844
|
+
var OriginAccessControl = class extends Resource {
|
|
4845
|
+
constructor(logicalId, props) {
|
|
4846
|
+
super("AWS::CloudFront::OriginAccessControl", logicalId);
|
|
4847
|
+
this.props = props;
|
|
4848
|
+
this.name = formatName(this.props.name || logicalId);
|
|
4849
|
+
}
|
|
4850
|
+
name;
|
|
4851
|
+
get id() {
|
|
4852
|
+
return getAtt(this.logicalId, "Id");
|
|
4853
|
+
}
|
|
4854
|
+
properties() {
|
|
4855
|
+
return {
|
|
4856
|
+
OriginAccessControlConfig: {
|
|
4857
|
+
Name: this.name,
|
|
4858
|
+
OriginAccessControlOriginType: this.props.type,
|
|
4859
|
+
SigningBehavior: this.props.behavior ?? "always",
|
|
4860
|
+
SigningProtocol: this.props.protocol ?? "sigv4"
|
|
4861
|
+
}
|
|
4862
|
+
};
|
|
4863
|
+
}
|
|
4864
|
+
};
|
|
4556
4865
|
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
}
|
|
4564
|
-
|
|
4565
|
-
)
|
|
4866
|
+
// src/formation/resource/cloud-front/response-headers-policy.ts
|
|
4867
|
+
var ResponseHeadersPolicy = class extends Resource {
|
|
4868
|
+
constructor(logicalId, props) {
|
|
4869
|
+
super("AWS::CloudFront::ResponseHeadersPolicy", logicalId);
|
|
4870
|
+
this.props = props;
|
|
4871
|
+
this.name = formatName(this.props.name || logicalId);
|
|
4872
|
+
}
|
|
4873
|
+
name;
|
|
4874
|
+
get id() {
|
|
4875
|
+
return getAtt(this.logicalId, "Id");
|
|
4876
|
+
}
|
|
4877
|
+
properties() {
|
|
4878
|
+
return {
|
|
4879
|
+
ResponseHeadersPolicyConfig: {
|
|
4880
|
+
Name: this.name,
|
|
4881
|
+
...this.props.remove && this.props.remove.length > 0 ? {
|
|
4882
|
+
RemoveHeadersConfig: {
|
|
4883
|
+
Items: this.props.remove?.map((value) => ({
|
|
4884
|
+
Header: value
|
|
4885
|
+
}))
|
|
4886
|
+
}
|
|
4887
|
+
} : {},
|
|
4888
|
+
CorsConfig: {
|
|
4889
|
+
OriginOverride: this.props.cors?.override ?? false,
|
|
4890
|
+
AccessControlAllowCredentials: this.props.cors?.credentials ?? false,
|
|
4891
|
+
AccessControlMaxAgeSec: this.props.cors?.maxAge?.toSeconds() ?? Duration.days(365).toSeconds(),
|
|
4892
|
+
AccessControlAllowHeaders: {
|
|
4893
|
+
Items: this.props.cors?.headers ?? ["*"]
|
|
4894
|
+
},
|
|
4895
|
+
AccessControlAllowMethods: {
|
|
4896
|
+
Items: this.props.cors?.methods ?? ["ALL"]
|
|
4897
|
+
},
|
|
4898
|
+
AccessControlAllowOrigins: {
|
|
4899
|
+
Items: this.props.cors?.origins ?? ["*"]
|
|
4900
|
+
},
|
|
4901
|
+
AccessControlExposeHeaders: {
|
|
4902
|
+
Items: this.props.cors?.exposeHeaders ?? ["*"]
|
|
4903
|
+
}
|
|
4904
|
+
},
|
|
4905
|
+
SecurityHeadersConfig: {
|
|
4906
|
+
...this.props.contentSecurityPolicy ? {
|
|
4907
|
+
ContentSecurityPolicy: {
|
|
4908
|
+
Override: this.props.contentSecurityPolicy?.override ?? false,
|
|
4909
|
+
ContentSecurityPolicy: this.props.contentSecurityPolicy?.contentSecurityPolicy
|
|
4910
|
+
}
|
|
4911
|
+
} : {},
|
|
4912
|
+
ContentTypeOptions: {
|
|
4913
|
+
Override: this.props.contentTypeOptions?.override ?? false
|
|
4914
|
+
},
|
|
4915
|
+
FrameOptions: {
|
|
4916
|
+
Override: this.props.frameOptions?.override ?? false,
|
|
4917
|
+
FrameOption: (this.props.frameOptions?.frameOption ?? "same-origin") === "same-origin" ? "SAMEORIGIN" : "DENY"
|
|
4918
|
+
},
|
|
4919
|
+
ReferrerPolicy: {
|
|
4920
|
+
Override: this.props.referrerPolicy?.override ?? false,
|
|
4921
|
+
ReferrerPolicy: this.props.referrerPolicy?.referrerPolicy ?? "same-origin"
|
|
4922
|
+
},
|
|
4923
|
+
StrictTransportSecurity: {
|
|
4924
|
+
Override: this.props.strictTransportSecurity?.override ?? false,
|
|
4925
|
+
Preload: this.props.strictTransportSecurity?.preload ?? true,
|
|
4926
|
+
AccessControlMaxAgeSec: this.props.strictTransportSecurity?.maxAge?.toSeconds() ?? 31536e3,
|
|
4927
|
+
IncludeSubdomains: this.props.strictTransportSecurity?.includeSubdomains ?? true
|
|
4928
|
+
},
|
|
4929
|
+
XSSProtection: {
|
|
4930
|
+
Override: this.props.xssProtection?.override ?? false,
|
|
4931
|
+
ModeBlock: this.props.xssProtection?.modeBlock ?? true,
|
|
4932
|
+
Protection: this.props.xssProtection?.enable ?? true,
|
|
4933
|
+
...this.attr("ReportUri", this.props.xssProtection?.reportUri)
|
|
4934
|
+
}
|
|
4935
|
+
}
|
|
4936
|
+
}
|
|
4937
|
+
};
|
|
4938
|
+
}
|
|
4939
|
+
};
|
|
4566
4940
|
|
|
4567
|
-
// src/
|
|
4568
|
-
var
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4941
|
+
// src/plugins/site.ts
|
|
4942
|
+
var sitePlugin = definePlugin({
|
|
4943
|
+
name: "site",
|
|
4944
|
+
schema: z24.object({
|
|
4945
|
+
stacks: z24.object({
|
|
4946
|
+
/** Define the sites in your stack.
|
|
4947
|
+
* @example
|
|
4948
|
+
* {
|
|
4949
|
+
* sites: {
|
|
4950
|
+
* SITE_NAME: {
|
|
4951
|
+
* static: 'dist/client'
|
|
4952
|
+
* ssr: 'dist/server/index.js'
|
|
4953
|
+
* }
|
|
4954
|
+
* }
|
|
4955
|
+
* }
|
|
4956
|
+
* */
|
|
4957
|
+
sites: z24.record(
|
|
4958
|
+
ResourceIdSchema,
|
|
4959
|
+
z24.object({
|
|
4960
|
+
/** The domain to link your site with. */
|
|
4961
|
+
domain: z24.string(),
|
|
4962
|
+
subDomain: z24.string().optional(),
|
|
4963
|
+
/** Specifies the path to the static files directory. */
|
|
4964
|
+
static: LocalDirectorySchema.optional(),
|
|
4965
|
+
/** Specifies the ssr file. */
|
|
4966
|
+
ssr: FunctionSchema.optional(),
|
|
4967
|
+
/** Define the cors headers. */
|
|
4968
|
+
cors: z24.object({
|
|
4969
|
+
override: z24.boolean().default(false),
|
|
4970
|
+
maxAge: DurationSchema.default("365 days"),
|
|
4971
|
+
exposeHeaders: z24.string().array().optional(),
|
|
4972
|
+
credentials: z24.boolean().default(false),
|
|
4973
|
+
headers: z24.string().array().default(["*"]),
|
|
4974
|
+
origins: z24.string().array().default(["*"]),
|
|
4975
|
+
methods: z24.enum(["GET", "DELETE", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "ALL"]).array().default(["ALL"])
|
|
4976
|
+
}).optional(),
|
|
4977
|
+
/** Define the cors headers. */
|
|
4978
|
+
security: z24.object({
|
|
4979
|
+
// contentSecurityPolicy: z.object({
|
|
4980
|
+
// override: z.boolean().default(false),
|
|
4981
|
+
// policy: z.string(),
|
|
4982
|
+
// })
|
|
4983
|
+
// contentSecurityPolicy?: {
|
|
4984
|
+
// override?: boolean
|
|
4985
|
+
// contentSecurityPolicy: string
|
|
4986
|
+
// }
|
|
4987
|
+
// contentTypeOptions?: {
|
|
4988
|
+
// override?: boolean
|
|
4989
|
+
// }
|
|
4990
|
+
// frameOptions?: {
|
|
4991
|
+
// override?: boolean
|
|
4992
|
+
// frameOption?: 'deny' | 'same-origin'
|
|
4993
|
+
// }
|
|
4994
|
+
// referrerPolicy?: {
|
|
4995
|
+
// override?: boolean
|
|
4996
|
+
// referrerPolicy?: (
|
|
4997
|
+
// 'no-referrer' |
|
|
4998
|
+
// 'no-referrer-when-downgrade' |
|
|
4999
|
+
// 'origin' |
|
|
5000
|
+
// 'origin-when-cross-origin' |
|
|
5001
|
+
// 'same-origin' |
|
|
5002
|
+
// 'strict-origin' |
|
|
5003
|
+
// 'strict-origin-when-cross-origin' |
|
|
5004
|
+
// 'unsafe-url'
|
|
5005
|
+
// )
|
|
5006
|
+
// }
|
|
5007
|
+
// strictTransportSecurity?: {
|
|
5008
|
+
// maxAge?: Duration
|
|
5009
|
+
// includeSubdomains?: boolean
|
|
5010
|
+
// override?: boolean
|
|
5011
|
+
// preload?: boolean
|
|
5012
|
+
// }
|
|
5013
|
+
// xssProtection?: {
|
|
5014
|
+
// override?: boolean
|
|
5015
|
+
// enable?: boolean
|
|
5016
|
+
// modeBlock?: boolean
|
|
5017
|
+
// reportUri?: string
|
|
5018
|
+
// }
|
|
5019
|
+
}).optional(),
|
|
5020
|
+
/** Specifies the cookies, headers, and query values that CloudFront includes in the cache key. */
|
|
5021
|
+
cache: z24.object({
|
|
5022
|
+
/** Specifies the cookies that CloudFront includes in the cache key. */
|
|
5023
|
+
cookies: z24.string().array().optional(),
|
|
5024
|
+
/** Specifies the headers that CloudFront includes in the cache key. */
|
|
5025
|
+
headers: z24.string().array().optional(),
|
|
5026
|
+
/** Specifies the query values that CloudFront includes in the cache key. */
|
|
5027
|
+
queries: z24.string().array().optional()
|
|
5028
|
+
}).optional()
|
|
5029
|
+
})
|
|
5030
|
+
).optional()
|
|
5031
|
+
}).array()
|
|
5032
|
+
}),
|
|
5033
|
+
onStack(ctx) {
|
|
5034
|
+
const { config, stack, stackConfig, bootstrap: bootstrap2 } = ctx;
|
|
5035
|
+
for (const [id, props] of Object.entries(stackConfig.sites || {})) {
|
|
5036
|
+
const origins = [];
|
|
5037
|
+
const originGroups = [];
|
|
5038
|
+
const deps = [];
|
|
5039
|
+
let bucket;
|
|
5040
|
+
if (props.ssr) {
|
|
5041
|
+
const lambda = toLambdaFunction(ctx, `site-${id}`, props.ssr);
|
|
5042
|
+
const permissions = new Permission2(`site-${id}`, {
|
|
5043
|
+
principal: "*",
|
|
5044
|
+
// principal: 'cloudfront.amazonaws.com',
|
|
5045
|
+
action: "lambda:InvokeFunctionUrl",
|
|
5046
|
+
functionArn: lambda.arn,
|
|
5047
|
+
urlAuthType: "none"
|
|
5048
|
+
// sourceArn: distribution.arn,
|
|
5049
|
+
}).dependsOn(lambda);
|
|
5050
|
+
const url = lambda.addUrl();
|
|
5051
|
+
stack.add(url, lambda, permissions);
|
|
5052
|
+
origins.push(new Origin({
|
|
5053
|
+
id: "lambda",
|
|
5054
|
+
domainName: select(2, split("/", url.url)),
|
|
5055
|
+
protocol: "https-only"
|
|
5056
|
+
}));
|
|
5057
|
+
deps.push(lambda, url, permissions);
|
|
5058
|
+
}
|
|
5059
|
+
if (props.static) {
|
|
5060
|
+
bucket = new Bucket(`site-${id}`, {
|
|
5061
|
+
// name: props.domain,
|
|
5062
|
+
name: `site-${config.name}-${stack.name}-${id}`,
|
|
5063
|
+
accessControl: "private",
|
|
5064
|
+
website: {
|
|
5065
|
+
indexDocument: "index.html",
|
|
5066
|
+
errorDocument: props.ssr ? void 0 : "error.html"
|
|
5067
|
+
}
|
|
5068
|
+
});
|
|
5069
|
+
const accessControl = new OriginAccessControl(`site-${id}`, {
|
|
5070
|
+
type: "s3"
|
|
5071
|
+
});
|
|
5072
|
+
const files = new Files(`site-${id}`, {
|
|
5073
|
+
directory: props.static
|
|
5074
|
+
});
|
|
5075
|
+
const uploadBucketAsset = new CustomResource(`site-${id}-upload-bucket-asset`, {
|
|
5076
|
+
serviceToken: bootstrap2.import("feature-upload-bucket-asset"),
|
|
5077
|
+
properties: {
|
|
5078
|
+
sourceBucketName: lazy(() => files.source?.bucket ?? ""),
|
|
5079
|
+
sourceObjectKey: lazy(() => files.source?.key ?? ""),
|
|
5080
|
+
sourceObjectVersion: lazy(() => files.source?.version ?? ""),
|
|
5081
|
+
destinationBucketName: bucket.name
|
|
5082
|
+
}
|
|
5083
|
+
}).dependsOn(bucket);
|
|
5084
|
+
const deleteBucket = new CustomResource(id, {
|
|
5085
|
+
serviceToken: bootstrap2.import("feature-delete-bucket"),
|
|
5086
|
+
properties: {
|
|
5087
|
+
bucketName: bucket.name
|
|
5088
|
+
}
|
|
5089
|
+
}).dependsOn(bucket);
|
|
5090
|
+
stack.add(bucket, files, uploadBucketAsset, deleteBucket, accessControl);
|
|
5091
|
+
origins.push(new Origin({
|
|
5092
|
+
id: "bucket",
|
|
5093
|
+
// domainName: select(2, split('/', bucket.url)),
|
|
5094
|
+
domainName: bucket.domainName,
|
|
5095
|
+
originAccessControlId: accessControl.id
|
|
5096
|
+
}));
|
|
5097
|
+
deps.push(bucket, accessControl);
|
|
5098
|
+
}
|
|
5099
|
+
if (props.ssr && props.static) {
|
|
5100
|
+
originGroups.push(new OriginGroup({
|
|
5101
|
+
id: "group",
|
|
5102
|
+
members: ["lambda", "bucket"],
|
|
5103
|
+
statusCodes: [403, 404]
|
|
5104
|
+
}));
|
|
5105
|
+
}
|
|
5106
|
+
const cache = new CachePolicy(id, {
|
|
5107
|
+
name: `site-${config.name}-${stack.name}-${id}`,
|
|
5108
|
+
minTtl: Duration.seconds(1),
|
|
5109
|
+
maxTtl: Duration.days(365),
|
|
5110
|
+
defaultTtl: Duration.days(1),
|
|
5111
|
+
...props.cache
|
|
4583
5112
|
});
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
5113
|
+
const originRequest = new OriginRequestPolicy(id, {
|
|
5114
|
+
name: `site-${config.name}-${stack.name}-${id}`,
|
|
5115
|
+
header: {
|
|
5116
|
+
behavior: "all-except",
|
|
5117
|
+
values: ["HOST"]
|
|
4588
5118
|
}
|
|
4589
5119
|
});
|
|
4590
|
-
|
|
5120
|
+
const domainName = props.subDomain ? `${props.subDomain}.${props.domain}` : props.domain;
|
|
5121
|
+
const hostedZoneId = bootstrap2.import(`hosted-zone-${props.domain}-id`);
|
|
5122
|
+
const certificateArn = bootstrap2.import(`us-east-certificate-${props.domain}-arn`);
|
|
5123
|
+
const responseHeaders = new ResponseHeadersPolicy(id, {
|
|
5124
|
+
name: `site-${config.name}-${stack.name}-${id}`,
|
|
5125
|
+
cors: props.cors,
|
|
5126
|
+
remove: ["server"]
|
|
5127
|
+
});
|
|
5128
|
+
const distribution = new Distribution(id, {
|
|
5129
|
+
name: `site-${config.name}-${stack.name}-${id}`,
|
|
5130
|
+
certificateArn,
|
|
5131
|
+
compress: true,
|
|
5132
|
+
aliases: [domainName],
|
|
5133
|
+
origins,
|
|
5134
|
+
originGroups,
|
|
5135
|
+
targetOriginId: props.ssr && props.static ? "group" : props.ssr ? "lambda" : "bucket",
|
|
5136
|
+
originRequestPolicyId: originRequest.id,
|
|
5137
|
+
cachePolicyId: cache.id,
|
|
5138
|
+
responseHeadersPolicyId: responseHeaders.id
|
|
5139
|
+
}).dependsOn(originRequest, responseHeaders, cache, ...deps);
|
|
5140
|
+
if (props.static) {
|
|
5141
|
+
const bucketPolicy = new BucketPolicy(`site-${id}`, {
|
|
5142
|
+
bucketName: bucket.name,
|
|
5143
|
+
statements: [
|
|
5144
|
+
{
|
|
5145
|
+
principal: "cloudfront.amazonaws.com",
|
|
5146
|
+
actions: ["s3:GetObject"],
|
|
5147
|
+
resources: [sub("${arn}/*", { arn: bucket.arn })],
|
|
5148
|
+
sourceArn: distribution.arn
|
|
5149
|
+
}
|
|
5150
|
+
// {
|
|
5151
|
+
// principal: distribution.id,
|
|
5152
|
+
// actions: [ 's3:GetObject' ],
|
|
5153
|
+
// resources: [ oac.attrId ]
|
|
5154
|
+
// }
|
|
5155
|
+
]
|
|
5156
|
+
}).dependsOn(bucket, distribution);
|
|
5157
|
+
stack.add(bucketPolicy);
|
|
5158
|
+
}
|
|
5159
|
+
const record = new RecordSet(`site-${id}`, {
|
|
5160
|
+
hostedZoneId,
|
|
5161
|
+
type: "A",
|
|
5162
|
+
name: domainName,
|
|
5163
|
+
alias: {
|
|
5164
|
+
dnsName: distribution.domainName,
|
|
5165
|
+
hostedZoneId: "Z2FDTNDATAQYW2"
|
|
5166
|
+
}
|
|
5167
|
+
}).dependsOn(distribution);
|
|
5168
|
+
stack.add(
|
|
5169
|
+
distribution,
|
|
5170
|
+
responseHeaders,
|
|
5171
|
+
originRequest,
|
|
5172
|
+
cache,
|
|
5173
|
+
record
|
|
5174
|
+
);
|
|
4591
5175
|
}
|
|
4592
|
-
|
|
4593
|
-
|
|
5176
|
+
}
|
|
5177
|
+
});
|
|
5178
|
+
|
|
5179
|
+
// src/plugins/feature.ts
|
|
5180
|
+
var featurePlugin = definePlugin({
|
|
5181
|
+
name: "feature",
|
|
5182
|
+
onApp({ config, bootstrap: bootstrap2 }) {
|
|
5183
|
+
const deleteBucketLambda = new Function("delete-bucket", {
|
|
5184
|
+
name: `${config.name}-delete-bucket`,
|
|
5185
|
+
code: Code.fromFeature("delete-bucket")
|
|
5186
|
+
}).enableLogs(Duration.days(3)).addPermissions({
|
|
5187
|
+
actions: ["s3:*"],
|
|
5188
|
+
resources: ["*"]
|
|
5189
|
+
});
|
|
5190
|
+
const uploadBucketAssetLambda = new Function("upload-bucket-asset", {
|
|
5191
|
+
name: `${config.name}-upload-bucket-asset`,
|
|
5192
|
+
code: Code.fromFeature("upload-bucket-asset"),
|
|
5193
|
+
memorySize: Size.gigaBytes(2)
|
|
5194
|
+
}).enableLogs(Duration.days(3)).addPermissions({
|
|
5195
|
+
actions: ["s3:*"],
|
|
5196
|
+
resources: ["*"]
|
|
5197
|
+
});
|
|
5198
|
+
bootstrap2.add(
|
|
5199
|
+
deleteBucketLambda,
|
|
5200
|
+
uploadBucketAssetLambda
|
|
5201
|
+
);
|
|
5202
|
+
bootstrap2.export("feature-delete-bucket", deleteBucketLambda.arn).export("feature-upload-bucket-asset", uploadBucketAssetLambda.arn);
|
|
5203
|
+
}
|
|
5204
|
+
});
|
|
5205
|
+
|
|
5206
|
+
// src/plugins/index.ts
|
|
5207
|
+
var defaultPlugins = [
|
|
5208
|
+
extendPlugin,
|
|
5209
|
+
featurePlugin,
|
|
5210
|
+
vpcPlugin,
|
|
5211
|
+
domainPlugin,
|
|
5212
|
+
functionPlugin,
|
|
5213
|
+
configPlugin,
|
|
5214
|
+
cachePlugin,
|
|
5215
|
+
cronPlugin,
|
|
5216
|
+
queuePlugin,
|
|
5217
|
+
tablePlugin,
|
|
5218
|
+
storePlugin,
|
|
5219
|
+
topicPlugin,
|
|
5220
|
+
pubsubPlugin,
|
|
5221
|
+
searchPlugin,
|
|
5222
|
+
graphqlPlugin,
|
|
5223
|
+
httpPlugin,
|
|
5224
|
+
restPlugin,
|
|
5225
|
+
sitePlugin,
|
|
5226
|
+
onFailurePlugin
|
|
5227
|
+
];
|
|
5228
|
+
|
|
5229
|
+
// src/formation/app.ts
|
|
5230
|
+
var App = class {
|
|
5231
|
+
constructor(name) {
|
|
5232
|
+
this.name = name;
|
|
5233
|
+
}
|
|
5234
|
+
list = /* @__PURE__ */ new Map();
|
|
5235
|
+
add(...stacks) {
|
|
5236
|
+
stacks.forEach((stack) => {
|
|
5237
|
+
this.list.set(stack.name, stack);
|
|
5238
|
+
stack.setApp(this);
|
|
5239
|
+
});
|
|
5240
|
+
return this;
|
|
5241
|
+
}
|
|
5242
|
+
find(resourceType) {
|
|
5243
|
+
return this.stacks.map((stack) => stack.find(resourceType)).flat();
|
|
5244
|
+
}
|
|
5245
|
+
[Symbol.iterator]() {
|
|
5246
|
+
return this.list.values();
|
|
5247
|
+
}
|
|
5248
|
+
get stacks() {
|
|
5249
|
+
return [...this.list.values()];
|
|
5250
|
+
}
|
|
5251
|
+
// get resources() {
|
|
5252
|
+
// return this.stacks.map(stack => stack.resources).flat()
|
|
5253
|
+
// }
|
|
4594
5254
|
};
|
|
4595
5255
|
|
|
4596
5256
|
// src/app.ts
|
|
@@ -4615,7 +5275,6 @@ var toApp = async (config, filters) => {
|
|
|
4615
5275
|
debug("Plugins detected:", plugins.map((plugin) => style.info(plugin.name)).join(", "));
|
|
4616
5276
|
const bootstrap2 = new Stack("bootstrap", config.region);
|
|
4617
5277
|
const usEastBootstrap = new Stack("us-east-bootstrap", "us-east-1");
|
|
4618
|
-
extendWithGlobalExports(config.name, usEastBootstrap, bootstrap2);
|
|
4619
5278
|
app.add(bootstrap2, usEastBootstrap);
|
|
4620
5279
|
debug("Run plugin onApp listeners");
|
|
4621
5280
|
const bindings = [];
|
|
@@ -4697,7 +5356,7 @@ var toApp = async (config, filters) => {
|
|
|
4697
5356
|
};
|
|
4698
5357
|
|
|
4699
5358
|
// src/config.ts
|
|
4700
|
-
import { join as
|
|
5359
|
+
import { join as join6 } from "path";
|
|
4701
5360
|
|
|
4702
5361
|
// src/util/account.ts
|
|
4703
5362
|
import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";
|
|
@@ -4716,17 +5375,17 @@ var getCredentials = (profile) => {
|
|
|
4716
5375
|
};
|
|
4717
5376
|
|
|
4718
5377
|
// src/schema/app.ts
|
|
4719
|
-
import { z as
|
|
5378
|
+
import { z as z28 } from "zod";
|
|
4720
5379
|
|
|
4721
5380
|
// src/schema/stack.ts
|
|
4722
|
-
import { z as
|
|
4723
|
-
var StackSchema =
|
|
5381
|
+
import { z as z25 } from "zod";
|
|
5382
|
+
var StackSchema = z25.object({
|
|
4724
5383
|
name: ResourceIdSchema,
|
|
4725
|
-
depends:
|
|
5384
|
+
depends: z25.array(z25.lazy(() => StackSchema)).optional()
|
|
4726
5385
|
});
|
|
4727
5386
|
|
|
4728
5387
|
// src/schema/region.ts
|
|
4729
|
-
import { z as
|
|
5388
|
+
import { z as z26 } from "zod";
|
|
4730
5389
|
var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
|
|
4731
5390
|
var AF = ["af-south-1"];
|
|
4732
5391
|
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 +5402,41 @@ var regions = [
|
|
|
4743
5402
|
...ME,
|
|
4744
5403
|
...SA
|
|
4745
5404
|
];
|
|
4746
|
-
var RegionSchema =
|
|
5405
|
+
var RegionSchema = z26.enum(regions);
|
|
4747
5406
|
|
|
4748
5407
|
// src/schema/plugin.ts
|
|
4749
|
-
import { z as
|
|
4750
|
-
var PluginSchema =
|
|
4751
|
-
name:
|
|
4752
|
-
schema:
|
|
5408
|
+
import { z as z27 } from "zod";
|
|
5409
|
+
var PluginSchema = z27.object({
|
|
5410
|
+
name: z27.string(),
|
|
5411
|
+
schema: z27.custom().optional(),
|
|
4753
5412
|
// depends: z.array(z.lazy(() => PluginSchema)).optional(),
|
|
4754
|
-
onApp:
|
|
4755
|
-
onStack:
|
|
4756
|
-
onResource:
|
|
5413
|
+
onApp: z27.function().returns(z27.void()).optional(),
|
|
5414
|
+
onStack: z27.function().returns(z27.any()).optional(),
|
|
5415
|
+
onResource: z27.function().returns(z27.any()).optional()
|
|
4757
5416
|
// bind: z.function().optional(),
|
|
4758
5417
|
});
|
|
4759
5418
|
|
|
4760
5419
|
// src/schema/app.ts
|
|
4761
|
-
var AppSchema =
|
|
5420
|
+
var AppSchema = z28.object({
|
|
4762
5421
|
/** App name */
|
|
4763
5422
|
name: ResourceIdSchema,
|
|
4764
5423
|
/** The AWS region to deploy to. */
|
|
4765
5424
|
region: RegionSchema,
|
|
4766
5425
|
/** The AWS profile to deploy to. */
|
|
4767
|
-
profile:
|
|
5426
|
+
profile: z28.string(),
|
|
4768
5427
|
/** The deployment stage.
|
|
4769
5428
|
* @default 'prod'
|
|
4770
5429
|
*/
|
|
4771
|
-
stage:
|
|
5430
|
+
stage: z28.string().regex(/^[a-z]+$/).default("prod"),
|
|
4772
5431
|
/** Default properties. */
|
|
4773
|
-
defaults:
|
|
5432
|
+
defaults: z28.object({}).default({}),
|
|
4774
5433
|
/** The application stacks. */
|
|
4775
|
-
stacks:
|
|
5434
|
+
stacks: z28.array(StackSchema).min(1).refine((stacks) => {
|
|
4776
5435
|
const unique = new Set(stacks.map((stack) => stack.name));
|
|
4777
5436
|
return unique.size === stacks.length;
|
|
4778
5437
|
}, "Must be an array of unique stacks"),
|
|
4779
5438
|
/** Custom plugins. */
|
|
4780
|
-
plugins:
|
|
5439
|
+
plugins: z28.array(PluginSchema).optional()
|
|
4781
5440
|
});
|
|
4782
5441
|
|
|
4783
5442
|
// src/util/import.ts
|
|
@@ -4785,7 +5444,7 @@ import { rollup as rollup2, watch } from "rollup";
|
|
|
4785
5444
|
import { swc as swc2 } from "rollup-plugin-swc3";
|
|
4786
5445
|
import replace from "rollup-plugin-replace";
|
|
4787
5446
|
import { EventIterator } from "event-iterator";
|
|
4788
|
-
import { dirname as dirname2, join as
|
|
5447
|
+
import { dirname as dirname2, join as join5 } from "path";
|
|
4789
5448
|
import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
4790
5449
|
var importFile = async (path) => {
|
|
4791
5450
|
const bundle = await rollup2({
|
|
@@ -4805,7 +5464,7 @@ var importFile = async (path) => {
|
|
|
4805
5464
|
})
|
|
4806
5465
|
]
|
|
4807
5466
|
});
|
|
4808
|
-
const outputFile =
|
|
5467
|
+
const outputFile = join5(directories.cache, "config.js");
|
|
4809
5468
|
const result = await bundle.generate({
|
|
4810
5469
|
format: "esm",
|
|
4811
5470
|
exports: "default"
|
|
@@ -4856,7 +5515,7 @@ var watchFile = (path) => {
|
|
|
4856
5515
|
event.result.close();
|
|
4857
5516
|
const output = result.output[0];
|
|
4858
5517
|
const code = output.code;
|
|
4859
|
-
const outputFile =
|
|
5518
|
+
const outputFile = join5(directories.cache, "config.js");
|
|
4860
5519
|
await mkdir2(directories.cache, { recursive: true });
|
|
4861
5520
|
await writeFile2(outputFile, code);
|
|
4862
5521
|
debug("Save config file:", style.info(outputFile));
|
|
@@ -4874,7 +5533,7 @@ var watchFile = (path) => {
|
|
|
4874
5533
|
};
|
|
4875
5534
|
|
|
4876
5535
|
// src/config.ts
|
|
4877
|
-
import { z as
|
|
5536
|
+
import { z as z29 } from "zod";
|
|
4878
5537
|
var ConfigError = class extends Error {
|
|
4879
5538
|
constructor(error, data) {
|
|
4880
5539
|
super(error.message);
|
|
@@ -4889,7 +5548,7 @@ var importConfig = async (options) => {
|
|
|
4889
5548
|
setRoot(root2);
|
|
4890
5549
|
debug("CWD:", style.info(root2));
|
|
4891
5550
|
debug("Import config file");
|
|
4892
|
-
const fileName =
|
|
5551
|
+
const fileName = join6(root2, configFile);
|
|
4893
5552
|
const module = await importFile(fileName);
|
|
4894
5553
|
const appConfig = typeof module.default === "function" ? await module.default(options) : module.default;
|
|
4895
5554
|
debug("Validate config file");
|
|
@@ -4907,7 +5566,7 @@ var importConfig = async (options) => {
|
|
|
4907
5566
|
try {
|
|
4908
5567
|
config = await schema2.parseAsync(appConfig);
|
|
4909
5568
|
} catch (error) {
|
|
4910
|
-
if (error instanceof
|
|
5569
|
+
if (error instanceof z29.ZodError) {
|
|
4911
5570
|
throw new ConfigError(error, appConfig);
|
|
4912
5571
|
}
|
|
4913
5572
|
throw error;
|
|
@@ -4930,7 +5589,7 @@ var watchConfig = async function* (options) {
|
|
|
4930
5589
|
setRoot(root2);
|
|
4931
5590
|
debug("CWD:", style.info(root2));
|
|
4932
5591
|
debug("Import config file");
|
|
4933
|
-
const fileName =
|
|
5592
|
+
const fileName = join6(root2, configFile);
|
|
4934
5593
|
for await (const module of watchFile(fileName)) {
|
|
4935
5594
|
const appConfig = typeof module.default === "function" ? await module.default(options) : module.default;
|
|
4936
5595
|
debug("Validate config file");
|
|
@@ -4948,7 +5607,7 @@ var watchConfig = async function* (options) {
|
|
|
4948
5607
|
try {
|
|
4949
5608
|
config = await schema2.parseAsync(appConfig);
|
|
4950
5609
|
} catch (error) {
|
|
4951
|
-
if (error instanceof
|
|
5610
|
+
if (error instanceof z29.ZodError) {
|
|
4952
5611
|
throw new ConfigError(error, appConfig);
|
|
4953
5612
|
}
|
|
4954
5613
|
throw error;
|
|
@@ -5545,7 +6204,7 @@ var flexLine = (term, left, right, reserveSpace = 0) => {
|
|
|
5545
6204
|
};
|
|
5546
6205
|
|
|
5547
6206
|
// src/cli/ui/complex/builder.ts
|
|
5548
|
-
import { dirname as dirname3, join as
|
|
6207
|
+
import { dirname as dirname3, join as join7 } from "path";
|
|
5549
6208
|
var assetBuilder = (app) => {
|
|
5550
6209
|
return async (term) => {
|
|
5551
6210
|
const assets = [];
|
|
@@ -5608,7 +6267,7 @@ var assetBuilder = (app) => {
|
|
|
5608
6267
|
try {
|
|
5609
6268
|
const data = await asset.build({
|
|
5610
6269
|
async write(file, data2) {
|
|
5611
|
-
const fullpath =
|
|
6270
|
+
const fullpath = join7(directories.asset, asset.type, app.name, stack.name, asset.id, file);
|
|
5612
6271
|
const basepath = dirname3(fullpath);
|
|
5613
6272
|
await mkdir3(basepath, { recursive: true });
|
|
5614
6273
|
await writeFile3(fullpath, data2);
|
|
@@ -5656,14 +6315,14 @@ var cleanUp = async () => {
|
|
|
5656
6315
|
|
|
5657
6316
|
// src/cli/ui/complex/template.ts
|
|
5658
6317
|
import { mkdir as mkdir5, writeFile as writeFile4 } from "fs/promises";
|
|
5659
|
-
import { join as
|
|
6318
|
+
import { join as join8 } from "path";
|
|
5660
6319
|
var templateBuilder = (app) => {
|
|
5661
6320
|
return async (term) => {
|
|
5662
6321
|
const done = term.out.write(loadingDialog("Building stack templates..."));
|
|
5663
6322
|
await Promise.all(app.stacks.map(async (stack) => {
|
|
5664
6323
|
const template = stack.toString(true);
|
|
5665
|
-
const path =
|
|
5666
|
-
const file =
|
|
6324
|
+
const path = join8(directories.template, app.name);
|
|
6325
|
+
const file = join8(path, `${stack.name}.json`);
|
|
5667
6326
|
await mkdir5(path, { recursive: true });
|
|
5668
6327
|
await writeFile4(file, template);
|
|
5669
6328
|
}));
|
|
@@ -5708,7 +6367,7 @@ var bootstrapStack = (account, region) => {
|
|
|
5708
6367
|
stack.add(new Bucket("assets", {
|
|
5709
6368
|
name: assetBucketName(account, region),
|
|
5710
6369
|
accessControl: "private",
|
|
5711
|
-
|
|
6370
|
+
versioning: true
|
|
5712
6371
|
}));
|
|
5713
6372
|
stack.export("version", version);
|
|
5714
6373
|
app.add(stack);
|
|
@@ -5878,6 +6537,7 @@ var StackClient = class {
|
|
|
5878
6537
|
});
|
|
5879
6538
|
debug("Status for:", style.info(name), "is", style.attr(stack.StackStatus));
|
|
5880
6539
|
return {
|
|
6540
|
+
id: stack.StackId,
|
|
5881
6541
|
status: stack.StackStatus,
|
|
5882
6542
|
reason: stack.StackStatusReason,
|
|
5883
6543
|
outputs,
|
|
@@ -5924,10 +6584,10 @@ var StackClient = class {
|
|
|
5924
6584
|
maxWaitTime: this.maxWaitTime,
|
|
5925
6585
|
maxDelay: this.maxDelay
|
|
5926
6586
|
}, {
|
|
5927
|
-
StackName:
|
|
6587
|
+
StackName: data.id
|
|
5928
6588
|
});
|
|
5929
6589
|
} catch (_) {
|
|
5930
|
-
const reason = await this.getFailureReason(
|
|
6590
|
+
const reason = await this.getFailureReason(data.id, region);
|
|
5931
6591
|
throw new Error(reason);
|
|
5932
6592
|
}
|
|
5933
6593
|
}
|
|
@@ -6185,7 +6845,7 @@ var status = (program2) => {
|
|
|
6185
6845
|
|
|
6186
6846
|
// src/cli/ui/complex/publisher.ts
|
|
6187
6847
|
import { readFile as readFile3 } from "fs/promises";
|
|
6188
|
-
import { join as
|
|
6848
|
+
import { join as join9 } from "path";
|
|
6189
6849
|
import { GetObjectCommand, ObjectCannedACL as ObjectCannedACL2, PutObjectCommand as PutObjectCommand2, S3Client as S3Client2, StorageClass as StorageClass2 } from "@aws-sdk/client-s3";
|
|
6190
6850
|
var assetPublisher = (config, app) => {
|
|
6191
6851
|
const client = new S3Client2({
|
|
@@ -6199,12 +6859,12 @@ var assetPublisher = (config, app) => {
|
|
|
6199
6859
|
await Promise.all([...stack.assets].map(async (asset) => {
|
|
6200
6860
|
await asset.publish?.({
|
|
6201
6861
|
async read(file) {
|
|
6202
|
-
const path =
|
|
6862
|
+
const path = join9(directories.asset, asset.type, app.name, stack.name, asset.id, file);
|
|
6203
6863
|
const data = await readFile3(path);
|
|
6204
6864
|
return data;
|
|
6205
6865
|
},
|
|
6206
6866
|
async publish(name, data, hash) {
|
|
6207
|
-
const key = `${app.name}/${stack.name}
|
|
6867
|
+
const key = `${app.name}/${stack.name}/${asset.type}/${name}`;
|
|
6208
6868
|
const bucket = assetBucketName(config.account, config.region);
|
|
6209
6869
|
let getResult;
|
|
6210
6870
|
try {
|
|
@@ -6444,16 +7104,6 @@ var secrets = (program2) => {
|
|
|
6444
7104
|
commands.forEach((cb) => cb(command));
|
|
6445
7105
|
};
|
|
6446
7106
|
|
|
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
7107
|
// src/cli/command/types.ts
|
|
6458
7108
|
var types = (program2) => {
|
|
6459
7109
|
program2.command("types").description("Generate type definition files").action(async () => {
|
|
@@ -6477,6 +7127,48 @@ var dev = (program2) => {
|
|
|
6477
7127
|
});
|
|
6478
7128
|
};
|
|
6479
7129
|
|
|
7130
|
+
// src/cli/command/delete.ts
|
|
7131
|
+
var del2 = (program2) => {
|
|
7132
|
+
program2.command("delete").argument("[stacks...]", "Optionally filter stacks to delete").description("Delete your app from AWS").action(async (filters) => {
|
|
7133
|
+
await layout(async (config, write) => {
|
|
7134
|
+
const { app, deploymentLine } = await toApp(config, filters);
|
|
7135
|
+
const deletingLine = deploymentLine.reverse();
|
|
7136
|
+
const stackNames = app.stacks.map((stack) => stack.name);
|
|
7137
|
+
const formattedFilter = stackNames.map((i) => style.info(i)).join(style.placeholder(", "));
|
|
7138
|
+
debug("Stacks to delete", formattedFilter);
|
|
7139
|
+
const deployAll = filters.length === 0;
|
|
7140
|
+
const deploySingle = filters.length === 1;
|
|
7141
|
+
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?`));
|
|
7142
|
+
if (!confirm) {
|
|
7143
|
+
throw new Cancelled();
|
|
7144
|
+
}
|
|
7145
|
+
const doneDeploying = write(loadingDialog("Deleting stacks from AWS..."));
|
|
7146
|
+
const client = new StackClient(app, config.account, config.region, config.credentials);
|
|
7147
|
+
const ui = write(stacksDeployer(deletingLine));
|
|
7148
|
+
for (const line2 of deletingLine) {
|
|
7149
|
+
const results = await Promise.allSettled(line2.map(async (stack) => {
|
|
7150
|
+
const item = ui[stack.name];
|
|
7151
|
+
item.start("deleting");
|
|
7152
|
+
try {
|
|
7153
|
+
await client.delete(stack.name, stack.region);
|
|
7154
|
+
} catch (error) {
|
|
7155
|
+
debugError(error);
|
|
7156
|
+
item.fail("failed");
|
|
7157
|
+
throw error;
|
|
7158
|
+
}
|
|
7159
|
+
item.done("deleted");
|
|
7160
|
+
}));
|
|
7161
|
+
for (const result of results) {
|
|
7162
|
+
if (result.status === "rejected") {
|
|
7163
|
+
throw result.reason;
|
|
7164
|
+
}
|
|
7165
|
+
}
|
|
7166
|
+
}
|
|
7167
|
+
doneDeploying("Done deleting stacks from AWS");
|
|
7168
|
+
});
|
|
7169
|
+
});
|
|
7170
|
+
};
|
|
7171
|
+
|
|
6480
7172
|
// src/cli/program.ts
|
|
6481
7173
|
var program = new Command();
|
|
6482
7174
|
program.name(logo().join("").replace(/\s+/, ""));
|
|
@@ -6498,9 +7190,10 @@ var commands2 = [
|
|
|
6498
7190
|
types,
|
|
6499
7191
|
build,
|
|
6500
7192
|
deploy,
|
|
7193
|
+
del2,
|
|
6501
7194
|
dev,
|
|
6502
|
-
secrets
|
|
6503
|
-
test
|
|
7195
|
+
secrets
|
|
7196
|
+
// test,
|
|
6504
7197
|
// diff,
|
|
6505
7198
|
// remove,
|
|
6506
7199
|
];
|