@awsless/awsless 0.0.367 → 0.0.369
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/dist/app.json +1 -1
- package/dist/bin.js +768 -626
- package/dist/build-json-schema.js +21 -2
- package/dist/prebuild/rpc/HASH +1 -1
- package/dist/prebuild/rpc/bundle.zip +0 -0
- package/dist/stack.json +1 -1
- package/package.json +11 -11
package/dist/bin.js
CHANGED
|
@@ -596,9 +596,9 @@ var require_Alias = __commonJS({
|
|
|
596
596
|
var anchors = require_anchors();
|
|
597
597
|
var visit = require_visit();
|
|
598
598
|
var identity = require_identity();
|
|
599
|
-
var
|
|
599
|
+
var Node25 = require_Node();
|
|
600
600
|
var toJS = require_toJS();
|
|
601
|
-
var Alias = class extends
|
|
601
|
+
var Alias = class extends Node25.NodeBase {
|
|
602
602
|
constructor(source) {
|
|
603
603
|
super(identity.ALIAS);
|
|
604
604
|
this.source = source;
|
|
@@ -696,10 +696,10 @@ var require_Scalar = __commonJS({
|
|
|
696
696
|
"../../node_modules/.pnpm/yaml@2.5.0/node_modules/yaml/dist/nodes/Scalar.js"(exports) {
|
|
697
697
|
"use strict";
|
|
698
698
|
var identity = require_identity();
|
|
699
|
-
var
|
|
699
|
+
var Node25 = require_Node();
|
|
700
700
|
var toJS = require_toJS();
|
|
701
701
|
var isScalarValue = (value) => !value || typeof value !== "function" && typeof value !== "object";
|
|
702
|
-
var Scalar = class extends
|
|
702
|
+
var Scalar = class extends Node25.NodeBase {
|
|
703
703
|
constructor(value) {
|
|
704
704
|
super(identity.SCALAR);
|
|
705
705
|
this.value = value;
|
|
@@ -803,7 +803,7 @@ var require_Collection = __commonJS({
|
|
|
803
803
|
"use strict";
|
|
804
804
|
var createNode = require_createNode();
|
|
805
805
|
var identity = require_identity();
|
|
806
|
-
var
|
|
806
|
+
var Node25 = require_Node();
|
|
807
807
|
function collectionFromPath(schema, path, value) {
|
|
808
808
|
let v = value;
|
|
809
809
|
for (let i = path.length - 1; i >= 0; --i) {
|
|
@@ -827,7 +827,7 @@ var require_Collection = __commonJS({
|
|
|
827
827
|
});
|
|
828
828
|
}
|
|
829
829
|
var isEmptyPath = (path) => path == null || typeof path === "object" && !!path[Symbol.iterator]().next().done;
|
|
830
|
-
var Collection = class extends
|
|
830
|
+
var Collection = class extends Node25.NodeBase {
|
|
831
831
|
constructor(type, schema) {
|
|
832
832
|
super(type);
|
|
833
833
|
Object.defineProperty(this, "schema", {
|
|
@@ -7680,10 +7680,22 @@ var LogRetentionSchema = DurationSchema.refine(
|
|
|
7680
7680
|
},
|
|
7681
7681
|
`Invalid log retention. Valid days are: ${validLogRetentionDays.map((days7) => `${days7}`).join(", ")}`
|
|
7682
7682
|
).describe("The log retention duration.");
|
|
7683
|
+
var LogSubscriptionSchema = z5.union([
|
|
7684
|
+
LocalFileSchema.transform((file) => ({
|
|
7685
|
+
file
|
|
7686
|
+
})),
|
|
7687
|
+
z5.object({
|
|
7688
|
+
subscriber: LocalFileSchema,
|
|
7689
|
+
filter: z5.string().optional()
|
|
7690
|
+
})
|
|
7691
|
+
]).describe(
|
|
7692
|
+
"Log Subscription allow you to subscribe to a real-time stream of log events and have them delivered to a specific destination"
|
|
7693
|
+
);
|
|
7683
7694
|
var LogSchema = z5.union([
|
|
7684
7695
|
z5.boolean().transform((enabled) => ({ retention: enabled ? days(7) : days(0) })),
|
|
7685
7696
|
LogRetentionSchema.transform((retention) => ({ retention })),
|
|
7686
7697
|
z5.object({
|
|
7698
|
+
subscription: LogSubscriptionSchema.optional(),
|
|
7687
7699
|
retention: LogRetentionSchema.optional(),
|
|
7688
7700
|
format: z5.enum(["text", "json"]).describe(
|
|
7689
7701
|
`The format in which Lambda sends your function's application and system logs to CloudWatch. Select between plain text and structured JSON.`
|
|
@@ -7981,6 +7993,11 @@ var InstancesSchema = z12.record(
|
|
|
7981
7993
|
})
|
|
7982
7994
|
).optional().describe("Define the instances in your stack.");
|
|
7983
7995
|
|
|
7996
|
+
// src/feature/log-subscription/schema.ts
|
|
7997
|
+
var LogSubscriptionSchema2 = FunctionSchema.optional().describe(
|
|
7998
|
+
"Log Subscription allow you to subscribe to a real-time stream of log events and have them delivered to a specific destination."
|
|
7999
|
+
);
|
|
8000
|
+
|
|
7984
8001
|
// src/feature/pubsub/schema.ts
|
|
7985
8002
|
import { z as z13 } from "zod";
|
|
7986
8003
|
var DomainSchema = ResourceIdSchema.describe("The domain id to link your Pubsub API with.");
|
|
@@ -8012,9 +8029,9 @@ var PubSubSchema = z13.record(
|
|
|
8012
8029
|
).optional().describe("Define the pubsub subscriber in your stack.");
|
|
8013
8030
|
|
|
8014
8031
|
// src/feature/queue/schema.ts
|
|
8015
|
-
import { z as z14 } from "zod";
|
|
8016
8032
|
import { days as days2, hours, minutes as minutes3, seconds as seconds2 } from "@awsless/duration";
|
|
8017
8033
|
import { kibibytes } from "@awsless/size";
|
|
8034
|
+
import { z as z14 } from "zod";
|
|
8018
8035
|
var RetentionPeriodSchema = DurationSchema.refine(
|
|
8019
8036
|
durationMin(minutes3(1)),
|
|
8020
8037
|
"Minimum retention period is 1 minute"
|
|
@@ -8073,7 +8090,7 @@ var QueuesSchema = z14.record(
|
|
|
8073
8090
|
}
|
|
8074
8091
|
})),
|
|
8075
8092
|
z14.object({
|
|
8076
|
-
consumer: FunctionSchema.describe("
|
|
8093
|
+
consumer: FunctionSchema.describe("The consuming lambda function properties."),
|
|
8077
8094
|
retentionPeriod: RetentionPeriodSchema.optional(),
|
|
8078
8095
|
visibilityTimeout: VisibilityTimeoutSchema.optional(),
|
|
8079
8096
|
deliveryDelay: DeliveryDelaySchema.optional(),
|
|
@@ -8264,6 +8281,8 @@ var AppSchema = z21.object({
|
|
|
8264
8281
|
// .regex(/^[a-z]+$/)
|
|
8265
8282
|
// .default('prod')
|
|
8266
8283
|
// .describe('The deployment stage.'),
|
|
8284
|
+
// onFailure: OnFailureSchema,
|
|
8285
|
+
logSubscription: LogSubscriptionSchema2,
|
|
8267
8286
|
defaults: z21.object({
|
|
8268
8287
|
auth: AuthDefaultSchema,
|
|
8269
8288
|
domains: DomainsDefaultSchema,
|
|
@@ -8797,411 +8816,143 @@ var loadStackConfigs = async (options) => {
|
|
|
8797
8816
|
return stacks;
|
|
8798
8817
|
};
|
|
8799
8818
|
|
|
8800
|
-
// src/
|
|
8801
|
-
import {
|
|
8802
|
-
|
|
8803
|
-
const data = {
|
|
8804
|
-
App: app.name,
|
|
8805
|
-
Region: app.region,
|
|
8806
|
-
Profile: app.profile
|
|
8807
|
-
};
|
|
8808
|
-
if (opt.stage) {
|
|
8809
|
-
data.Stage = color.warning(opt.stage);
|
|
8810
|
-
}
|
|
8811
|
-
note(wrap(list(data)), "App Config");
|
|
8812
|
-
};
|
|
8813
|
-
|
|
8814
|
-
// src/cli/ui/error/error.ts
|
|
8815
|
-
import { AppError as AppError2, StackError as StackError3 } from "@awsless/formation";
|
|
8816
|
-
import { log as log6 } from "@clack/prompts";
|
|
8819
|
+
// src/feature/auth/index.ts
|
|
8820
|
+
import { aws as aws3, Node as Node2 } from "@awsless/formation";
|
|
8821
|
+
import { constantCase as constantCase2 } from "change-case";
|
|
8817
8822
|
|
|
8818
|
-
// src/
|
|
8819
|
-
|
|
8820
|
-
import { log as log3 } from "@clack/prompts";
|
|
8823
|
+
// src/feature.ts
|
|
8824
|
+
var defineFeature = (feature) => feature;
|
|
8821
8825
|
|
|
8822
|
-
// src/
|
|
8823
|
-
import {
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
|
|
8827
|
-
const value = ` ${capitalCase2(operation)} `;
|
|
8828
|
-
switch (operation) {
|
|
8829
|
-
case "create":
|
|
8830
|
-
return color.success.bold.inverse(value);
|
|
8831
|
-
case "update":
|
|
8832
|
-
return color.warning.bold.inverse(value);
|
|
8833
|
-
case "delete":
|
|
8834
|
-
return color.error.bold.inverse(value);
|
|
8835
|
-
case "heal":
|
|
8836
|
-
return color.warning.bold.inverse(value);
|
|
8837
|
-
case "get":
|
|
8838
|
-
return color.info.bold.inverse(value);
|
|
8826
|
+
// src/type-gen/file.ts
|
|
8827
|
+
import { camelCase } from "change-case";
|
|
8828
|
+
var TypeFile = class {
|
|
8829
|
+
constructor(module) {
|
|
8830
|
+
this.module = module;
|
|
8839
8831
|
}
|
|
8840
|
-
|
|
8841
|
-
|
|
8842
|
-
|
|
8843
|
-
|
|
8844
|
-
|
|
8845
|
-
|
|
8846
|
-
|
|
8847
|
-
)
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
|
|
8853
|
-
|
|
8854
|
-
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
|
|
8832
|
+
codes = /* @__PURE__ */ new Set();
|
|
8833
|
+
interfaces = /* @__PURE__ */ new Map();
|
|
8834
|
+
imports = /* @__PURE__ */ new Map();
|
|
8835
|
+
addImport(varName, path) {
|
|
8836
|
+
this.imports.set(varName, path);
|
|
8837
|
+
return this;
|
|
8838
|
+
}
|
|
8839
|
+
addCode(code) {
|
|
8840
|
+
this.codes.add(code);
|
|
8841
|
+
return this;
|
|
8842
|
+
}
|
|
8843
|
+
addInterface(name, type) {
|
|
8844
|
+
const value = type.toString();
|
|
8845
|
+
if (value) {
|
|
8846
|
+
this.interfaces.set(name, value);
|
|
8847
|
+
}
|
|
8848
|
+
return this;
|
|
8849
|
+
}
|
|
8850
|
+
toString() {
|
|
8851
|
+
if (this.interfaces.size === 0) {
|
|
8852
|
+
return;
|
|
8853
|
+
}
|
|
8854
|
+
const lines = [];
|
|
8855
|
+
if (this.imports.size > 0) {
|
|
8856
|
+
lines.push(
|
|
8857
|
+
...[
|
|
8858
|
+
"// Imports",
|
|
8859
|
+
...Array.from(this.imports.entries()).map(([varName, path]) => {
|
|
8860
|
+
if (typeof varName === "string") {
|
|
8861
|
+
return `import ${camelCase(varName)} from '${path}'`;
|
|
8862
|
+
}
|
|
8863
|
+
return `import { ${Object.entries(varName).map(([key, alias]) => `${key} as ${camelCase(alias)}`).join(", ")} } from '${path}'`;
|
|
8864
|
+
}),
|
|
8865
|
+
""
|
|
8866
|
+
]
|
|
8862
8867
|
);
|
|
8863
|
-
} else if (issue instanceof Error) {
|
|
8864
|
-
log2.message(wrap(color.error(issue.message), { hard: true }), {
|
|
8865
|
-
symbol: color.error(icon.error)
|
|
8866
|
-
});
|
|
8867
8868
|
}
|
|
8869
|
+
if (this.codes.size > 0) {
|
|
8870
|
+
lines.push(...["// Types", ...Array.from(this.codes).map((v) => v.trim()), ""]);
|
|
8871
|
+
}
|
|
8872
|
+
return [
|
|
8873
|
+
...lines,
|
|
8874
|
+
"// Extend module",
|
|
8875
|
+
`declare module '${this.module}' {`,
|
|
8876
|
+
Array.from(this.interfaces).map(([name, type]) => {
|
|
8877
|
+
return ` interface ${name} ${type}`;
|
|
8878
|
+
}).join("\n\n"),
|
|
8879
|
+
// ...Array.from(this.types.entries()).map(([propName, type]) => { // `\tinterface ${this.interfaceName} {`,
|
|
8880
|
+
// return `\t\t${this.readonly ? 'readonly ' : ''}${propName}: ${type}`
|
|
8881
|
+
// }),
|
|
8882
|
+
// `\t}`,
|
|
8883
|
+
`}`,
|
|
8884
|
+
"",
|
|
8885
|
+
"// Export fix",
|
|
8886
|
+
`export {}`
|
|
8887
|
+
].join("\n");
|
|
8868
8888
|
}
|
|
8869
8889
|
};
|
|
8870
8890
|
|
|
8871
|
-
// src/
|
|
8872
|
-
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
|
|
8878
|
-
);
|
|
8879
|
-
|
|
8880
|
-
|
|
8881
|
-
|
|
8882
|
-
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8891
|
+
// src/type-gen/object.ts
|
|
8892
|
+
import { camelCase as camelCase2, constantCase } from "change-case";
|
|
8893
|
+
var TypeObject = class {
|
|
8894
|
+
constructor(level, readonly = true) {
|
|
8895
|
+
this.level = level;
|
|
8896
|
+
this.readonly = readonly;
|
|
8897
|
+
}
|
|
8898
|
+
types = /* @__PURE__ */ new Map();
|
|
8899
|
+
add(name, type) {
|
|
8900
|
+
const value = type.toString();
|
|
8901
|
+
if (value) {
|
|
8902
|
+
this.types.set(name, value);
|
|
8903
|
+
}
|
|
8904
|
+
return this;
|
|
8905
|
+
}
|
|
8906
|
+
addType(name, type) {
|
|
8907
|
+
return this.add(camelCase2(name), type);
|
|
8908
|
+
}
|
|
8909
|
+
addConst(name, type) {
|
|
8910
|
+
return this.add(constantCase(name), type);
|
|
8911
|
+
}
|
|
8912
|
+
toString() {
|
|
8913
|
+
if (!this.types.size) {
|
|
8914
|
+
return "";
|
|
8886
8915
|
}
|
|
8916
|
+
return [
|
|
8917
|
+
"{",
|
|
8918
|
+
...Array.from(this.types.entries()).map(([propName, type]) => {
|
|
8919
|
+
return [
|
|
8920
|
+
" ".repeat(this.level + 1),
|
|
8921
|
+
this.readonly ? "readonly" : "",
|
|
8922
|
+
" ",
|
|
8923
|
+
propName,
|
|
8924
|
+
": ",
|
|
8925
|
+
type
|
|
8926
|
+
].join("");
|
|
8927
|
+
}),
|
|
8928
|
+
`${" ".repeat(this.level)}}`
|
|
8929
|
+
].join("\n");
|
|
8887
8930
|
}
|
|
8888
8931
|
};
|
|
8889
8932
|
|
|
8890
|
-
// src/
|
|
8891
|
-
import
|
|
8892
|
-
|
|
8933
|
+
// src/util/name.ts
|
|
8934
|
+
import { paramCase as paramCase3 } from "change-case";
|
|
8935
|
+
import { createHmac } from "crypto";
|
|
8936
|
+
var formatGlobalResourceName = (opt) => {
|
|
8893
8937
|
return [
|
|
8894
8938
|
//
|
|
8895
|
-
|
|
8896
|
-
|
|
8897
|
-
|
|
8939
|
+
opt.prefix,
|
|
8940
|
+
opt.appName,
|
|
8941
|
+
opt.resourceType,
|
|
8942
|
+
opt.resourceName,
|
|
8943
|
+
opt.postfix
|
|
8944
|
+
].filter((v) => typeof v === "string").map((v) => paramCase3(v)).join(opt.seperator ?? "--");
|
|
8898
8945
|
};
|
|
8899
|
-
var
|
|
8900
|
-
|
|
8901
|
-
|
|
8902
|
-
|
|
8903
|
-
|
|
8904
|
-
|
|
8905
|
-
|
|
8906
|
-
|
|
8907
|
-
|
|
8908
|
-
|
|
8909
|
-
case "bigint":
|
|
8910
|
-
return `${value}n`;
|
|
8911
|
-
case "symbol":
|
|
8912
|
-
return "Symbol()";
|
|
8913
|
-
case "object":
|
|
8914
|
-
return "{ ... }";
|
|
8915
|
-
case "undefined":
|
|
8916
|
-
return "undefined";
|
|
8917
|
-
case "string":
|
|
8918
|
-
case "number":
|
|
8919
|
-
case "boolean":
|
|
8920
|
-
return JSON.stringify(value);
|
|
8921
|
-
}
|
|
8922
|
-
return "";
|
|
8923
|
-
};
|
|
8924
|
-
var logConfigError = (error) => {
|
|
8925
|
-
for (const issue of error.error.errors) {
|
|
8926
|
-
const message = [color.error(issue.message), color.dim(error.file), "\n{"];
|
|
8927
|
-
let context = error.data;
|
|
8928
|
-
const inStack = issue.path[0] === "stacks" && typeof issue.path[1] === "number";
|
|
8929
|
-
const length = issue.path.length;
|
|
8930
|
-
const end = ["}"];
|
|
8931
|
-
issue.path.forEach((path, i) => {
|
|
8932
|
-
const index = i + 1;
|
|
8933
|
-
context = context[path];
|
|
8934
|
-
if (typeof path === "string") {
|
|
8935
|
-
const key = path + `: `;
|
|
8936
|
-
if (index === length) {
|
|
8937
|
-
const space = " ".repeat(key.length);
|
|
8938
|
-
const value = format(context);
|
|
8939
|
-
const error2 = icon.arrow.top.repeat(value.length);
|
|
8940
|
-
message.push(codeLine(key + color.warning(value), index));
|
|
8941
|
-
message.push(codeLine(space + color.error(error2), index));
|
|
8942
|
-
} else if (Array.isArray(context)) {
|
|
8943
|
-
message.push(codeLine(key + "[", index));
|
|
8944
|
-
end.unshift(codeLine("]", index));
|
|
8945
|
-
} else if (typeof context === "object") {
|
|
8946
|
-
if (inStack && index === 3) {
|
|
8947
|
-
const name = error.data.stacks[issue.path[1]].name;
|
|
8948
|
-
message.push(codeLine("name: " + color.info(`"${name}"`) + ",", index));
|
|
8949
|
-
}
|
|
8950
|
-
message.push(codeLine(key + "{", index));
|
|
8951
|
-
end.unshift(codeLine("}", index));
|
|
8952
|
-
}
|
|
8953
|
-
} else if (typeof context === "object") {
|
|
8954
|
-
message.push(codeLine("{", index));
|
|
8955
|
-
end.unshift(codeLine("}", index));
|
|
8956
|
-
} else if (typeof context === "string") {
|
|
8957
|
-
message.push(codeLine(color.warning(`"${context}"`), index));
|
|
8958
|
-
const error2 = icon.arrow.top.repeat(context.length + 2);
|
|
8959
|
-
message.push(codeLine(color.error(error2), index));
|
|
8960
|
-
}
|
|
8961
|
-
});
|
|
8962
|
-
p.log.message(
|
|
8963
|
-
wrap([...message, ...end], {
|
|
8964
|
-
trim: false
|
|
8965
|
-
}),
|
|
8966
|
-
{
|
|
8967
|
-
symbol: color.error`×`
|
|
8968
|
-
}
|
|
8969
|
-
);
|
|
8970
|
-
}
|
|
8971
|
-
};
|
|
8972
|
-
|
|
8973
|
-
// src/cli/ui/error/file-error.ts
|
|
8974
|
-
import { log as log5 } from "@clack/prompts";
|
|
8975
|
-
var logFileError = (error) => {
|
|
8976
|
-
log5.message(
|
|
8977
|
-
wrap([color.error(error.message), color.dim(error.file)].join("\n"), {
|
|
8978
|
-
hard: true
|
|
8979
|
-
}),
|
|
8980
|
-
{ symbol: color.error(icon.error) }
|
|
8981
|
-
);
|
|
8982
|
-
};
|
|
8983
|
-
|
|
8984
|
-
// src/cli/ui/error/error.ts
|
|
8985
|
-
var logError = (error) => {
|
|
8986
|
-
if (error instanceof ConfigError) {
|
|
8987
|
-
logConfigError(error);
|
|
8988
|
-
} else if (error instanceof Cancelled) {
|
|
8989
|
-
log6.message(color.error("Cancelled."), {
|
|
8990
|
-
symbol: color.error(icon.error)
|
|
8991
|
-
});
|
|
8992
|
-
} else if (error instanceof ExpectedError) {
|
|
8993
|
-
log6.message(color.error(error.message), {
|
|
8994
|
-
symbol: color.error(icon.error)
|
|
8995
|
-
});
|
|
8996
|
-
} else if (error instanceof AppError2) {
|
|
8997
|
-
logAppError(error);
|
|
8998
|
-
} else if (error instanceof StackError3) {
|
|
8999
|
-
logStackError(error);
|
|
9000
|
-
} else if (error instanceof FileError) {
|
|
9001
|
-
logFileError(error);
|
|
9002
|
-
} else if (error instanceof Error) {
|
|
9003
|
-
const message = `${error.name}: ${error.message}`;
|
|
9004
|
-
const stack = error.stack ? color.dim(error.stack.replace(message, "")) : "";
|
|
9005
|
-
log6.message(
|
|
9006
|
-
wrap([color.error(message), stack], {
|
|
9007
|
-
hard: true
|
|
9008
|
-
}),
|
|
9009
|
-
{ symbol: color.error(icon.error) }
|
|
9010
|
-
);
|
|
9011
|
-
} else if (typeof error === "string") {
|
|
9012
|
-
log6.message(wrap(color.error(error)), {
|
|
9013
|
-
symbol: color.error(icon.error)
|
|
9014
|
-
});
|
|
9015
|
-
} else {
|
|
9016
|
-
log6.message(wrap(color.error("Unknown error!")), {
|
|
9017
|
-
symbol: color.error(icon.error)
|
|
9018
|
-
});
|
|
9019
|
-
}
|
|
9020
|
-
};
|
|
9021
|
-
|
|
9022
|
-
// src/cli/ui/logo.ts
|
|
9023
|
-
var logo = () => {
|
|
9024
|
-
return `${color.primary`AWS`}${color.primary.dim`LESS`}`;
|
|
9025
|
-
};
|
|
9026
|
-
|
|
9027
|
-
// src/cli/ui/complex/layout.ts
|
|
9028
|
-
var layout = async (command, cb) => {
|
|
9029
|
-
console.log();
|
|
9030
|
-
intro(`${logo()} ${color.dim(command)}`);
|
|
9031
|
-
try {
|
|
9032
|
-
const options = program.optsWithGlobals();
|
|
9033
|
-
const appConfig = await loadAppConfig(options);
|
|
9034
|
-
logApp(appConfig, options);
|
|
9035
|
-
const stackConfigs = await loadStackConfigs(options);
|
|
9036
|
-
const result = await cb({
|
|
9037
|
-
options,
|
|
9038
|
-
appConfig,
|
|
9039
|
-
stackConfigs
|
|
9040
|
-
});
|
|
9041
|
-
outro(result ?? void 0);
|
|
9042
|
-
} catch (error) {
|
|
9043
|
-
logError(error);
|
|
9044
|
-
outro();
|
|
9045
|
-
process.exit(1);
|
|
9046
|
-
}
|
|
9047
|
-
};
|
|
9048
|
-
|
|
9049
|
-
// src/cli/command/bootstrap.ts
|
|
9050
|
-
var bootstrap = (program2) => {
|
|
9051
|
-
program2.command("bootstrap").description("Create the awsless bootstrap stack").action(async () => {
|
|
9052
|
-
await layout("bootstrap", async ({ appConfig }) => {
|
|
9053
|
-
const credentials = getCredentials(appConfig.profile);
|
|
9054
|
-
const accountId = await getAccountId(credentials, appConfig.region);
|
|
9055
|
-
await bootstrapAwsless({
|
|
9056
|
-
credentials,
|
|
9057
|
-
region: appConfig.region,
|
|
9058
|
-
accountId
|
|
9059
|
-
});
|
|
9060
|
-
return "Ready to go!";
|
|
9061
|
-
});
|
|
9062
|
-
});
|
|
9063
|
-
};
|
|
9064
|
-
|
|
9065
|
-
// src/app.ts
|
|
9066
|
-
import { App as App2, Stack } from "@awsless/formation";
|
|
9067
|
-
|
|
9068
|
-
// src/feature/auth/index.ts
|
|
9069
|
-
import { aws as aws3, Node as Node2 } from "@awsless/formation";
|
|
9070
|
-
import { constantCase as constantCase2 } from "change-case";
|
|
9071
|
-
|
|
9072
|
-
// src/feature.ts
|
|
9073
|
-
var defineFeature = (feature) => feature;
|
|
9074
|
-
|
|
9075
|
-
// src/type-gen/file.ts
|
|
9076
|
-
import { camelCase } from "change-case";
|
|
9077
|
-
var TypeFile = class {
|
|
9078
|
-
constructor(module) {
|
|
9079
|
-
this.module = module;
|
|
9080
|
-
}
|
|
9081
|
-
codes = /* @__PURE__ */ new Set();
|
|
9082
|
-
interfaces = /* @__PURE__ */ new Map();
|
|
9083
|
-
imports = /* @__PURE__ */ new Map();
|
|
9084
|
-
addImport(varName, path) {
|
|
9085
|
-
this.imports.set(varName, path);
|
|
9086
|
-
return this;
|
|
9087
|
-
}
|
|
9088
|
-
addCode(code) {
|
|
9089
|
-
this.codes.add(code);
|
|
9090
|
-
return this;
|
|
9091
|
-
}
|
|
9092
|
-
addInterface(name, type) {
|
|
9093
|
-
const value = type.toString();
|
|
9094
|
-
if (value) {
|
|
9095
|
-
this.interfaces.set(name, value);
|
|
9096
|
-
}
|
|
9097
|
-
return this;
|
|
9098
|
-
}
|
|
9099
|
-
toString() {
|
|
9100
|
-
if (this.interfaces.size === 0) {
|
|
9101
|
-
return;
|
|
9102
|
-
}
|
|
9103
|
-
const lines = [];
|
|
9104
|
-
if (this.imports.size > 0) {
|
|
9105
|
-
lines.push(
|
|
9106
|
-
...[
|
|
9107
|
-
"// Imports",
|
|
9108
|
-
...Array.from(this.imports.entries()).map(([varName, path]) => {
|
|
9109
|
-
if (typeof varName === "string") {
|
|
9110
|
-
return `import ${camelCase(varName)} from '${path}'`;
|
|
9111
|
-
}
|
|
9112
|
-
return `import { ${Object.entries(varName).map(([key, alias]) => `${key} as ${camelCase(alias)}`).join(", ")} } from '${path}'`;
|
|
9113
|
-
}),
|
|
9114
|
-
""
|
|
9115
|
-
]
|
|
9116
|
-
);
|
|
9117
|
-
}
|
|
9118
|
-
if (this.codes.size > 0) {
|
|
9119
|
-
lines.push(...["// Types", ...Array.from(this.codes).map((v) => v.trim()), ""]);
|
|
9120
|
-
}
|
|
9121
|
-
return [
|
|
9122
|
-
...lines,
|
|
9123
|
-
"// Extend module",
|
|
9124
|
-
`declare module '${this.module}' {`,
|
|
9125
|
-
Array.from(this.interfaces).map(([name, type]) => {
|
|
9126
|
-
return ` interface ${name} ${type}`;
|
|
9127
|
-
}).join("\n\n"),
|
|
9128
|
-
// ...Array.from(this.types.entries()).map(([propName, type]) => { // `\tinterface ${this.interfaceName} {`,
|
|
9129
|
-
// return `\t\t${this.readonly ? 'readonly ' : ''}${propName}: ${type}`
|
|
9130
|
-
// }),
|
|
9131
|
-
// `\t}`,
|
|
9132
|
-
`}`,
|
|
9133
|
-
"",
|
|
9134
|
-
"// Export fix",
|
|
9135
|
-
`export {}`
|
|
9136
|
-
].join("\n");
|
|
9137
|
-
}
|
|
9138
|
-
};
|
|
9139
|
-
|
|
9140
|
-
// src/type-gen/object.ts
|
|
9141
|
-
import { camelCase as camelCase2, constantCase } from "change-case";
|
|
9142
|
-
var TypeObject = class {
|
|
9143
|
-
constructor(level, readonly = true) {
|
|
9144
|
-
this.level = level;
|
|
9145
|
-
this.readonly = readonly;
|
|
9146
|
-
}
|
|
9147
|
-
types = /* @__PURE__ */ new Map();
|
|
9148
|
-
add(name, type) {
|
|
9149
|
-
const value = type.toString();
|
|
9150
|
-
if (value) {
|
|
9151
|
-
this.types.set(name, value);
|
|
9152
|
-
}
|
|
9153
|
-
return this;
|
|
9154
|
-
}
|
|
9155
|
-
addType(name, type) {
|
|
9156
|
-
return this.add(camelCase2(name), type);
|
|
9157
|
-
}
|
|
9158
|
-
addConst(name, type) {
|
|
9159
|
-
return this.add(constantCase(name), type);
|
|
9160
|
-
}
|
|
9161
|
-
toString() {
|
|
9162
|
-
if (!this.types.size) {
|
|
9163
|
-
return "";
|
|
9164
|
-
}
|
|
9165
|
-
return [
|
|
9166
|
-
"{",
|
|
9167
|
-
...Array.from(this.types.entries()).map(([propName, type]) => {
|
|
9168
|
-
return [
|
|
9169
|
-
" ".repeat(this.level + 1),
|
|
9170
|
-
this.readonly ? "readonly" : "",
|
|
9171
|
-
" ",
|
|
9172
|
-
propName,
|
|
9173
|
-
": ",
|
|
9174
|
-
type
|
|
9175
|
-
].join("");
|
|
9176
|
-
}),
|
|
9177
|
-
`${" ".repeat(this.level)}}`
|
|
9178
|
-
].join("\n");
|
|
9179
|
-
}
|
|
9180
|
-
};
|
|
9181
|
-
|
|
9182
|
-
// src/util/name.ts
|
|
9183
|
-
import { paramCase as paramCase3 } from "change-case";
|
|
9184
|
-
import { createHmac } from "crypto";
|
|
9185
|
-
var formatGlobalResourceName = (opt) => {
|
|
9186
|
-
return [
|
|
9187
|
-
//
|
|
9188
|
-
opt.prefix,
|
|
9189
|
-
opt.appName,
|
|
9190
|
-
opt.resourceType,
|
|
9191
|
-
opt.resourceName,
|
|
9192
|
-
opt.postfix
|
|
9193
|
-
].filter((v) => typeof v === "string").map((v) => paramCase3(v)).join(opt.seperator ?? "--");
|
|
9194
|
-
};
|
|
9195
|
-
var formatLocalResourceName = (opt) => {
|
|
9196
|
-
return [
|
|
9197
|
-
//
|
|
9198
|
-
opt.prefix,
|
|
9199
|
-
opt.appName,
|
|
9200
|
-
opt.stackName,
|
|
9201
|
-
opt.resourceType,
|
|
9202
|
-
opt.resourceName,
|
|
9203
|
-
opt.postfix
|
|
9204
|
-
].filter((v) => typeof v === "string").map((v) => paramCase3(v)).join(opt.seperator ?? "--");
|
|
8946
|
+
var formatLocalResourceName = (opt) => {
|
|
8947
|
+
return [
|
|
8948
|
+
//
|
|
8949
|
+
opt.prefix,
|
|
8950
|
+
opt.appName,
|
|
8951
|
+
opt.stackName,
|
|
8952
|
+
opt.resourceType,
|
|
8953
|
+
opt.resourceName,
|
|
8954
|
+
opt.postfix
|
|
8955
|
+
].filter((v) => typeof v === "string").map((v) => paramCase3(v)).join(opt.seperator ?? "--");
|
|
9205
8956
|
};
|
|
9206
8957
|
var generateGlobalAppId = (opt) => {
|
|
9207
8958
|
return createHmac("sha1", "awsless").update(opt.accountId).update(opt.region).update(opt.appName).digest("hex").substring(0, 8);
|
|
@@ -10929,6 +10680,14 @@ var createLambdaFunction = (group, ctx, ns, id, local2) => {
|
|
|
10929
10680
|
resources: [logGroup.arn.apply((arn) => `${arn}:*`)]
|
|
10930
10681
|
}
|
|
10931
10682
|
);
|
|
10683
|
+
const logSubscriptionArn = ctx.shared.get("log-subscription-destination-arn");
|
|
10684
|
+
if (logSubscriptionArn) {
|
|
10685
|
+
new aws2.cloudWatch.SubscriptionFilter(group, `log-subscription`, {
|
|
10686
|
+
destinationArn: logSubscriptionArn,
|
|
10687
|
+
logGroupName: logGroup.name,
|
|
10688
|
+
filterPattern: "{$.level = ERROR}"
|
|
10689
|
+
});
|
|
10690
|
+
}
|
|
10932
10691
|
}
|
|
10933
10692
|
if (ctx.appConfig.defaults.function.permissions) {
|
|
10934
10693
|
policy.addStatement(...ctx.appConfig.defaults.function.permissions);
|
|
@@ -11196,14 +10955,20 @@ var cacheFeature = defineFeature({
|
|
|
11196
10955
|
// src/feature/command/index.ts
|
|
11197
10956
|
var commandFeature = defineFeature({
|
|
11198
10957
|
name: "command",
|
|
11199
|
-
|
|
10958
|
+
onValidate(ctx) {
|
|
11200
10959
|
const names = /* @__PURE__ */ new Set();
|
|
11201
|
-
for (const
|
|
11202
|
-
|
|
11203
|
-
names.
|
|
11204
|
-
|
|
11205
|
-
|
|
10960
|
+
for (const stack of ctx.stackConfigs) {
|
|
10961
|
+
for (const name of Object.keys(stack.commands ?? {})) {
|
|
10962
|
+
if (!names.has(name)) {
|
|
10963
|
+
names.add(name);
|
|
10964
|
+
} else {
|
|
10965
|
+
throw new FileError(stack.file, `Duplicate command names aren't allowed: ${name}`);
|
|
10966
|
+
}
|
|
11206
10967
|
}
|
|
10968
|
+
}
|
|
10969
|
+
},
|
|
10970
|
+
onStack(ctx) {
|
|
10971
|
+
for (const [name, props] of Object.entries(ctx.stackConfig.commands ?? {})) {
|
|
11207
10972
|
ctx.registerCommand({ name, ...props });
|
|
11208
10973
|
}
|
|
11209
10974
|
}
|
|
@@ -12302,8 +12067,75 @@ var instanceFeature = defineFeature({
|
|
|
12302
12067
|
}
|
|
12303
12068
|
});
|
|
12304
12069
|
|
|
12305
|
-
// src/feature/
|
|
12070
|
+
// src/feature/log-subscription/index.ts
|
|
12306
12071
|
import { Node as Node10, aws as aws11 } from "@awsless/formation";
|
|
12072
|
+
var logSubscriptionFeature = defineFeature({
|
|
12073
|
+
name: "log-subscription",
|
|
12074
|
+
onApp(ctx) {
|
|
12075
|
+
if (!ctx.appConfig.logSubscription) {
|
|
12076
|
+
return;
|
|
12077
|
+
}
|
|
12078
|
+
const group = new Node10(ctx.base, "log-subscription", "main");
|
|
12079
|
+
const { lambda, policy } = createLambdaFunction(
|
|
12080
|
+
group,
|
|
12081
|
+
ctx,
|
|
12082
|
+
"log-subscription",
|
|
12083
|
+
"main",
|
|
12084
|
+
ctx.appConfig.logSubscription
|
|
12085
|
+
);
|
|
12086
|
+
new aws11.lambda.Permission(group, "log-subscription-permission", {
|
|
12087
|
+
action: "lambda:InvokeFunction",
|
|
12088
|
+
principal: "logs.amazonaws.com",
|
|
12089
|
+
functionArn: lambda.arn,
|
|
12090
|
+
sourceArn: `arn:aws:logs:${ctx.appConfig.region}:${ctx.accountId}:log-group:/aws/lambda/app-kennedy--*`
|
|
12091
|
+
});
|
|
12092
|
+
ctx.shared.set("log-subscription-destination-arn", lambda.arn);
|
|
12093
|
+
for (const stack of ctx.stackConfigs) {
|
|
12094
|
+
for (const id of stack.topics ?? []) {
|
|
12095
|
+
policy.addStatement({
|
|
12096
|
+
actions: ["sns:Publish"],
|
|
12097
|
+
resources: [ctx.shared.get(`topic-${id}-arn`)]
|
|
12098
|
+
});
|
|
12099
|
+
}
|
|
12100
|
+
for (const [id, props] of Object.entries(stack.tables ?? {})) {
|
|
12101
|
+
const tableName = formatLocalResourceName({
|
|
12102
|
+
appName: ctx.app.name,
|
|
12103
|
+
stackName: stack.name,
|
|
12104
|
+
resourceType: "table",
|
|
12105
|
+
resourceName: id
|
|
12106
|
+
});
|
|
12107
|
+
policy.addStatement({
|
|
12108
|
+
actions: [
|
|
12109
|
+
"dynamodb:DescribeTable",
|
|
12110
|
+
"dynamodb:PutItem",
|
|
12111
|
+
"dynamodb:GetItem",
|
|
12112
|
+
"dynamodb:UpdateItem",
|
|
12113
|
+
"dynamodb:DeleteItem",
|
|
12114
|
+
"dynamodb:TransactWrite",
|
|
12115
|
+
"dynamodb:BatchWriteItem",
|
|
12116
|
+
"dynamodb:BatchGetItem",
|
|
12117
|
+
"dynamodb:ConditionCheckItem",
|
|
12118
|
+
"dynamodb:Query",
|
|
12119
|
+
"dynamodb:Scan"
|
|
12120
|
+
],
|
|
12121
|
+
resources: [`arn:aws:dynamodb:${ctx.appConfig.region}:${ctx.accountId}:table/${tableName}`]
|
|
12122
|
+
});
|
|
12123
|
+
const indexes = Object.keys(props.indexes ?? {});
|
|
12124
|
+
if (indexes.length) {
|
|
12125
|
+
policy.addStatement({
|
|
12126
|
+
actions: ["dynamodb:Query"],
|
|
12127
|
+
resources: indexes.map(
|
|
12128
|
+
(indexName) => `arn:aws:dynamodb:${ctx.appConfig.region}:${ctx.accountId}:table/${tableName}/index/${indexName}`
|
|
12129
|
+
)
|
|
12130
|
+
});
|
|
12131
|
+
}
|
|
12132
|
+
}
|
|
12133
|
+
}
|
|
12134
|
+
}
|
|
12135
|
+
});
|
|
12136
|
+
|
|
12137
|
+
// src/feature/on-failure/index.ts
|
|
12138
|
+
import { Node as Node11, aws as aws12 } from "@awsless/formation";
|
|
12307
12139
|
var onFailureFeature = defineFeature({
|
|
12308
12140
|
name: "on-failure",
|
|
12309
12141
|
onApp(ctx) {
|
|
@@ -12314,7 +12146,7 @@ var onFailureFeature = defineFeature({
|
|
|
12314
12146
|
if (count > 1) {
|
|
12315
12147
|
throw new TypeError("Only 1 onFailure configuration is allowed in your app.");
|
|
12316
12148
|
}
|
|
12317
|
-
const queue2 = new
|
|
12149
|
+
const queue2 = new aws12.sqs.Queue(ctx.base, "on-failure", {
|
|
12318
12150
|
name: formatGlobalResourceName({
|
|
12319
12151
|
appName: ctx.app.name,
|
|
12320
12152
|
resourceType: "on-failure",
|
|
@@ -12329,9 +12161,9 @@ var onFailureFeature = defineFeature({
|
|
|
12329
12161
|
return;
|
|
12330
12162
|
}
|
|
12331
12163
|
const queueArn = ctx.shared.get("on-failure-queue-arn");
|
|
12332
|
-
const group = new
|
|
12164
|
+
const group = new Node11(ctx.stack, "on-failure", "failure");
|
|
12333
12165
|
const { lambda, policy } = createLambdaFunction(group, ctx, "on-failure", "failure", onFailure);
|
|
12334
|
-
const source = new
|
|
12166
|
+
const source = new aws12.lambda.EventSourceMapping(group, "on-failure", {
|
|
12335
12167
|
functionArn: lambda.arn,
|
|
12336
12168
|
sourceArn: queueArn,
|
|
12337
12169
|
batchSize: 10
|
|
@@ -12351,13 +12183,13 @@ var onFailureFeature = defineFeature({
|
|
|
12351
12183
|
});
|
|
12352
12184
|
|
|
12353
12185
|
// src/feature/pubsub/index.ts
|
|
12354
|
-
import { aws as
|
|
12186
|
+
import { aws as aws13, Node as Node12 } from "@awsless/formation";
|
|
12355
12187
|
import { constantCase as constantCase6 } from "change-case";
|
|
12356
12188
|
var pubsubFeature = defineFeature({
|
|
12357
12189
|
name: "pubsub",
|
|
12358
12190
|
onApp(ctx) {
|
|
12359
12191
|
for (const [id, props] of Object.entries(ctx.appConfig.defaults.pubsub ?? {})) {
|
|
12360
|
-
const group = new
|
|
12192
|
+
const group = new Node12(ctx.base, "pubsub", id);
|
|
12361
12193
|
const functionProps = typeof props.auth === "string" ? { file: "" } : props.auth.authorizer;
|
|
12362
12194
|
const { lambda } = createLambdaFunction(group, ctx, "pubsub-authorizer", id, functionProps);
|
|
12363
12195
|
lambda.addEnvironment("PUBSUB_POLICY", JSON.stringify(props.policy));
|
|
@@ -12367,23 +12199,23 @@ var pubsubFeature = defineFeature({
|
|
|
12367
12199
|
resourceType: "pubsub",
|
|
12368
12200
|
resourceName: id
|
|
12369
12201
|
});
|
|
12370
|
-
const authorizer = new
|
|
12202
|
+
const authorizer = new aws13.iot.Authorizer(group, "authorizer", {
|
|
12371
12203
|
name,
|
|
12372
12204
|
functionArn: lambda.arn
|
|
12373
12205
|
});
|
|
12374
|
-
new
|
|
12206
|
+
new aws13.lambda.Permission(group, "permission", {
|
|
12375
12207
|
functionArn: lambda.arn,
|
|
12376
12208
|
principal: "iot.amazonaws.com",
|
|
12377
12209
|
sourceArn: authorizer.arn,
|
|
12378
12210
|
action: "lambda:InvokeFunction"
|
|
12379
12211
|
});
|
|
12380
12212
|
ctx.bind(`PUBSUB_${constantCase6(id)}_AUTHORIZER`, name);
|
|
12381
|
-
const endpoint = new
|
|
12213
|
+
const endpoint = new aws13.iot.Endpoint(group, "endpoint", {
|
|
12382
12214
|
type: "data-ats"
|
|
12383
12215
|
});
|
|
12384
12216
|
if (props.domain) {
|
|
12385
12217
|
const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
12386
|
-
new
|
|
12218
|
+
new aws13.iot.DomainConfiguration(group, "domain", {
|
|
12387
12219
|
name,
|
|
12388
12220
|
domainName,
|
|
12389
12221
|
certificates: [ctx.shared.get(`local-certificate-${props.domain}-arn`)],
|
|
@@ -12392,7 +12224,7 @@ var pubsubFeature = defineFeature({
|
|
|
12392
12224
|
}
|
|
12393
12225
|
// validationCertificate: ctx.shared.get(`global-certificate-${props.domain}-arn`),
|
|
12394
12226
|
});
|
|
12395
|
-
new
|
|
12227
|
+
new aws13.route53.RecordSet(group, "record", {
|
|
12396
12228
|
hostedZoneId: ctx.shared.get(`hosted-zone-${props.domain}-id`),
|
|
12397
12229
|
name: domainName,
|
|
12398
12230
|
type: "CNAME",
|
|
@@ -12413,7 +12245,7 @@ var pubsubFeature = defineFeature({
|
|
|
12413
12245
|
},
|
|
12414
12246
|
onStack(ctx) {
|
|
12415
12247
|
for (const [id, props] of Object.entries(ctx.stackConfig.pubsub ?? {})) {
|
|
12416
|
-
const group = new
|
|
12248
|
+
const group = new Node12(ctx.stack, "pubsub", id);
|
|
12417
12249
|
const { lambda } = createAsyncLambdaFunction(group, ctx, `pubsub`, id, props.consumer);
|
|
12418
12250
|
const name = formatLocalResourceName({
|
|
12419
12251
|
appName: ctx.app.name,
|
|
@@ -12421,13 +12253,13 @@ var pubsubFeature = defineFeature({
|
|
|
12421
12253
|
resourceType: "pubsub",
|
|
12422
12254
|
resourceName: id
|
|
12423
12255
|
});
|
|
12424
|
-
const topic = new
|
|
12256
|
+
const topic = new aws13.iot.TopicRule(group, "rule", {
|
|
12425
12257
|
name: name.replaceAll("-", "_"),
|
|
12426
12258
|
sql: props.sql,
|
|
12427
12259
|
sqlVersion: props.sqlVersion,
|
|
12428
12260
|
actions: [{ lambda: { functionArn: lambda.arn } }]
|
|
12429
12261
|
});
|
|
12430
|
-
new
|
|
12262
|
+
new aws13.lambda.Permission(group, "permission", {
|
|
12431
12263
|
action: "lambda:InvokeFunction",
|
|
12432
12264
|
principal: "iot.amazonaws.com",
|
|
12433
12265
|
functionArn: lambda.arn,
|
|
@@ -12438,7 +12270,7 @@ var pubsubFeature = defineFeature({
|
|
|
12438
12270
|
});
|
|
12439
12271
|
|
|
12440
12272
|
// src/feature/queue/index.ts
|
|
12441
|
-
import { aws as
|
|
12273
|
+
import { aws as aws14, Node as Node13 } from "@awsless/formation";
|
|
12442
12274
|
import { camelCase as camelCase5, constantCase as constantCase7 } from "change-case";
|
|
12443
12275
|
import deepmerge3 from "deepmerge";
|
|
12444
12276
|
import { relative as relative4 } from "path";
|
|
@@ -12498,21 +12330,21 @@ var queueFeature = defineFeature({
|
|
|
12498
12330
|
onStack(ctx) {
|
|
12499
12331
|
for (const [id, local2] of Object.entries(ctx.stackConfig.queues || {})) {
|
|
12500
12332
|
const props = deepmerge3(ctx.appConfig.defaults.queue, local2);
|
|
12501
|
-
const group = new
|
|
12333
|
+
const group = new Node13(ctx.stack, "queue", id);
|
|
12502
12334
|
const name = formatLocalResourceName({
|
|
12503
12335
|
appName: ctx.app.name,
|
|
12504
12336
|
stackName: ctx.stack.name,
|
|
12505
12337
|
resourceType: "queue",
|
|
12506
12338
|
resourceName: id
|
|
12507
12339
|
});
|
|
12508
|
-
const queue2 = new
|
|
12340
|
+
const queue2 = new aws14.sqs.Queue(group, "queue", {
|
|
12509
12341
|
name,
|
|
12510
12342
|
deadLetterArn: getGlobalOnFailure(ctx),
|
|
12511
12343
|
...props
|
|
12512
12344
|
});
|
|
12513
12345
|
const { lambda, policy } = createLambdaFunction(group, ctx, `queue`, id, props.consumer);
|
|
12514
12346
|
lambda.addEnvironment("LOG_VIEWABLE_ERROR", "1");
|
|
12515
|
-
new
|
|
12347
|
+
new aws14.lambda.EventSourceMapping(group, "event", {
|
|
12516
12348
|
functionArn: lambda.arn,
|
|
12517
12349
|
sourceArn: queue2.arn,
|
|
12518
12350
|
batchSize: props.batchSize,
|
|
@@ -12532,23 +12364,23 @@ var queueFeature = defineFeature({
|
|
|
12532
12364
|
});
|
|
12533
12365
|
|
|
12534
12366
|
// src/feature/rest/index.ts
|
|
12535
|
-
import { aws as
|
|
12367
|
+
import { aws as aws15, Node as Node14 } from "@awsless/formation";
|
|
12536
12368
|
import { constantCase as constantCase8 } from "change-case";
|
|
12537
12369
|
var restFeature = defineFeature({
|
|
12538
12370
|
name: "rest",
|
|
12539
12371
|
onApp(ctx) {
|
|
12540
12372
|
for (const [id, props] of Object.entries(ctx.appConfig.defaults?.rest ?? {})) {
|
|
12541
|
-
const group = new
|
|
12373
|
+
const group = new Node14(ctx.base, "rest", id);
|
|
12542
12374
|
const name = formatGlobalResourceName({
|
|
12543
12375
|
appName: ctx.app.name,
|
|
12544
12376
|
resourceType: "rest",
|
|
12545
12377
|
resourceName: id
|
|
12546
12378
|
});
|
|
12547
|
-
const api = new
|
|
12379
|
+
const api = new aws15.apiGatewayV2.Api(group, "api", {
|
|
12548
12380
|
name,
|
|
12549
12381
|
protocolType: "HTTP"
|
|
12550
12382
|
});
|
|
12551
|
-
const stage = new
|
|
12383
|
+
const stage = new aws15.apiGatewayV2.Stage(group, "stage", {
|
|
12552
12384
|
name: "v1",
|
|
12553
12385
|
apiId: api.id
|
|
12554
12386
|
});
|
|
@@ -12557,7 +12389,7 @@ var restFeature = defineFeature({
|
|
|
12557
12389
|
const domainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
12558
12390
|
const hostedZoneId = ctx.shared.get(`hosted-zone-${props.domain}-id`);
|
|
12559
12391
|
const certificateArn = ctx.shared.get(`certificate-${props.domain}-arn`);
|
|
12560
|
-
const domain = new
|
|
12392
|
+
const domain = new aws15.apiGatewayV2.DomainName(group, "domain", {
|
|
12561
12393
|
name: domainName,
|
|
12562
12394
|
certificates: [
|
|
12563
12395
|
{
|
|
@@ -12565,12 +12397,12 @@ var restFeature = defineFeature({
|
|
|
12565
12397
|
}
|
|
12566
12398
|
]
|
|
12567
12399
|
});
|
|
12568
|
-
const mapping = new
|
|
12400
|
+
const mapping = new aws15.apiGatewayV2.ApiMapping(group, "mapping", {
|
|
12569
12401
|
apiId: api.id,
|
|
12570
12402
|
domainName: domain.name,
|
|
12571
12403
|
stage: stage.name
|
|
12572
12404
|
});
|
|
12573
|
-
const record = new
|
|
12405
|
+
const record = new aws15.route53.RecordSet(group, "record", {
|
|
12574
12406
|
hostedZoneId,
|
|
12575
12407
|
type: "A",
|
|
12576
12408
|
name: domainName,
|
|
@@ -12588,21 +12420,21 @@ var restFeature = defineFeature({
|
|
|
12588
12420
|
},
|
|
12589
12421
|
onStack(ctx) {
|
|
12590
12422
|
for (const [id, routes] of Object.entries(ctx.stackConfig.rest ?? {})) {
|
|
12591
|
-
const restGroup = new
|
|
12423
|
+
const restGroup = new Node14(ctx.stack, "rest", id);
|
|
12592
12424
|
for (const [routeKey, props] of Object.entries(routes)) {
|
|
12593
|
-
const group = new
|
|
12425
|
+
const group = new Node14(restGroup, "route", routeKey);
|
|
12594
12426
|
const apiId = ctx.shared.get(`rest-${id}-id`);
|
|
12595
12427
|
const routeId = shortId(routeKey);
|
|
12596
12428
|
const { lambda } = createLambdaFunction(group, ctx, "rest", `${id}-${routeId}`, {
|
|
12597
12429
|
...props,
|
|
12598
12430
|
description: `${id} ${routeKey}`
|
|
12599
12431
|
});
|
|
12600
|
-
const permission = new
|
|
12432
|
+
const permission = new aws15.lambda.Permission(group, "permission", {
|
|
12601
12433
|
action: "lambda:InvokeFunction",
|
|
12602
12434
|
principal: "apigateway.amazonaws.com",
|
|
12603
12435
|
functionArn: lambda.arn
|
|
12604
12436
|
});
|
|
12605
|
-
const integration = new
|
|
12437
|
+
const integration = new aws15.apiGatewayV2.Integration(group, "integration", {
|
|
12606
12438
|
apiId,
|
|
12607
12439
|
description: `${id} ${routeKey}`,
|
|
12608
12440
|
method: "POST",
|
|
@@ -12612,7 +12444,7 @@ var restFeature = defineFeature({
|
|
|
12612
12444
|
return `arn:aws:apigateway:${ctx.appConfig.region}:lambda:path/2015-03-31/functions/${arn}/invocations`;
|
|
12613
12445
|
})
|
|
12614
12446
|
});
|
|
12615
|
-
const route = new
|
|
12447
|
+
const route = new aws15.apiGatewayV2.Route(group, "route", {
|
|
12616
12448
|
apiId,
|
|
12617
12449
|
routeKey,
|
|
12618
12450
|
target: integration.id.apply((id2) => `integrations/${id2}`)
|
|
@@ -12625,13 +12457,13 @@ var restFeature = defineFeature({
|
|
|
12625
12457
|
|
|
12626
12458
|
// src/feature/rpc/index.ts
|
|
12627
12459
|
import { camelCase as camelCase6, constantCase as constantCase9, paramCase as paramCase6 } from "change-case";
|
|
12628
|
-
import { aws as
|
|
12460
|
+
import { aws as aws17, Node as Node16, Output as Output3 } from "@awsless/formation";
|
|
12629
12461
|
import { mebibytes as mebibytes2 } from "@awsless/size";
|
|
12630
12462
|
import { dirname as dirname10, join as join8, relative as relative5 } from "path";
|
|
12631
12463
|
import { fileURLToPath } from "node:url";
|
|
12632
12464
|
|
|
12633
12465
|
// src/feature/function/prebuild.ts
|
|
12634
|
-
import { Asset as Asset4, aws as
|
|
12466
|
+
import { Asset as Asset4, aws as aws16 } from "@awsless/formation";
|
|
12635
12467
|
var createPrebuildLambdaFunction = (group, ctx, ns, id, local2) => {
|
|
12636
12468
|
let name;
|
|
12637
12469
|
if ("stack" in ctx) {
|
|
@@ -12653,21 +12485,21 @@ var createPrebuildLambdaFunction = (group, ctx, ns, id, local2) => {
|
|
|
12653
12485
|
runtime: "nodejs20.x",
|
|
12654
12486
|
...local2
|
|
12655
12487
|
};
|
|
12656
|
-
const code = new
|
|
12488
|
+
const code = new aws16.s3.BucketObject(group, "code", {
|
|
12657
12489
|
bucket: ctx.shared.get("function-bucket-name"),
|
|
12658
12490
|
key: `/lambda/${name}.zip`,
|
|
12659
12491
|
body: Asset4.fromFile(props.bundleFile)
|
|
12660
12492
|
});
|
|
12661
|
-
const role = new
|
|
12493
|
+
const role = new aws16.iam.Role(group, "role", {
|
|
12662
12494
|
name,
|
|
12663
12495
|
assumedBy: "lambda.amazonaws.com"
|
|
12664
12496
|
});
|
|
12665
|
-
const policy = new
|
|
12497
|
+
const policy = new aws16.iam.RolePolicy(group, "policy", {
|
|
12666
12498
|
role: role.name,
|
|
12667
12499
|
name: "lambda-policy",
|
|
12668
12500
|
version: "2012-10-17"
|
|
12669
12501
|
});
|
|
12670
|
-
const lambda = new
|
|
12502
|
+
const lambda = new aws16.lambda.Function(group, `function`, {
|
|
12671
12503
|
...props,
|
|
12672
12504
|
name,
|
|
12673
12505
|
role: role.arn,
|
|
@@ -12677,7 +12509,7 @@ var createPrebuildLambdaFunction = (group, ctx, ns, id, local2) => {
|
|
|
12677
12509
|
vpc: void 0,
|
|
12678
12510
|
log: props.log
|
|
12679
12511
|
});
|
|
12680
|
-
new
|
|
12512
|
+
new aws16.lambda.SourceCodeUpdate(group, "update", {
|
|
12681
12513
|
functionName: lambda.name,
|
|
12682
12514
|
version: Asset4.fromFile(props.bundleHash),
|
|
12683
12515
|
architecture: props.architecture,
|
|
@@ -12693,7 +12525,7 @@ var createPrebuildLambdaFunction = (group, ctx, ns, id, local2) => {
|
|
|
12693
12525
|
lambda.addEnvironment("STACK", ctx.stackConfig.name);
|
|
12694
12526
|
}
|
|
12695
12527
|
if (props.log?.retention && props.log?.retention?.value > 0n) {
|
|
12696
|
-
const logGroup = new
|
|
12528
|
+
const logGroup = new aws16.cloudWatch.LogGroup(group, "log", {
|
|
12697
12529
|
name: lambda.name.apply((name2) => `/aws/lambda/${name2}`),
|
|
12698
12530
|
retention: props.log.retention
|
|
12699
12531
|
});
|
|
@@ -12712,7 +12544,7 @@ var createPrebuildLambdaFunction = (group, ctx, ns, id, local2) => {
|
|
|
12712
12544
|
policy.addStatement(...local2.permissions);
|
|
12713
12545
|
}
|
|
12714
12546
|
if (props.warm) {
|
|
12715
|
-
const rule = new
|
|
12547
|
+
const rule = new aws16.events.Rule(group, "warm", {
|
|
12716
12548
|
name: `${name}--warm`,
|
|
12717
12549
|
schedule: "rate(5 minutes)",
|
|
12718
12550
|
enabled: true,
|
|
@@ -12727,7 +12559,7 @@ var createPrebuildLambdaFunction = (group, ctx, ns, id, local2) => {
|
|
|
12727
12559
|
}
|
|
12728
12560
|
]
|
|
12729
12561
|
});
|
|
12730
|
-
new
|
|
12562
|
+
new aws16.lambda.Permission(group, `warm`, {
|
|
12731
12563
|
action: "lambda:InvokeFunction",
|
|
12732
12564
|
principal: "events.amazonaws.com",
|
|
12733
12565
|
functionArn: lambda.arn,
|
|
@@ -12742,7 +12574,7 @@ var createPrebuildLambdaFunction = (group, ctx, ns, id, local2) => {
|
|
|
12742
12574
|
ctx.shared.get(`vpc-public-subnet-id-2`)
|
|
12743
12575
|
]
|
|
12744
12576
|
});
|
|
12745
|
-
const vpcPolicy = new
|
|
12577
|
+
const vpcPolicy = new aws16.iam.RolePolicy(group, "vpc-policy", {
|
|
12746
12578
|
role: role.name,
|
|
12747
12579
|
name: "lambda-vpc-policy",
|
|
12748
12580
|
version: "2012-10-17",
|
|
@@ -12776,6 +12608,9 @@ var rpcFeature = defineFeature({
|
|
|
12776
12608
|
name: "rpc",
|
|
12777
12609
|
async onTypeGen(ctx) {
|
|
12778
12610
|
const types2 = new TypeFile("@awsless/awsless/client");
|
|
12611
|
+
types2.addCode(`type Input<T> = Parameters<T>[0]`);
|
|
12612
|
+
types2.addCode(`type Output<T> = Promise<ReturnType<T>>`);
|
|
12613
|
+
types2.addCode(`type Handle<T> = (input:Input<T>) => Output<T>`);
|
|
12779
12614
|
const schemas = new TypeObject(1);
|
|
12780
12615
|
for (const id of Object.keys(ctx.appConfig.defaults.rpc ?? {})) {
|
|
12781
12616
|
const schema = new TypeObject(2);
|
|
@@ -12784,7 +12619,7 @@ var rpcFeature = defineFeature({
|
|
|
12784
12619
|
const relFile = relative5(directories.types, props.file);
|
|
12785
12620
|
const varName = camelCase6(`${stack.name}-${name}`);
|
|
12786
12621
|
types2.addImport(varName, relFile);
|
|
12787
|
-
schema.addType(name, `
|
|
12622
|
+
schema.addType(name, `Handle<typeof ${varName}>`);
|
|
12788
12623
|
}
|
|
12789
12624
|
}
|
|
12790
12625
|
schemas.addType(id, schema);
|
|
@@ -12792,9 +12627,27 @@ var rpcFeature = defineFeature({
|
|
|
12792
12627
|
types2.addInterface("RpcSchema", schemas);
|
|
12793
12628
|
await ctx.write("rpc.d.ts", types2, true);
|
|
12794
12629
|
},
|
|
12630
|
+
onValidate(ctx) {
|
|
12631
|
+
const names = {};
|
|
12632
|
+
for (const id of Object.keys(ctx.appConfig.defaults.rpc ?? {})) {
|
|
12633
|
+
names[id] = /* @__PURE__ */ new Set();
|
|
12634
|
+
}
|
|
12635
|
+
for (const stack of ctx.stackConfigs) {
|
|
12636
|
+
for (const [id, queries] of Object.entries(stack.rpc ?? {})) {
|
|
12637
|
+
const list4 = names[id];
|
|
12638
|
+
for (const name of Object.keys(queries ?? {})) {
|
|
12639
|
+
if (list4.has(name)) {
|
|
12640
|
+
throw new FileError(stack.file, `Double RPC API function "${id}.${name}"`);
|
|
12641
|
+
} else {
|
|
12642
|
+
list4.add(name);
|
|
12643
|
+
}
|
|
12644
|
+
}
|
|
12645
|
+
}
|
|
12646
|
+
}
|
|
12647
|
+
},
|
|
12795
12648
|
onApp(ctx) {
|
|
12796
12649
|
for (const [id, props] of Object.entries(ctx.appConfig.defaults.rpc ?? {})) {
|
|
12797
|
-
const group = new
|
|
12650
|
+
const group = new Node16(ctx.base, "rpc", id);
|
|
12798
12651
|
const name = formatGlobalResourceName({
|
|
12799
12652
|
appName: ctx.app.name,
|
|
12800
12653
|
resourceType: "rpc",
|
|
@@ -12803,7 +12656,8 @@ var rpcFeature = defineFeature({
|
|
|
12803
12656
|
const { lambda } = createPrebuildLambdaFunction(group, ctx, "rpc", id, {
|
|
12804
12657
|
bundleFile: join8(__dirname, "/prebuild/rpc/bundle.zip"),
|
|
12805
12658
|
bundleHash: join8(__dirname, "/prebuild/rpc/HASH"),
|
|
12806
|
-
memorySize: mebibytes2(256)
|
|
12659
|
+
memorySize: mebibytes2(256),
|
|
12660
|
+
warm: 3
|
|
12807
12661
|
});
|
|
12808
12662
|
const schema = {};
|
|
12809
12663
|
lambda.addEnvironment(
|
|
@@ -12816,40 +12670,49 @@ var rpcFeature = defineFeature({
|
|
|
12816
12670
|
);
|
|
12817
12671
|
ctx.shared.set(`rpc-${id}-schema`, schema);
|
|
12818
12672
|
if (props.auth) {
|
|
12819
|
-
const authGroup = new
|
|
12673
|
+
const authGroup = new Node16(group, "auth", "authorizer");
|
|
12820
12674
|
const auth2 = createLambdaFunction(authGroup, ctx, "rpc", `${id}-auth`, props.auth);
|
|
12821
12675
|
lambda.addEnvironment("AUTH", auth2.lambda.name);
|
|
12822
12676
|
}
|
|
12823
|
-
const permission = new
|
|
12677
|
+
const permission = new aws17.lambda.Permission(group, "permission", {
|
|
12824
12678
|
principal: "*",
|
|
12825
12679
|
action: "lambda:InvokeFunctionUrl",
|
|
12826
12680
|
functionArn: lambda.arn,
|
|
12827
12681
|
urlAuthType: "none"
|
|
12828
12682
|
});
|
|
12829
|
-
const url = new
|
|
12683
|
+
const url = new aws17.lambda.Url(group, "url-2", {
|
|
12830
12684
|
targetArn: lambda.arn,
|
|
12831
|
-
authType: "none"
|
|
12685
|
+
authType: "none",
|
|
12686
|
+
cors: {
|
|
12687
|
+
allow: {
|
|
12688
|
+
origins: ["*"],
|
|
12689
|
+
methods: ["*"],
|
|
12690
|
+
headers: ["Authentication", "Content-Type"]
|
|
12691
|
+
// credentials: true,
|
|
12692
|
+
}
|
|
12693
|
+
}
|
|
12832
12694
|
}).dependsOn(permission);
|
|
12833
12695
|
const domainName = props.domain ? formatFullDomainName(ctx.appConfig, props.domain, props.subDomain) : void 0;
|
|
12834
12696
|
const certificateArn = props.domain ? ctx.shared.get(`global-certificate-${props.domain}-arn`) : void 0;
|
|
12835
|
-
const cache = new
|
|
12697
|
+
const cache = new aws17.cloudFront.CachePolicy(group, "cache", {
|
|
12836
12698
|
name,
|
|
12837
12699
|
minTtl: seconds3(1),
|
|
12838
12700
|
maxTtl: days5(365),
|
|
12839
12701
|
defaultTtl: days5(1)
|
|
12840
12702
|
});
|
|
12841
|
-
const originRequest = new
|
|
12703
|
+
const originRequest = new aws17.cloudFront.OriginRequestPolicy(group, "request", {
|
|
12842
12704
|
name,
|
|
12843
12705
|
header: {
|
|
12844
12706
|
behavior: "all-except",
|
|
12845
|
-
values: ["
|
|
12707
|
+
values: ["Host"]
|
|
12846
12708
|
}
|
|
12847
12709
|
});
|
|
12848
|
-
const cdn = new
|
|
12710
|
+
const cdn = new aws17.cloudFront.Distribution(group, "cdn-2", {
|
|
12849
12711
|
name,
|
|
12850
12712
|
compress: true,
|
|
12851
12713
|
certificateArn,
|
|
12852
12714
|
viewerProtocol: "https-only",
|
|
12715
|
+
allowMethod: ["GET", "HEAD", "OPTIONS", "PUT", "PATCH", "POST", "DELETE"],
|
|
12853
12716
|
aliases: domainName ? [domainName] : void 0,
|
|
12854
12717
|
origins: [
|
|
12855
12718
|
{
|
|
@@ -12861,11 +12724,10 @@ var rpcFeature = defineFeature({
|
|
|
12861
12724
|
targetOriginId: "default",
|
|
12862
12725
|
cachePolicyId: cache.id,
|
|
12863
12726
|
originRequestPolicyId: originRequest.id
|
|
12864
|
-
// responseHeadersPolicyId: responseHeaders.id,
|
|
12865
12727
|
});
|
|
12866
12728
|
if (props.domain) {
|
|
12867
12729
|
const fullDomainName = formatFullDomainName(ctx.appConfig, props.domain, props.subDomain);
|
|
12868
|
-
new
|
|
12730
|
+
new aws17.route53.RecordSet(group, "record", {
|
|
12869
12731
|
hostedZoneId: ctx.shared.get(`hosted-zone-${props.domain}-id`),
|
|
12870
12732
|
type: "A",
|
|
12871
12733
|
name: fullDomainName,
|
|
@@ -12884,9 +12746,9 @@ var rpcFeature = defineFeature({
|
|
|
12884
12746
|
throw new FileError(ctx.stackConfig.file, `RPC definition is not defined on app level for "${id}"`);
|
|
12885
12747
|
}
|
|
12886
12748
|
const schema = ctx.shared.get(`rpc-${id}-schema`);
|
|
12887
|
-
const group = new
|
|
12749
|
+
const group = new Node16(ctx.stack, "rpc", id);
|
|
12888
12750
|
for (const [name, props] of Object.entries(queries ?? {})) {
|
|
12889
|
-
const queryGroup = new
|
|
12751
|
+
const queryGroup = new Node16(group, "query", name);
|
|
12890
12752
|
const entryId = paramCase6(`${id}-${shortId(name)}`);
|
|
12891
12753
|
const lambda = createLambdaFunction(queryGroup, ctx, `rpc`, entryId, {
|
|
12892
12754
|
...props,
|
|
@@ -12899,7 +12761,7 @@ var rpcFeature = defineFeature({
|
|
|
12899
12761
|
});
|
|
12900
12762
|
|
|
12901
12763
|
// src/feature/search/index.ts
|
|
12902
|
-
import { aws as
|
|
12764
|
+
import { aws as aws18, Node as Node17 } from "@awsless/formation";
|
|
12903
12765
|
import { constantCase as constantCase10 } from "change-case";
|
|
12904
12766
|
var typeGenCode4 = `
|
|
12905
12767
|
import { AnyStruct, Table } from '@awsless/open-search'
|
|
@@ -12927,9 +12789,9 @@ var searchFeature = defineFeature({
|
|
|
12927
12789
|
},
|
|
12928
12790
|
onStack(ctx) {
|
|
12929
12791
|
for (const [id, props] of Object.entries(ctx.stackConfig.searchs ?? {})) {
|
|
12930
|
-
const group = new
|
|
12792
|
+
const group = new Node17(ctx.stack, "search", id);
|
|
12931
12793
|
const name = `${id}-${shortId([ctx.app.name, ctx.stack.name, this.name, id].join("--"))}`;
|
|
12932
|
-
const openSearch = new
|
|
12794
|
+
const openSearch = new aws18.openSearch.Domain(group, "domain", {
|
|
12933
12795
|
name,
|
|
12934
12796
|
version: props.version,
|
|
12935
12797
|
storageSize: props.storage,
|
|
@@ -12969,7 +12831,7 @@ var searchFeature = defineFeature({
|
|
|
12969
12831
|
|
|
12970
12832
|
// src/feature/site/index.ts
|
|
12971
12833
|
import { days as days6, seconds as seconds4 } from "@awsless/duration";
|
|
12972
|
-
import { Asset as Asset5, aws as
|
|
12834
|
+
import { Asset as Asset5, aws as aws19, Node as Node18 } from "@awsless/formation";
|
|
12973
12835
|
import { glob as glob2 } from "glob";
|
|
12974
12836
|
import { join as join9 } from "path";
|
|
12975
12837
|
|
|
@@ -12999,7 +12861,7 @@ var siteFeature = defineFeature({
|
|
|
12999
12861
|
name: "site",
|
|
13000
12862
|
onStack(ctx) {
|
|
13001
12863
|
for (const [id, props] of Object.entries(ctx.stackConfig.sites ?? {})) {
|
|
13002
|
-
const group = new
|
|
12864
|
+
const group = new Node18(ctx.stack, "site", id);
|
|
13003
12865
|
const name = formatLocalResourceName({
|
|
13004
12866
|
appName: ctx.app.name,
|
|
13005
12867
|
stackName: ctx.stack.name,
|
|
@@ -13018,7 +12880,7 @@ var siteFeature = defineFeature({
|
|
|
13018
12880
|
ctx.onBind((name2, value) => {
|
|
13019
12881
|
lambda.addEnvironment(name2, value);
|
|
13020
12882
|
});
|
|
13021
|
-
new
|
|
12883
|
+
new aws19.lambda.Permission(group, "permission", {
|
|
13022
12884
|
principal: "*",
|
|
13023
12885
|
// principal: 'cloudfront.amazonaws.com',
|
|
13024
12886
|
action: "lambda:InvokeFunctionUrl",
|
|
@@ -13027,7 +12889,7 @@ var siteFeature = defineFeature({
|
|
|
13027
12889
|
// urlAuthType: 'aws-iam',
|
|
13028
12890
|
// sourceArn: distribution.arn,
|
|
13029
12891
|
});
|
|
13030
|
-
const url = new
|
|
12892
|
+
const url = new aws19.lambda.Url(group, "url", {
|
|
13031
12893
|
targetArn: lambda.arn,
|
|
13032
12894
|
authType: "none"
|
|
13033
12895
|
// authType: 'aws-iam',
|
|
@@ -13039,7 +12901,7 @@ var siteFeature = defineFeature({
|
|
|
13039
12901
|
});
|
|
13040
12902
|
}
|
|
13041
12903
|
if (props.static) {
|
|
13042
|
-
bucket = new
|
|
12904
|
+
bucket = new aws19.s3.Bucket(group, "bucket", {
|
|
13043
12905
|
name: formatLocalResourceName({
|
|
13044
12906
|
appName: ctx.app.name,
|
|
13045
12907
|
stackName: ctx.stack.name,
|
|
@@ -13065,7 +12927,7 @@ var siteFeature = defineFeature({
|
|
|
13065
12927
|
policy.addStatement(bucket.permissions);
|
|
13066
12928
|
});
|
|
13067
12929
|
bucket.deletionPolicy = "after-deployment";
|
|
13068
|
-
const accessControl = new
|
|
12930
|
+
const accessControl = new aws19.cloudFront.OriginAccessControl(group, `access`, {
|
|
13069
12931
|
name,
|
|
13070
12932
|
type: "s3",
|
|
13071
12933
|
behavior: "always",
|
|
@@ -13077,7 +12939,7 @@ var siteFeature = defineFeature({
|
|
|
13077
12939
|
nodir: true
|
|
13078
12940
|
});
|
|
13079
12941
|
for (const file of files) {
|
|
13080
|
-
const object = new
|
|
12942
|
+
const object = new aws19.s3.BucketObject(group, file, {
|
|
13081
12943
|
bucket: bucket.name,
|
|
13082
12944
|
key: file,
|
|
13083
12945
|
body: Asset5.fromFile(join9(props.static, file)),
|
|
@@ -13100,21 +12962,21 @@ var siteFeature = defineFeature({
|
|
|
13100
12962
|
statusCodes: [403, 404]
|
|
13101
12963
|
});
|
|
13102
12964
|
}
|
|
13103
|
-
const cache = new
|
|
12965
|
+
const cache = new aws19.cloudFront.CachePolicy(group, "cache", {
|
|
13104
12966
|
name,
|
|
13105
12967
|
minTtl: seconds4(1),
|
|
13106
12968
|
maxTtl: days6(365),
|
|
13107
12969
|
defaultTtl: days6(1),
|
|
13108
12970
|
...props.cache
|
|
13109
12971
|
});
|
|
13110
|
-
const originRequest = new
|
|
12972
|
+
const originRequest = new aws19.cloudFront.OriginRequestPolicy(group, "request", {
|
|
13111
12973
|
name,
|
|
13112
12974
|
header: {
|
|
13113
12975
|
behavior: "all-except",
|
|
13114
12976
|
values: ["host", "authorization"]
|
|
13115
12977
|
}
|
|
13116
12978
|
});
|
|
13117
|
-
const responseHeaders = new
|
|
12979
|
+
const responseHeaders = new aws19.cloudFront.ResponseHeadersPolicy(group, "response", {
|
|
13118
12980
|
name,
|
|
13119
12981
|
cors: props.cors,
|
|
13120
12982
|
remove: ["server"]
|
|
@@ -13124,7 +12986,7 @@ var siteFeature = defineFeature({
|
|
|
13124
12986
|
});
|
|
13125
12987
|
const domainName = props.domain ? formatFullDomainName(ctx.appConfig, props.domain, props.subDomain) : void 0;
|
|
13126
12988
|
const certificateArn = props.domain ? ctx.shared.get(`global-certificate-${props.domain}-arn`) : void 0;
|
|
13127
|
-
const distribution = new
|
|
12989
|
+
const distribution = new aws19.cloudFront.Distribution(group, "distribution", {
|
|
13128
12990
|
name,
|
|
13129
12991
|
compress: true,
|
|
13130
12992
|
certificateArn,
|
|
@@ -13152,13 +13014,13 @@ var siteFeature = defineFeature({
|
|
|
13152
13014
|
};
|
|
13153
13015
|
})
|
|
13154
13016
|
});
|
|
13155
|
-
new
|
|
13017
|
+
new aws19.cloudFront.InvalidateCache(group, "invalidate", {
|
|
13156
13018
|
distributionId: distribution.id,
|
|
13157
13019
|
paths: ["/*"],
|
|
13158
13020
|
versions
|
|
13159
13021
|
});
|
|
13160
13022
|
if (props.static) {
|
|
13161
|
-
new
|
|
13023
|
+
new aws19.s3.BucketPolicy(group, `policy`, {
|
|
13162
13024
|
bucketName: bucket.name,
|
|
13163
13025
|
statements: [
|
|
13164
13026
|
{
|
|
@@ -13185,7 +13047,7 @@ var siteFeature = defineFeature({
|
|
|
13185
13047
|
});
|
|
13186
13048
|
}
|
|
13187
13049
|
if (domainName) {
|
|
13188
|
-
new
|
|
13050
|
+
new aws19.route53.RecordSet(group, `record`, {
|
|
13189
13051
|
hostedZoneId: ctx.shared.get(`hosted-zone-${props.domain}-id`),
|
|
13190
13052
|
type: "A",
|
|
13191
13053
|
name: domainName,
|
|
@@ -13201,7 +13063,7 @@ var siteFeature = defineFeature({
|
|
|
13201
13063
|
});
|
|
13202
13064
|
|
|
13203
13065
|
// src/feature/store/index.ts
|
|
13204
|
-
import { aws as
|
|
13066
|
+
import { aws as aws20, Node as Node19 } from "@awsless/formation";
|
|
13205
13067
|
import { paramCase as paramCase7 } from "change-case";
|
|
13206
13068
|
var typeGenCode5 = `
|
|
13207
13069
|
import { Body, PutObjectProps, BodyStream } from '@awsless/s3'
|
|
@@ -13238,7 +13100,7 @@ var storeFeature = defineFeature({
|
|
|
13238
13100
|
},
|
|
13239
13101
|
onStack(ctx) {
|
|
13240
13102
|
for (const [id, props] of Object.entries(ctx.stackConfig.stores ?? {})) {
|
|
13241
|
-
const group = new
|
|
13103
|
+
const group = new Node19(ctx.stack, "store", id);
|
|
13242
13104
|
const name = formatLocalResourceName({
|
|
13243
13105
|
appName: ctx.app.name,
|
|
13244
13106
|
stackName: ctx.stack.name,
|
|
@@ -13258,13 +13120,13 @@ var storeFeature = defineFeature({
|
|
|
13258
13120
|
"removed:marker": "s3:ObjectRemoved:DeleteMarkerCreated"
|
|
13259
13121
|
};
|
|
13260
13122
|
for (const [event, funcProps] of Object.entries(props.events ?? {})) {
|
|
13261
|
-
const eventGroup = new
|
|
13123
|
+
const eventGroup = new Node19(group, "event", event);
|
|
13262
13124
|
const eventId = paramCase7(`${id}-${shortId(event)}`);
|
|
13263
13125
|
const { lambda } = createAsyncLambdaFunction(eventGroup, ctx, `store`, eventId, {
|
|
13264
13126
|
...funcProps,
|
|
13265
13127
|
description: `${id} event "${event}"`
|
|
13266
13128
|
});
|
|
13267
|
-
new
|
|
13129
|
+
new aws20.lambda.Permission(eventGroup, "permission", {
|
|
13268
13130
|
action: "lambda:InvokeFunction",
|
|
13269
13131
|
principal: "s3.amazonaws.com",
|
|
13270
13132
|
functionArn: lambda.arn,
|
|
@@ -13275,7 +13137,7 @@ var storeFeature = defineFeature({
|
|
|
13275
13137
|
function: lambda.arn
|
|
13276
13138
|
});
|
|
13277
13139
|
}
|
|
13278
|
-
const bucket = new
|
|
13140
|
+
const bucket = new aws20.s3.Bucket(group, "store", {
|
|
13279
13141
|
name,
|
|
13280
13142
|
versioning: props.versioning,
|
|
13281
13143
|
forceDelete: true,
|
|
@@ -13303,24 +13165,24 @@ var storeFeature = defineFeature({
|
|
|
13303
13165
|
});
|
|
13304
13166
|
|
|
13305
13167
|
// src/feature/stream/index.ts
|
|
13306
|
-
import { aws as
|
|
13168
|
+
import { aws as aws21, Node as Node20 } from "@awsless/formation";
|
|
13307
13169
|
import { constantCase as constantCase12 } from "change-case";
|
|
13308
13170
|
var streamFeature = defineFeature({
|
|
13309
13171
|
name: "stream",
|
|
13310
13172
|
onStack(ctx) {
|
|
13311
13173
|
for (const [id, props] of Object.entries(ctx.stackConfig.streams ?? {})) {
|
|
13312
|
-
const group = new
|
|
13174
|
+
const group = new Node20(ctx.stack, "stream", id);
|
|
13313
13175
|
const name = formatLocalResourceName({
|
|
13314
13176
|
appName: ctx.app.name,
|
|
13315
13177
|
stackName: ctx.stack.name,
|
|
13316
13178
|
resourceType: "stream",
|
|
13317
13179
|
resourceName: id
|
|
13318
13180
|
});
|
|
13319
|
-
const channel = new
|
|
13181
|
+
const channel = new aws21.ivs.Channel(group, "channel", {
|
|
13320
13182
|
name,
|
|
13321
13183
|
...props
|
|
13322
13184
|
});
|
|
13323
|
-
const streamKey = new
|
|
13185
|
+
const streamKey = new aws21.ivs.StreamKey(group, "key", {
|
|
13324
13186
|
channel: channel.arn
|
|
13325
13187
|
});
|
|
13326
13188
|
const prefix = `STREAM_${constantCase12(ctx.stack.name)}_${constantCase12(id)}`;
|
|
@@ -13332,7 +13194,7 @@ var streamFeature = defineFeature({
|
|
|
13332
13194
|
});
|
|
13333
13195
|
|
|
13334
13196
|
// src/feature/table/index.ts
|
|
13335
|
-
import { aws as
|
|
13197
|
+
import { aws as aws22, Node as Node21 } from "@awsless/formation";
|
|
13336
13198
|
var tableFeature = defineFeature({
|
|
13337
13199
|
name: "table",
|
|
13338
13200
|
async onTypeGen(ctx) {
|
|
@@ -13356,7 +13218,7 @@ var tableFeature = defineFeature({
|
|
|
13356
13218
|
},
|
|
13357
13219
|
onStack(ctx) {
|
|
13358
13220
|
for (const [id, props] of Object.entries(ctx.stackConfig.tables ?? {})) {
|
|
13359
|
-
const group = new
|
|
13221
|
+
const group = new Node21(ctx.stack, "table", id);
|
|
13360
13222
|
const name = formatLocalResourceName({
|
|
13361
13223
|
appName: ctx.app.name,
|
|
13362
13224
|
stackName: ctx.stack.name,
|
|
@@ -13364,7 +13226,7 @@ var tableFeature = defineFeature({
|
|
|
13364
13226
|
resourceName: id
|
|
13365
13227
|
});
|
|
13366
13228
|
const deletionProtection = props.deletionProtection ?? ctx.appConfig.defaults.table?.deletionProtection;
|
|
13367
|
-
const table2 = new
|
|
13229
|
+
const table2 = new aws22.dynamodb.Table(group, "table", {
|
|
13368
13230
|
...props,
|
|
13369
13231
|
name,
|
|
13370
13232
|
stream: props.stream?.type,
|
|
@@ -13377,7 +13239,7 @@ var tableFeature = defineFeature({
|
|
|
13377
13239
|
const { lambda, policy } = createLambdaFunction(group, ctx, "table", id, props.stream.consumer);
|
|
13378
13240
|
lambda.addEnvironment("LOG_VIEWABLE_ERROR", "1");
|
|
13379
13241
|
const onFailure = getGlobalOnFailure(ctx);
|
|
13380
|
-
const source = new
|
|
13242
|
+
const source = new aws22.lambda.EventSourceMapping(group, id, {
|
|
13381
13243
|
functionArn: lambda.arn,
|
|
13382
13244
|
sourceArn: table2.streamArn,
|
|
13383
13245
|
batchSize: 100,
|
|
@@ -13404,7 +13266,7 @@ var tableFeature = defineFeature({
|
|
|
13404
13266
|
});
|
|
13405
13267
|
|
|
13406
13268
|
// src/feature/task/index.ts
|
|
13407
|
-
import { Node as
|
|
13269
|
+
import { Node as Node22 } from "@awsless/formation";
|
|
13408
13270
|
import { camelCase as camelCase7 } from "change-case";
|
|
13409
13271
|
import { relative as relative6 } from "path";
|
|
13410
13272
|
var typeGenCode6 = `
|
|
@@ -13466,7 +13328,7 @@ var taskFeature = defineFeature({
|
|
|
13466
13328
|
},
|
|
13467
13329
|
onStack(ctx) {
|
|
13468
13330
|
for (const [id, props] of Object.entries(ctx.stackConfig.tasks ?? {})) {
|
|
13469
|
-
const group = new
|
|
13331
|
+
const group = new Node22(ctx.stack, "task", id);
|
|
13470
13332
|
createAsyncLambdaFunction(group, ctx, "task", id, props.consumer);
|
|
13471
13333
|
}
|
|
13472
13334
|
}
|
|
@@ -13483,7 +13345,7 @@ var testFeature = defineFeature({
|
|
|
13483
13345
|
});
|
|
13484
13346
|
|
|
13485
13347
|
// src/feature/topic/index.ts
|
|
13486
|
-
import { aws as
|
|
13348
|
+
import { aws as aws23, Node as Node23 } from "@awsless/formation";
|
|
13487
13349
|
var typeGenCode7 = `
|
|
13488
13350
|
import type { PublishOptions } from '@awsless/sns'
|
|
13489
13351
|
import type { Mock } from 'vitest'
|
|
@@ -13524,154 +13386,436 @@ var topicFeature = defineFeature({
|
|
|
13524
13386
|
onApp(ctx) {
|
|
13525
13387
|
for (const stack of ctx.stackConfigs) {
|
|
13526
13388
|
for (const id of stack.topics ?? []) {
|
|
13527
|
-
const group = new
|
|
13389
|
+
const group = new Node23(ctx.base, "topic", id);
|
|
13528
13390
|
const name = formatGlobalResourceName({
|
|
13529
13391
|
appName: ctx.appConfig.name,
|
|
13530
13392
|
resourceType: "topic",
|
|
13531
13393
|
resourceName: id
|
|
13532
13394
|
});
|
|
13533
|
-
const topic = new
|
|
13395
|
+
const topic = new aws23.sns.Topic(group, "topic", {
|
|
13534
13396
|
name
|
|
13535
13397
|
});
|
|
13536
13398
|
ctx.shared.set(`topic-${id}-arn`, topic.arn);
|
|
13537
13399
|
}
|
|
13538
|
-
}
|
|
13539
|
-
},
|
|
13540
|
-
onStack(ctx) {
|
|
13541
|
-
for (const id of ctx.stackConfig.topics ?? []) {
|
|
13542
|
-
ctx.onPolicy((policy) => {
|
|
13543
|
-
policy.addStatement({
|
|
13544
|
-
actions: ["sns:Publish"],
|
|
13545
|
-
resources: [ctx.shared.get(`topic-${id}-arn`)]
|
|
13546
|
-
});
|
|
13547
|
-
});
|
|
13548
|
-
}
|
|
13549
|
-
for (const [id, props] of Object.entries(ctx.stackConfig.subscribers ?? {})) {
|
|
13550
|
-
const group = new
|
|
13551
|
-
const topicArn = ctx.shared.get(`topic-${id}-arn`);
|
|
13552
|
-
if (typeof props === "string" && isEmail(props)) {
|
|
13553
|
-
new
|
|
13554
|
-
topicArn,
|
|
13555
|
-
protocol: "email",
|
|
13556
|
-
endpoint: props
|
|
13557
|
-
});
|
|
13558
|
-
} else if (typeof props === "object") {
|
|
13559
|
-
const { lambda } = createAsyncLambdaFunction(group, ctx, `topic`, id, props);
|
|
13560
|
-
new
|
|
13561
|
-
topicArn,
|
|
13562
|
-
protocol: "lambda",
|
|
13563
|
-
endpoint: lambda.arn
|
|
13564
|
-
});
|
|
13565
|
-
new
|
|
13566
|
-
action: "lambda:InvokeFunction",
|
|
13567
|
-
principal: "sns.amazonaws.com",
|
|
13568
|
-
functionArn: lambda.arn,
|
|
13569
|
-
sourceArn: topicArn
|
|
13570
|
-
});
|
|
13400
|
+
}
|
|
13401
|
+
},
|
|
13402
|
+
onStack(ctx) {
|
|
13403
|
+
for (const id of ctx.stackConfig.topics ?? []) {
|
|
13404
|
+
ctx.onPolicy((policy) => {
|
|
13405
|
+
policy.addStatement({
|
|
13406
|
+
actions: ["sns:Publish"],
|
|
13407
|
+
resources: [ctx.shared.get(`topic-${id}-arn`)]
|
|
13408
|
+
});
|
|
13409
|
+
});
|
|
13410
|
+
}
|
|
13411
|
+
for (const [id, props] of Object.entries(ctx.stackConfig.subscribers ?? {})) {
|
|
13412
|
+
const group = new Node23(ctx.stack, "topic", id);
|
|
13413
|
+
const topicArn = ctx.shared.get(`topic-${id}-arn`);
|
|
13414
|
+
if (typeof props === "string" && isEmail(props)) {
|
|
13415
|
+
new aws23.sns.Subscription(group, id, {
|
|
13416
|
+
topicArn,
|
|
13417
|
+
protocol: "email",
|
|
13418
|
+
endpoint: props
|
|
13419
|
+
});
|
|
13420
|
+
} else if (typeof props === "object") {
|
|
13421
|
+
const { lambda } = createAsyncLambdaFunction(group, ctx, `topic`, id, props);
|
|
13422
|
+
new aws23.sns.Subscription(group, id, {
|
|
13423
|
+
topicArn,
|
|
13424
|
+
protocol: "lambda",
|
|
13425
|
+
endpoint: lambda.arn
|
|
13426
|
+
});
|
|
13427
|
+
new aws23.lambda.Permission(group, id, {
|
|
13428
|
+
action: "lambda:InvokeFunction",
|
|
13429
|
+
principal: "sns.amazonaws.com",
|
|
13430
|
+
functionArn: lambda.arn,
|
|
13431
|
+
sourceArn: topicArn
|
|
13432
|
+
});
|
|
13433
|
+
}
|
|
13434
|
+
}
|
|
13435
|
+
}
|
|
13436
|
+
});
|
|
13437
|
+
|
|
13438
|
+
// src/feature/vpc/index.ts
|
|
13439
|
+
import { aws as aws24, combine as combine2, Node as Node24 } from "@awsless/formation";
|
|
13440
|
+
var vpcFeature = defineFeature({
|
|
13441
|
+
name: "vpc",
|
|
13442
|
+
onApp(ctx) {
|
|
13443
|
+
const group = new Node24(ctx.base, "vpc", "main");
|
|
13444
|
+
const vpc = new aws24.ec2.Vpc(group, "vpc", {
|
|
13445
|
+
name: ctx.app.name,
|
|
13446
|
+
cidrBlock: aws24.ec2.Peer.ipv4("10.0.0.0/16")
|
|
13447
|
+
// cidrBlock: aws.ec2.Peer.ipv6('fd00:10:20::/48'),
|
|
13448
|
+
// cidrBlock: aws.ec2.Peer.ipv6('2a05:d018:c69:6600::/56'),
|
|
13449
|
+
// enableDnsSupport: true,
|
|
13450
|
+
// enableDnsHostnames: true,
|
|
13451
|
+
});
|
|
13452
|
+
const privateRouteTable = new aws24.ec2.RouteTable(group, "private", {
|
|
13453
|
+
vpcId: vpc.id,
|
|
13454
|
+
name: "private"
|
|
13455
|
+
});
|
|
13456
|
+
const publicRouteTable = new aws24.ec2.RouteTable(group, "public", {
|
|
13457
|
+
vpcId: vpc.id,
|
|
13458
|
+
name: "public"
|
|
13459
|
+
});
|
|
13460
|
+
const gateway = new aws24.ec2.InternetGateway(group, "gateway");
|
|
13461
|
+
const attachment = new aws24.ec2.VPCGatewayAttachment(group, "attachment", {
|
|
13462
|
+
vpcId: vpc.id,
|
|
13463
|
+
internetGatewayId: gateway.id
|
|
13464
|
+
});
|
|
13465
|
+
new aws24.ec2.Route(group, "route", {
|
|
13466
|
+
gatewayId: gateway.id,
|
|
13467
|
+
routeTableId: publicRouteTable.id,
|
|
13468
|
+
destination: aws24.ec2.Peer.anyIpv4()
|
|
13469
|
+
// destination: aws.ec2.Peer.anyIpv6(),
|
|
13470
|
+
});
|
|
13471
|
+
ctx.shared.set(
|
|
13472
|
+
"vpc-id",
|
|
13473
|
+
// Some resources require the internet gateway to be attached.
|
|
13474
|
+
combine2([vpc.id, attachment.internetGatewayId]).apply(([id]) => id)
|
|
13475
|
+
);
|
|
13476
|
+
ctx.shared.set("vpc-security-group-id", vpc.defaultSecurityGroup);
|
|
13477
|
+
const zones = ["a", "b"];
|
|
13478
|
+
const tables = [privateRouteTable, publicRouteTable];
|
|
13479
|
+
let block = 0n;
|
|
13480
|
+
for (const table2 of tables) {
|
|
13481
|
+
for (const i in zones) {
|
|
13482
|
+
const index = Number(i) + 1;
|
|
13483
|
+
const id = `${table2.identifier}-${index}`;
|
|
13484
|
+
const subnet = new aws24.ec2.Subnet(group, id, {
|
|
13485
|
+
name: `${ctx.app.name}--${table2.identifier}-${index}`,
|
|
13486
|
+
vpcId: vpc.id,
|
|
13487
|
+
cidrBlock: aws24.ec2.Peer.ipv4(`10.0.${block++}.0/24`),
|
|
13488
|
+
// ipv6CidrBlock: aws.ec2.Peer.ipv6(`fd00:10:20:${++block}::/64`),
|
|
13489
|
+
// ipv6CidrBlock: aws.ec2.Peer.ipv6(`2a05:d018:c69:660${++block}::/64`),
|
|
13490
|
+
// ipv6CidrBlock: ipv6CidrBlock.ipv6CidrBlock.apply(ip => ),
|
|
13491
|
+
// ipv6CidrBlock: slices.apply(list => aws.ec2.Peer.ipv6(list.get(block++).toString())),
|
|
13492
|
+
// assignIpv6AddressOnCreation: true,
|
|
13493
|
+
// ipv6Native: true,
|
|
13494
|
+
mapPublicIpOnLaunch: table2.identifier === "public",
|
|
13495
|
+
availabilityZone: ctx.appConfig.region + zones[i]
|
|
13496
|
+
});
|
|
13497
|
+
new aws24.ec2.SubnetRouteTableAssociation(group, id, {
|
|
13498
|
+
routeTableId: table2.id,
|
|
13499
|
+
subnetId: subnet.id
|
|
13500
|
+
});
|
|
13501
|
+
ctx.shared.set(`vpc-${table2.identifier}-subnet-id-${index}`, subnet.id);
|
|
13502
|
+
}
|
|
13503
|
+
}
|
|
13504
|
+
}
|
|
13505
|
+
});
|
|
13506
|
+
|
|
13507
|
+
// src/feature/index.ts
|
|
13508
|
+
var features = [
|
|
13509
|
+
// 1
|
|
13510
|
+
vpcFeature,
|
|
13511
|
+
domainFeature,
|
|
13512
|
+
commandFeature,
|
|
13513
|
+
onFailureFeature,
|
|
13514
|
+
// 2
|
|
13515
|
+
authFeature,
|
|
13516
|
+
// 3
|
|
13517
|
+
functionFeature,
|
|
13518
|
+
instanceFeature,
|
|
13519
|
+
graphqlFeature,
|
|
13520
|
+
configFeature,
|
|
13521
|
+
searchFeature,
|
|
13522
|
+
pubsubFeature,
|
|
13523
|
+
streamFeature,
|
|
13524
|
+
tableFeature,
|
|
13525
|
+
topicFeature,
|
|
13526
|
+
queueFeature,
|
|
13527
|
+
storeFeature,
|
|
13528
|
+
cacheFeature,
|
|
13529
|
+
taskFeature,
|
|
13530
|
+
testFeature,
|
|
13531
|
+
cronFeature,
|
|
13532
|
+
httpFeature,
|
|
13533
|
+
restFeature,
|
|
13534
|
+
siteFeature,
|
|
13535
|
+
// 4
|
|
13536
|
+
logSubscriptionFeature,
|
|
13537
|
+
// I think needs to be after s3 feature
|
|
13538
|
+
rpcFeature
|
|
13539
|
+
];
|
|
13540
|
+
|
|
13541
|
+
// src/feature/validate.ts
|
|
13542
|
+
var validateFeatures = (props) => {
|
|
13543
|
+
for (const feature of features) {
|
|
13544
|
+
feature.onValidate?.(props);
|
|
13545
|
+
}
|
|
13546
|
+
};
|
|
13547
|
+
|
|
13548
|
+
// src/cli/ui/app.ts
|
|
13549
|
+
import { note } from "@clack/prompts";
|
|
13550
|
+
var logApp = (app, opt) => {
|
|
13551
|
+
const data = {
|
|
13552
|
+
App: app.name,
|
|
13553
|
+
Region: app.region,
|
|
13554
|
+
Profile: app.profile
|
|
13555
|
+
};
|
|
13556
|
+
if (opt.stage) {
|
|
13557
|
+
data.Stage = color.warning(opt.stage);
|
|
13558
|
+
}
|
|
13559
|
+
note(wrap(list(data)), "App Config");
|
|
13560
|
+
};
|
|
13561
|
+
|
|
13562
|
+
// src/cli/ui/error/error.ts
|
|
13563
|
+
import { AppError as AppError2, StackError as StackError3 } from "@awsless/formation";
|
|
13564
|
+
import { log as log6 } from "@clack/prompts";
|
|
13565
|
+
|
|
13566
|
+
// src/cli/ui/error/app-error.ts
|
|
13567
|
+
import { StackError as StackError2 } from "@awsless/formation";
|
|
13568
|
+
import { log as log3 } from "@clack/prompts";
|
|
13569
|
+
|
|
13570
|
+
// src/cli/ui/error/stack-error.ts
|
|
13571
|
+
import { ResourceError } from "@awsless/formation";
|
|
13572
|
+
import { log as log2 } from "@clack/prompts";
|
|
13573
|
+
import { capitalCase as capitalCase2 } from "change-case";
|
|
13574
|
+
var formatOperation = (operation) => {
|
|
13575
|
+
const value = ` ${capitalCase2(operation)} `;
|
|
13576
|
+
switch (operation) {
|
|
13577
|
+
case "create":
|
|
13578
|
+
return color.success.bold.inverse(value);
|
|
13579
|
+
case "update":
|
|
13580
|
+
return color.warning.bold.inverse(value);
|
|
13581
|
+
case "delete":
|
|
13582
|
+
return color.error.bold.inverse(value);
|
|
13583
|
+
case "heal":
|
|
13584
|
+
return color.warning.bold.inverse(value);
|
|
13585
|
+
case "get":
|
|
13586
|
+
return color.info.bold.inverse(value);
|
|
13587
|
+
}
|
|
13588
|
+
};
|
|
13589
|
+
var logStackError = (error) => {
|
|
13590
|
+
log2.message(
|
|
13591
|
+
wrap([color.error(error.message), `Stack: ${error.stack}`].join("\n"), {
|
|
13592
|
+
hard: true
|
|
13593
|
+
}),
|
|
13594
|
+
{ symbol: color.error(icon.error) }
|
|
13595
|
+
);
|
|
13596
|
+
for (const issue of error.issues) {
|
|
13597
|
+
if (issue instanceof ResourceError) {
|
|
13598
|
+
log2.message(
|
|
13599
|
+
[
|
|
13600
|
+
formatOperation(issue.operation),
|
|
13601
|
+
"\n",
|
|
13602
|
+
wrap("URN: " + issue.urn, { hard: true }),
|
|
13603
|
+
"\n",
|
|
13604
|
+
wrap("ID: " + issue.id, { hard: true }),
|
|
13605
|
+
"\n\n",
|
|
13606
|
+
wrap(color.error(issue.message), { hard: true })
|
|
13607
|
+
// , '\n', color.error(issue.message)
|
|
13608
|
+
].join(""),
|
|
13609
|
+
{ symbol: color.error(icon.error) }
|
|
13610
|
+
);
|
|
13611
|
+
} else if (issue instanceof Error) {
|
|
13612
|
+
log2.message(wrap(color.error(issue.message), { hard: true }), {
|
|
13613
|
+
symbol: color.error(icon.error)
|
|
13614
|
+
});
|
|
13615
|
+
}
|
|
13616
|
+
}
|
|
13617
|
+
};
|
|
13618
|
+
|
|
13619
|
+
// src/cli/ui/error/app-error.ts
|
|
13620
|
+
var logAppError = (error) => {
|
|
13621
|
+
log3.message(
|
|
13622
|
+
wrap([color.error(error.message), `App: ${error.app}`].join("\n"), {
|
|
13623
|
+
hard: true
|
|
13624
|
+
}),
|
|
13625
|
+
{ symbol: color.error(icon.error) }
|
|
13626
|
+
);
|
|
13627
|
+
for (const issue of error.issues) {
|
|
13628
|
+
if (issue instanceof StackError2) {
|
|
13629
|
+
logStackError(issue);
|
|
13630
|
+
} else if (issue instanceof Error) {
|
|
13631
|
+
log3.message(wrap(color.error(issue.message), { hard: true }), {
|
|
13632
|
+
symbol: color.error(icon.error)
|
|
13633
|
+
});
|
|
13634
|
+
}
|
|
13635
|
+
}
|
|
13636
|
+
};
|
|
13637
|
+
|
|
13638
|
+
// src/cli/ui/error/config-error.ts
|
|
13639
|
+
import * as p from "@clack/prompts";
|
|
13640
|
+
var codeLine = (value, level = 0) => {
|
|
13641
|
+
return [
|
|
13642
|
+
//
|
|
13643
|
+
" ".repeat(level),
|
|
13644
|
+
value
|
|
13645
|
+
].join("");
|
|
13646
|
+
};
|
|
13647
|
+
var format = (value) => {
|
|
13648
|
+
if (Array.isArray(value)) {
|
|
13649
|
+
return "[ ... ]";
|
|
13650
|
+
}
|
|
13651
|
+
if (value === null) {
|
|
13652
|
+
return "null";
|
|
13653
|
+
}
|
|
13654
|
+
switch (typeof value) {
|
|
13655
|
+
case "function":
|
|
13656
|
+
return "() => { ... }";
|
|
13657
|
+
case "bigint":
|
|
13658
|
+
return `${value}n`;
|
|
13659
|
+
case "symbol":
|
|
13660
|
+
return "Symbol()";
|
|
13661
|
+
case "object":
|
|
13662
|
+
return "{ ... }";
|
|
13663
|
+
case "undefined":
|
|
13664
|
+
return "undefined";
|
|
13665
|
+
case "string":
|
|
13666
|
+
case "number":
|
|
13667
|
+
case "boolean":
|
|
13668
|
+
return JSON.stringify(value);
|
|
13669
|
+
}
|
|
13670
|
+
return "";
|
|
13671
|
+
};
|
|
13672
|
+
var logConfigError = (error) => {
|
|
13673
|
+
for (const issue of error.error.errors) {
|
|
13674
|
+
const message = [color.error(issue.message), color.dim(error.file), "\n{"];
|
|
13675
|
+
let context = error.data;
|
|
13676
|
+
const inStack = issue.path[0] === "stacks" && typeof issue.path[1] === "number";
|
|
13677
|
+
const length = issue.path.length;
|
|
13678
|
+
const end = ["}"];
|
|
13679
|
+
issue.path.forEach((path, i) => {
|
|
13680
|
+
const index = i + 1;
|
|
13681
|
+
context = context[path];
|
|
13682
|
+
if (typeof path === "string") {
|
|
13683
|
+
const key = path + `: `;
|
|
13684
|
+
if (index === length) {
|
|
13685
|
+
const space = " ".repeat(key.length);
|
|
13686
|
+
const value = format(context);
|
|
13687
|
+
const error2 = icon.arrow.top.repeat(value.length);
|
|
13688
|
+
message.push(codeLine(key + color.warning(value), index));
|
|
13689
|
+
message.push(codeLine(space + color.error(error2), index));
|
|
13690
|
+
} else if (Array.isArray(context)) {
|
|
13691
|
+
message.push(codeLine(key + "[", index));
|
|
13692
|
+
end.unshift(codeLine("]", index));
|
|
13693
|
+
} else if (typeof context === "object") {
|
|
13694
|
+
if (inStack && index === 3) {
|
|
13695
|
+
const name = error.data.stacks[issue.path[1]].name;
|
|
13696
|
+
message.push(codeLine("name: " + color.info(`"${name}"`) + ",", index));
|
|
13697
|
+
}
|
|
13698
|
+
message.push(codeLine(key + "{", index));
|
|
13699
|
+
end.unshift(codeLine("}", index));
|
|
13700
|
+
}
|
|
13701
|
+
} else if (typeof context === "object") {
|
|
13702
|
+
message.push(codeLine("{", index));
|
|
13703
|
+
end.unshift(codeLine("}", index));
|
|
13704
|
+
} else if (typeof context === "string") {
|
|
13705
|
+
message.push(codeLine(color.warning(`"${context}"`), index));
|
|
13706
|
+
const error2 = icon.arrow.top.repeat(context.length + 2);
|
|
13707
|
+
message.push(codeLine(color.error(error2), index));
|
|
13708
|
+
}
|
|
13709
|
+
});
|
|
13710
|
+
p.log.message(
|
|
13711
|
+
wrap([...message, ...end], {
|
|
13712
|
+
trim: false
|
|
13713
|
+
}),
|
|
13714
|
+
{
|
|
13715
|
+
symbol: color.error`×`
|
|
13571
13716
|
}
|
|
13572
|
-
|
|
13717
|
+
);
|
|
13573
13718
|
}
|
|
13574
|
-
}
|
|
13719
|
+
};
|
|
13575
13720
|
|
|
13576
|
-
// src/
|
|
13577
|
-
import {
|
|
13578
|
-
var
|
|
13579
|
-
|
|
13580
|
-
|
|
13581
|
-
|
|
13582
|
-
|
|
13583
|
-
|
|
13584
|
-
|
|
13585
|
-
|
|
13586
|
-
|
|
13587
|
-
|
|
13588
|
-
|
|
13721
|
+
// src/cli/ui/error/file-error.ts
|
|
13722
|
+
import { log as log5 } from "@clack/prompts";
|
|
13723
|
+
var logFileError = (error) => {
|
|
13724
|
+
log5.message(
|
|
13725
|
+
wrap([color.error(error.message), color.dim(error.file)].join("\n"), {
|
|
13726
|
+
hard: true
|
|
13727
|
+
}),
|
|
13728
|
+
{ symbol: color.error(icon.error) }
|
|
13729
|
+
);
|
|
13730
|
+
};
|
|
13731
|
+
|
|
13732
|
+
// src/cli/ui/error/error.ts
|
|
13733
|
+
var logError = (error) => {
|
|
13734
|
+
if (error instanceof ConfigError) {
|
|
13735
|
+
logConfigError(error);
|
|
13736
|
+
} else if (error instanceof Cancelled) {
|
|
13737
|
+
log6.message(color.error("Cancelled."), {
|
|
13738
|
+
symbol: color.error(icon.error)
|
|
13589
13739
|
});
|
|
13590
|
-
|
|
13591
|
-
|
|
13592
|
-
|
|
13740
|
+
} else if (error instanceof ExpectedError) {
|
|
13741
|
+
log6.message(color.error(error.message), {
|
|
13742
|
+
symbol: color.error(icon.error)
|
|
13593
13743
|
});
|
|
13594
|
-
|
|
13595
|
-
|
|
13596
|
-
|
|
13744
|
+
} else if (error instanceof AppError2) {
|
|
13745
|
+
logAppError(error);
|
|
13746
|
+
} else if (error instanceof StackError3) {
|
|
13747
|
+
logStackError(error);
|
|
13748
|
+
} else if (error instanceof FileError) {
|
|
13749
|
+
logFileError(error);
|
|
13750
|
+
} else if (error instanceof Error) {
|
|
13751
|
+
const message = `${error.name}: ${error.message}`;
|
|
13752
|
+
const stack = error.stack ? color.dim(error.stack.replace(message, "")) : "";
|
|
13753
|
+
log6.message(
|
|
13754
|
+
wrap([color.error(message), stack], {
|
|
13755
|
+
hard: true
|
|
13756
|
+
}),
|
|
13757
|
+
{ symbol: color.error(icon.error) }
|
|
13758
|
+
);
|
|
13759
|
+
} else if (typeof error === "string") {
|
|
13760
|
+
log6.message(wrap(color.error(error)), {
|
|
13761
|
+
symbol: color.error(icon.error)
|
|
13597
13762
|
});
|
|
13598
|
-
|
|
13599
|
-
|
|
13600
|
-
|
|
13601
|
-
internetGatewayId: gateway.id
|
|
13763
|
+
} else {
|
|
13764
|
+
log6.message(wrap(color.error("Unknown error!")), {
|
|
13765
|
+
symbol: color.error(icon.error)
|
|
13602
13766
|
});
|
|
13603
|
-
|
|
13604
|
-
|
|
13605
|
-
|
|
13606
|
-
|
|
13607
|
-
|
|
13767
|
+
}
|
|
13768
|
+
};
|
|
13769
|
+
|
|
13770
|
+
// src/cli/ui/logo.ts
|
|
13771
|
+
var logo = () => {
|
|
13772
|
+
return `${color.primary`AWS`}${color.primary.dim`LESS`}`;
|
|
13773
|
+
};
|
|
13774
|
+
|
|
13775
|
+
// src/cli/ui/complex/layout.ts
|
|
13776
|
+
var layout = async (command, cb) => {
|
|
13777
|
+
console.log();
|
|
13778
|
+
intro(`${logo()} ${color.dim(command)}`);
|
|
13779
|
+
try {
|
|
13780
|
+
const options = program.optsWithGlobals();
|
|
13781
|
+
const appConfig = await loadAppConfig(options);
|
|
13782
|
+
logApp(appConfig, options);
|
|
13783
|
+
const stackConfigs = await loadStackConfigs(options);
|
|
13784
|
+
validateFeatures({
|
|
13785
|
+
appConfig,
|
|
13786
|
+
stackConfigs
|
|
13608
13787
|
});
|
|
13609
|
-
|
|
13610
|
-
|
|
13611
|
-
|
|
13612
|
-
|
|
13613
|
-
);
|
|
13614
|
-
|
|
13615
|
-
|
|
13616
|
-
|
|
13617
|
-
|
|
13618
|
-
|
|
13619
|
-
for (const i in zones) {
|
|
13620
|
-
const index = Number(i) + 1;
|
|
13621
|
-
const id = `${table2.identifier}-${index}`;
|
|
13622
|
-
const subnet = new aws23.ec2.Subnet(group, id, {
|
|
13623
|
-
name: `${ctx.app.name}--${table2.identifier}-${index}`,
|
|
13624
|
-
vpcId: vpc.id,
|
|
13625
|
-
cidrBlock: aws23.ec2.Peer.ipv4(`10.0.${block++}.0/24`),
|
|
13626
|
-
// ipv6CidrBlock: aws.ec2.Peer.ipv6(`fd00:10:20:${++block}::/64`),
|
|
13627
|
-
// ipv6CidrBlock: aws.ec2.Peer.ipv6(`2a05:d018:c69:660${++block}::/64`),
|
|
13628
|
-
// ipv6CidrBlock: ipv6CidrBlock.ipv6CidrBlock.apply(ip => ),
|
|
13629
|
-
// ipv6CidrBlock: slices.apply(list => aws.ec2.Peer.ipv6(list.get(block++).toString())),
|
|
13630
|
-
// assignIpv6AddressOnCreation: true,
|
|
13631
|
-
// ipv6Native: true,
|
|
13632
|
-
mapPublicIpOnLaunch: table2.identifier === "public",
|
|
13633
|
-
availabilityZone: ctx.appConfig.region + zones[i]
|
|
13634
|
-
});
|
|
13635
|
-
new aws23.ec2.SubnetRouteTableAssociation(group, id, {
|
|
13636
|
-
routeTableId: table2.id,
|
|
13637
|
-
subnetId: subnet.id
|
|
13638
|
-
});
|
|
13639
|
-
ctx.shared.set(`vpc-${table2.identifier}-subnet-id-${index}`, subnet.id);
|
|
13640
|
-
}
|
|
13641
|
-
}
|
|
13788
|
+
const result = await cb({
|
|
13789
|
+
options,
|
|
13790
|
+
appConfig,
|
|
13791
|
+
stackConfigs
|
|
13792
|
+
});
|
|
13793
|
+
outro(result ?? void 0);
|
|
13794
|
+
} catch (error) {
|
|
13795
|
+
logError(error);
|
|
13796
|
+
outro();
|
|
13797
|
+
process.exit(1);
|
|
13642
13798
|
}
|
|
13643
|
-
}
|
|
13799
|
+
};
|
|
13644
13800
|
|
|
13645
|
-
// src/
|
|
13646
|
-
var
|
|
13647
|
-
|
|
13648
|
-
|
|
13649
|
-
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
|
|
13655
|
-
|
|
13656
|
-
|
|
13657
|
-
|
|
13658
|
-
|
|
13659
|
-
|
|
13660
|
-
|
|
13661
|
-
|
|
13662
|
-
|
|
13663
|
-
topicFeature,
|
|
13664
|
-
queueFeature,
|
|
13665
|
-
storeFeature,
|
|
13666
|
-
cacheFeature,
|
|
13667
|
-
taskFeature,
|
|
13668
|
-
testFeature,
|
|
13669
|
-
cronFeature,
|
|
13670
|
-
httpFeature,
|
|
13671
|
-
restFeature,
|
|
13672
|
-
siteFeature,
|
|
13673
|
-
rpcFeature
|
|
13674
|
-
];
|
|
13801
|
+
// src/cli/command/bootstrap.ts
|
|
13802
|
+
var bootstrap = (program2) => {
|
|
13803
|
+
program2.command("bootstrap").description("Create the awsless bootstrap stack").action(async () => {
|
|
13804
|
+
await layout("bootstrap", async ({ appConfig }) => {
|
|
13805
|
+
const credentials = getCredentials(appConfig.profile);
|
|
13806
|
+
const accountId = await getAccountId(credentials, appConfig.region);
|
|
13807
|
+
await bootstrapAwsless({
|
|
13808
|
+
credentials,
|
|
13809
|
+
region: appConfig.region,
|
|
13810
|
+
accountId
|
|
13811
|
+
});
|
|
13812
|
+
return "Ready to go!";
|
|
13813
|
+
});
|
|
13814
|
+
});
|
|
13815
|
+
};
|
|
13816
|
+
|
|
13817
|
+
// src/app.ts
|
|
13818
|
+
import { App as App2, Stack } from "@awsless/formation";
|
|
13675
13819
|
|
|
13676
13820
|
// src/shared.ts
|
|
13677
13821
|
var SharedData = class {
|
|
@@ -14694,10 +14838,8 @@ var watchConfig = async (options, resolve2, reject) => {
|
|
|
14694
14838
|
try {
|
|
14695
14839
|
const appConfig = await loadAppConfig(options);
|
|
14696
14840
|
const stackConfigs = await loadStackConfigs(options);
|
|
14697
|
-
|
|
14698
|
-
|
|
14699
|
-
stackConfigs
|
|
14700
|
-
});
|
|
14841
|
+
validateFeatures({ appConfig, stackConfigs });
|
|
14842
|
+
resolve2({ appConfig, stackConfigs });
|
|
14701
14843
|
} catch (error) {
|
|
14702
14844
|
reject(error);
|
|
14703
14845
|
}
|