@awsless/awsless 0.0.12 → 0.0.14
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/bin.cjs +613 -324
- package/dist/bin.js +614 -325
- package/dist/index.cjs +7 -0
- package/dist/index.d.ts +375 -56
- package/dist/index.js +6 -0
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -63,15 +63,15 @@ var flushDebug = () => {
|
|
|
63
63
|
|
|
64
64
|
// src/util/param.ts
|
|
65
65
|
import { DeleteParameterCommand, GetParameterCommand, GetParametersByPathCommand, ParameterType, PutParameterCommand, SSMClient } from "@aws-sdk/client-ssm";
|
|
66
|
-
var configParameterPrefix = (
|
|
67
|
-
return `/${
|
|
66
|
+
var configParameterPrefix = (config) => {
|
|
67
|
+
return `/${config.stage}/awsless/${config.name}`;
|
|
68
68
|
};
|
|
69
69
|
var Params = class {
|
|
70
|
-
constructor(
|
|
71
|
-
this.config =
|
|
70
|
+
constructor(config) {
|
|
71
|
+
this.config = config;
|
|
72
72
|
this.client = new SSMClient({
|
|
73
|
-
credentials:
|
|
74
|
-
region:
|
|
73
|
+
credentials: config.credentials,
|
|
74
|
+
region: config.region
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
77
|
client;
|
|
@@ -146,13 +146,17 @@ var Params = class {
|
|
|
146
146
|
};
|
|
147
147
|
|
|
148
148
|
// src/stack.ts
|
|
149
|
-
var toStack = ({ config
|
|
150
|
-
const stackName = `${
|
|
149
|
+
var toStack = ({ config, assets, app, stackConfig, plugins }) => {
|
|
150
|
+
const stackName = `${config.name}-${stackConfig.name}`;
|
|
151
151
|
const stack = new Stack(app, stackConfig.name, {
|
|
152
152
|
stackName,
|
|
153
|
+
env: {
|
|
154
|
+
account: config.account,
|
|
155
|
+
region: config.region
|
|
156
|
+
},
|
|
153
157
|
tags: {
|
|
154
|
-
APP:
|
|
155
|
-
STAGE:
|
|
158
|
+
APP: config.name,
|
|
159
|
+
STAGE: config.stage,
|
|
156
160
|
STACK: stackConfig.name
|
|
157
161
|
}
|
|
158
162
|
});
|
|
@@ -163,7 +167,7 @@ var toStack = ({ config: config2, assets, app, stackConfig, plugins }) => {
|
|
|
163
167
|
};
|
|
164
168
|
debug("Run plugin onStack listeners");
|
|
165
169
|
const functions = plugins.map((plugin) => plugin.onStack?.({
|
|
166
|
-
config
|
|
170
|
+
config,
|
|
167
171
|
assets,
|
|
168
172
|
app,
|
|
169
173
|
stack,
|
|
@@ -182,12 +186,12 @@ var toStack = ({ config: config2, assets, app, stackConfig, plugins }) => {
|
|
|
182
186
|
],
|
|
183
187
|
resources: [
|
|
184
188
|
Arn.format({
|
|
185
|
-
region:
|
|
186
|
-
account:
|
|
189
|
+
region: config.region,
|
|
190
|
+
account: config.account,
|
|
187
191
|
partition: "aws",
|
|
188
192
|
service: "ssm",
|
|
189
193
|
resource: "parameter",
|
|
190
|
-
resourceName: configParameterPrefix(
|
|
194
|
+
resourceName: configParameterPrefix(config)
|
|
191
195
|
})
|
|
192
196
|
// Fn.sub('arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter' + configParameterPrefix(config)),
|
|
193
197
|
]
|
|
@@ -259,6 +263,9 @@ var toId = (resource, id) => {
|
|
|
259
263
|
var toName = (stack, id) => {
|
|
260
264
|
return paramCase(`${stack.stackName}-${id}`);
|
|
261
265
|
};
|
|
266
|
+
var toExportName = (name) => {
|
|
267
|
+
return paramCase(name);
|
|
268
|
+
};
|
|
262
269
|
var toEnvKey = (resource, id) => {
|
|
263
270
|
return `RESOURCE_${resource.toUpperCase()}_${id}`;
|
|
264
271
|
};
|
|
@@ -361,7 +368,7 @@ var SizeSchema = z7.custom((value) => {
|
|
|
361
368
|
|
|
362
369
|
// src/plugins/function/util/build.ts
|
|
363
370
|
import JSZip from "jszip";
|
|
364
|
-
import {
|
|
371
|
+
import { dirname, join as join2 } from "path";
|
|
365
372
|
import { mkdir, writeFile } from "fs/promises";
|
|
366
373
|
import { filesize } from "filesize";
|
|
367
374
|
var zipFiles = (files) => {
|
|
@@ -377,22 +384,22 @@ var zipFiles = (files) => {
|
|
|
377
384
|
}
|
|
378
385
|
});
|
|
379
386
|
};
|
|
380
|
-
var writeBuildHash = async (
|
|
381
|
-
const funcPath = join2(assetDir, "function",
|
|
387
|
+
var writeBuildHash = async (config, stack, id, hash) => {
|
|
388
|
+
const funcPath = join2(assetDir, "function", config.name, stack.artifactId, id);
|
|
382
389
|
const versionFile = join2(funcPath, "HASH");
|
|
383
390
|
await writeFile(versionFile, hash);
|
|
384
391
|
};
|
|
385
|
-
var writeBuildFiles = async (
|
|
392
|
+
var writeBuildFiles = async (config, stack, id, files) => {
|
|
386
393
|
const bundle = await zipFiles(files);
|
|
387
|
-
const funcPath = join2(assetDir, "function",
|
|
394
|
+
const funcPath = join2(assetDir, "function", config.name, stack.artifactId, id);
|
|
388
395
|
const filesPath = join2(funcPath, "files");
|
|
389
396
|
const bundleFile = join2(funcPath, "bundle.zip");
|
|
390
|
-
debug("Bundle size of", style.info(join2(
|
|
397
|
+
debug("Bundle size of", style.info(join2(config.name, stack.artifactId, id)), "is", style.attr(filesize(bundle.byteLength)));
|
|
391
398
|
await mkdir(filesPath, { recursive: true });
|
|
392
399
|
await writeFile(bundleFile, bundle);
|
|
393
400
|
await Promise.all(files.map(async (file) => {
|
|
394
401
|
const fileName = join2(filesPath, file.name);
|
|
395
|
-
await mkdir(
|
|
402
|
+
await mkdir(dirname(fileName), { recursive: true });
|
|
396
403
|
await writeFile(fileName, file.code);
|
|
397
404
|
if (file.map) {
|
|
398
405
|
const mapName = join2(filesPath, `${file.name}.map`);
|
|
@@ -413,20 +420,20 @@ import { GetObjectCommand, ObjectCannedACL, PutObjectCommand, S3Client, StorageC
|
|
|
413
420
|
// src/stack/bootstrap.ts
|
|
414
421
|
import { CfnOutput, RemovalPolicy, Stack as Stack2 } from "aws-cdk-lib";
|
|
415
422
|
import { Bucket, BucketAccessControl } from "aws-cdk-lib/aws-s3";
|
|
416
|
-
var assetBucketName = (
|
|
417
|
-
return `awsless-bootstrap-${
|
|
423
|
+
var assetBucketName = (config) => {
|
|
424
|
+
return `awsless-bootstrap-${config.account}-${config.region}`;
|
|
418
425
|
};
|
|
419
|
-
var assetBucketUrl = (
|
|
420
|
-
const bucket = assetBucketName(
|
|
421
|
-
return `https://s3-${
|
|
426
|
+
var assetBucketUrl = (config, stackName) => {
|
|
427
|
+
const bucket = assetBucketName(config);
|
|
428
|
+
return `https://s3-${config.region}.amazonaws.com/${bucket}/${stackName}/cloudformation.json`;
|
|
422
429
|
};
|
|
423
|
-
var version = "
|
|
424
|
-
var bootstrapStack = (
|
|
430
|
+
var version = "1";
|
|
431
|
+
var bootstrapStack = (config, app) => {
|
|
425
432
|
const stack = new Stack2(app, "bootstrap", {
|
|
426
433
|
stackName: `awsless-bootstrap`
|
|
427
434
|
});
|
|
428
435
|
new Bucket(stack, "assets", {
|
|
429
|
-
bucketName: assetBucketName(
|
|
436
|
+
bucketName: assetBucketName(config),
|
|
430
437
|
versioned: true,
|
|
431
438
|
accessControl: BucketAccessControl.PRIVATE,
|
|
432
439
|
removalPolicy: RemovalPolicy.DESTROY
|
|
@@ -444,17 +451,17 @@ var shouldDeployBootstrap = async (client, name) => {
|
|
|
444
451
|
};
|
|
445
452
|
|
|
446
453
|
// src/plugins/function/util/publish.ts
|
|
447
|
-
var publishFunctionAsset = async (
|
|
448
|
-
const bucket = assetBucketName(
|
|
449
|
-
const key = `${
|
|
450
|
-
const funcPath = join3(assetDir, "function",
|
|
454
|
+
var publishFunctionAsset = async (config, stack, id) => {
|
|
455
|
+
const bucket = assetBucketName(config);
|
|
456
|
+
const key = `${config.name}/${stack.artifactId}/function/${id}.zip`;
|
|
457
|
+
const funcPath = join3(assetDir, "function", config.name, stack.artifactId, id);
|
|
451
458
|
const bundleFile = join3(funcPath, "bundle.zip");
|
|
452
459
|
const hashFile = join3(funcPath, "HASH");
|
|
453
460
|
const hash = await readFile(hashFile, "utf8");
|
|
454
461
|
const file = await readFile(bundleFile);
|
|
455
462
|
const client = new S3Client({
|
|
456
|
-
credentials:
|
|
457
|
-
region:
|
|
463
|
+
credentials: config.credentials,
|
|
464
|
+
region: config.region
|
|
458
465
|
});
|
|
459
466
|
let getResult;
|
|
460
467
|
try {
|
|
@@ -589,8 +596,8 @@ var functionPlugin = definePlugin({
|
|
|
589
596
|
});
|
|
590
597
|
}
|
|
591
598
|
});
|
|
592
|
-
var toFunction = ({ config
|
|
593
|
-
const props = typeof fileOrProps === "string" ? { ...
|
|
599
|
+
var toFunction = ({ config, stack, assets }, id, fileOrProps) => {
|
|
600
|
+
const props = typeof fileOrProps === "string" ? { ...config.defaults?.function, file: fileOrProps } : { ...config.defaults?.function, ...fileOrProps };
|
|
594
601
|
const lambda = new Function(stack, toId("function", id), {
|
|
595
602
|
functionName: toName(stack, id),
|
|
596
603
|
handler: "index.default",
|
|
@@ -598,8 +605,8 @@ var toFunction = ({ config: config2, stack, assets }, id, fileOrProps) => {
|
|
|
598
605
|
...props,
|
|
599
606
|
memorySize: props.memorySize.toMebibytes()
|
|
600
607
|
});
|
|
601
|
-
lambda.addEnvironment("APP",
|
|
602
|
-
lambda.addEnvironment("STAGE",
|
|
608
|
+
lambda.addEnvironment("APP", config.name, { removeInEdge: true });
|
|
609
|
+
lambda.addEnvironment("STAGE", config.stage, { removeInEdge: true });
|
|
603
610
|
lambda.addEnvironment("STACK", stack.artifactId, { removeInEdge: true });
|
|
604
611
|
if (lambda.runtime.toString().startsWith("nodejs")) {
|
|
605
612
|
lambda.addEnvironment("AWS_NODEJS_CONNECTION_REUSE_ENABLED", "1", {
|
|
@@ -612,8 +619,8 @@ var toFunction = ({ config: config2, stack, assets }, id, fileOrProps) => {
|
|
|
612
619
|
resourceName: id,
|
|
613
620
|
async build() {
|
|
614
621
|
const result = await rollupBuild(props.file);
|
|
615
|
-
const bundle = await writeBuildFiles(
|
|
616
|
-
await writeBuildHash(
|
|
622
|
+
const bundle = await writeBuildFiles(config, stack, id, result.files);
|
|
623
|
+
await writeBuildHash(config, stack, id, result.hash);
|
|
617
624
|
const func = lambda.node.defaultChild;
|
|
618
625
|
func.handler = result.handler;
|
|
619
626
|
return {
|
|
@@ -621,11 +628,11 @@ var toFunction = ({ config: config2, stack, assets }, id, fileOrProps) => {
|
|
|
621
628
|
};
|
|
622
629
|
},
|
|
623
630
|
async publish() {
|
|
624
|
-
const version2 = await publishFunctionAsset(
|
|
631
|
+
const version2 = await publishFunctionAsset(config, stack, id);
|
|
625
632
|
const func = lambda.node.defaultChild;
|
|
626
633
|
func.code = {
|
|
627
|
-
s3Bucket: assetBucketName(
|
|
628
|
-
s3Key: `${
|
|
634
|
+
s3Bucket: assetBucketName(config),
|
|
635
|
+
s3Key: `${config.name}/${stack.artifactId}/function/${id}.zip`,
|
|
629
636
|
s3ObjectVersion: version2
|
|
630
637
|
};
|
|
631
638
|
}
|
|
@@ -694,9 +701,9 @@ var queuePlugin = definePlugin({
|
|
|
694
701
|
}).array()
|
|
695
702
|
}),
|
|
696
703
|
onStack(ctx) {
|
|
697
|
-
const { stack, config
|
|
704
|
+
const { stack, config, stackConfig, bind } = ctx;
|
|
698
705
|
return Object.entries(stackConfig.queues || {}).map(([id, functionOrProps]) => {
|
|
699
|
-
const props = typeof functionOrProps === "string" ? { ...
|
|
706
|
+
const props = typeof functionOrProps === "string" ? { ...config.defaults.queue, consumer: functionOrProps } : { ...config.defaults.queue, ...functionOrProps };
|
|
700
707
|
const queue2 = new Queue(stack, toId("queue", id), {
|
|
701
708
|
queueName: toName(stack, id),
|
|
702
709
|
...props,
|
|
@@ -860,20 +867,20 @@ var topicPlugin = definePlugin({
|
|
|
860
867
|
topics: z18.record(ResourceIdSchema, FunctionSchema).optional()
|
|
861
868
|
}).array()
|
|
862
869
|
}),
|
|
863
|
-
onBootstrap({ config
|
|
864
|
-
const allTopicNames =
|
|
870
|
+
onBootstrap({ config, stack }) {
|
|
871
|
+
const allTopicNames = config.stacks.map((stack2) => {
|
|
865
872
|
return Object.keys(stack2.topics || {});
|
|
866
873
|
}).flat();
|
|
867
874
|
const uniqueTopicNames = [...new Set(allTopicNames)];
|
|
868
875
|
uniqueTopicNames.forEach((id) => {
|
|
869
876
|
new Topic(stack, toId("topic", id), {
|
|
870
|
-
topicName: `${
|
|
877
|
+
topicName: `${config.name}-${id}`,
|
|
871
878
|
displayName: id
|
|
872
879
|
});
|
|
873
880
|
});
|
|
874
881
|
},
|
|
875
882
|
onStack(ctx) {
|
|
876
|
-
const { config
|
|
883
|
+
const { config, stack, stackConfig, bind } = ctx;
|
|
877
884
|
return Object.entries(stackConfig.topics || {}).map(([id, props]) => {
|
|
878
885
|
const lambda = toFunction(ctx, id, props);
|
|
879
886
|
const topic = Topic.fromTopicArn(
|
|
@@ -882,7 +889,7 @@ var topicPlugin = definePlugin({
|
|
|
882
889
|
Arn2.format({
|
|
883
890
|
arnFormat: ArnFormat.NO_RESOURCE_NAME,
|
|
884
891
|
service: "sns",
|
|
885
|
-
resource: `${
|
|
892
|
+
resource: `${config.name}-${id}`
|
|
886
893
|
}, stack)
|
|
887
894
|
);
|
|
888
895
|
lambda.addEventSource(new SnsEventSource(topic));
|
|
@@ -895,35 +902,8 @@ var topicPlugin = definePlugin({
|
|
|
895
902
|
}
|
|
896
903
|
});
|
|
897
904
|
|
|
898
|
-
// src/plugins/search.ts
|
|
899
|
-
import { z as z19 } from "zod";
|
|
900
|
-
import { CfnCollection } from "aws-cdk-lib/aws-opensearchserverless";
|
|
901
|
-
import { PolicyStatement as PolicyStatement2 } from "aws-cdk-lib/aws-iam";
|
|
902
|
-
var searchPlugin = definePlugin({
|
|
903
|
-
name: "search",
|
|
904
|
-
schema: z19.object({
|
|
905
|
-
stacks: z19.object({
|
|
906
|
-
searchs: z19.array(ResourceIdSchema).optional()
|
|
907
|
-
}).array()
|
|
908
|
-
}),
|
|
909
|
-
onStack({ stack, stackConfig, bind }) {
|
|
910
|
-
(stackConfig.searchs || []).forEach((id) => {
|
|
911
|
-
const collection = new CfnCollection(stack, toId("search", id), {
|
|
912
|
-
name: toName(stack, id),
|
|
913
|
-
type: "SEARCH"
|
|
914
|
-
});
|
|
915
|
-
bind((lambda) => {
|
|
916
|
-
lambda.addToRolePolicy(new PolicyStatement2({
|
|
917
|
-
actions: ["aoss:APIAccessAll"],
|
|
918
|
-
resources: [collection.attrArn]
|
|
919
|
-
}));
|
|
920
|
-
});
|
|
921
|
-
});
|
|
922
|
-
}
|
|
923
|
-
});
|
|
924
|
-
|
|
925
905
|
// src/plugins/graphql/index.ts
|
|
926
|
-
import { z as
|
|
906
|
+
import { z as z20 } from "zod";
|
|
927
907
|
import { AuthorizationType, CfnGraphQLApi, CfnGraphQLSchema, GraphqlApi, MappingTemplate } from "aws-cdk-lib/aws-appsync";
|
|
928
908
|
import { mergeTypeDefs } from "@graphql-tools/merge";
|
|
929
909
|
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
@@ -937,56 +917,56 @@ var toArray = (value) => {
|
|
|
937
917
|
};
|
|
938
918
|
|
|
939
919
|
// src/plugins/graphql/index.ts
|
|
940
|
-
import { dirname, join as join4 } from "path";
|
|
920
|
+
import { dirname as dirname2, join as join4 } from "path";
|
|
941
921
|
import { print } from "graphql";
|
|
942
922
|
import { paramCase as paramCase2 } from "change-case";
|
|
943
923
|
|
|
944
924
|
// src/plugins/graphql/schema/resolver-field.ts
|
|
945
|
-
import { z as
|
|
946
|
-
var ResolverFieldSchema =
|
|
947
|
-
return
|
|
925
|
+
import { z as z19 } from "zod";
|
|
926
|
+
var ResolverFieldSchema = z19.custom((value) => {
|
|
927
|
+
return z19.string().regex(/([a-z0-9\_]+)(\s){1}([a-z0-9\_]+)/gi).safeParse(value).success;
|
|
948
928
|
}, `Invalid resolver field. Valid example: "Query list"`);
|
|
949
929
|
|
|
950
930
|
// src/plugins/graphql/index.ts
|
|
951
931
|
import { CfnOutput as CfnOutput2, Fn } from "aws-cdk-lib";
|
|
952
932
|
var graphqlPlugin = definePlugin({
|
|
953
933
|
name: "graphql",
|
|
954
|
-
schema:
|
|
955
|
-
defaults:
|
|
956
|
-
graphql:
|
|
957
|
-
authorization:
|
|
934
|
+
schema: z20.object({
|
|
935
|
+
defaults: z20.object({
|
|
936
|
+
graphql: z20.record(ResourceIdSchema, z20.object({
|
|
937
|
+
authorization: z20.object({
|
|
958
938
|
authorizer: FunctionSchema,
|
|
959
939
|
ttl: DurationSchema.default("1 hour")
|
|
960
940
|
}).optional(),
|
|
961
|
-
mappingTemplate:
|
|
941
|
+
mappingTemplate: z20.object({
|
|
962
942
|
request: LocalFileSchema.optional(),
|
|
963
943
|
response: LocalFileSchema.optional()
|
|
964
944
|
}).optional()
|
|
965
945
|
})).optional()
|
|
966
946
|
}).default({}),
|
|
967
|
-
stacks:
|
|
968
|
-
graphql:
|
|
969
|
-
schema:
|
|
947
|
+
stacks: z20.object({
|
|
948
|
+
graphql: z20.record(ResourceIdSchema, z20.object({
|
|
949
|
+
schema: z20.union([
|
|
970
950
|
LocalFileSchema,
|
|
971
|
-
|
|
951
|
+
z20.array(LocalFileSchema).min(1)
|
|
972
952
|
]).optional(),
|
|
973
|
-
resolvers:
|
|
953
|
+
resolvers: z20.record(ResolverFieldSchema, FunctionSchema).optional()
|
|
974
954
|
})).optional()
|
|
975
955
|
}).array()
|
|
976
956
|
}),
|
|
977
|
-
onBootstrap({ config
|
|
957
|
+
onBootstrap({ config, stack, assets }) {
|
|
978
958
|
const list3 = /* @__PURE__ */ new Set();
|
|
979
|
-
Object.values(
|
|
959
|
+
Object.values(config.stacks).forEach((stackConfig) => {
|
|
980
960
|
Object.keys(stackConfig.graphql || {}).forEach((id) => {
|
|
981
961
|
list3.add(id);
|
|
982
962
|
});
|
|
983
963
|
});
|
|
984
964
|
list3.forEach((id) => {
|
|
985
|
-
const file = join4(assetDir, "graphql",
|
|
986
|
-
const authorization =
|
|
965
|
+
const file = join4(assetDir, "graphql", config.name, id, "schema.graphql");
|
|
966
|
+
const authorization = config.defaults.graphql?.[id]?.authorization;
|
|
987
967
|
const authProps = {};
|
|
988
968
|
if (authorization) {
|
|
989
|
-
const authorizer = toFunction({ config
|
|
969
|
+
const authorizer = toFunction({ config, assets, stack }, `${id}-authorizer`, authorization.authorizer);
|
|
990
970
|
authProps.additionalAuthenticationProviders = [{
|
|
991
971
|
authenticationType: AuthorizationType.LAMBDA,
|
|
992
972
|
lambdaAuthorizerConfig: {
|
|
@@ -1010,7 +990,7 @@ var graphqlPlugin = definePlugin({
|
|
|
1010
990
|
resourceName: id,
|
|
1011
991
|
async build() {
|
|
1012
992
|
const schemas = [];
|
|
1013
|
-
await Promise.all(Object.values(
|
|
993
|
+
await Promise.all(Object.values(config.stacks).map(async (stackConfig) => {
|
|
1014
994
|
const schemaFiles = toArray(stackConfig.graphql?.[id].schema || []);
|
|
1015
995
|
await Promise.all(schemaFiles.map(async (schemaFile) => {
|
|
1016
996
|
const schema3 = await readFile2(schemaFile, "utf8");
|
|
@@ -1018,7 +998,7 @@ var graphqlPlugin = definePlugin({
|
|
|
1018
998
|
}));
|
|
1019
999
|
}));
|
|
1020
1000
|
const schema2 = print(mergeTypeDefs(schemas));
|
|
1021
|
-
await mkdir2(
|
|
1001
|
+
await mkdir2(dirname2(file), { recursive: true });
|
|
1022
1002
|
await writeFile2(file, schema2);
|
|
1023
1003
|
new CfnGraphQLSchema(stack, toId("schema", id), {
|
|
1024
1004
|
apiId: api.attrApiId,
|
|
@@ -1029,9 +1009,9 @@ var graphqlPlugin = definePlugin({
|
|
|
1029
1009
|
});
|
|
1030
1010
|
},
|
|
1031
1011
|
onStack(ctx) {
|
|
1032
|
-
const { config
|
|
1012
|
+
const { config, stack, stackConfig } = ctx;
|
|
1033
1013
|
return Object.entries(stackConfig.graphql || {}).map(([id, props]) => {
|
|
1034
|
-
const defaults =
|
|
1014
|
+
const defaults = config.defaults.graphql?.[id] || {};
|
|
1035
1015
|
return Object.entries(props.resolvers || {}).map(([typeAndField, functionProps]) => {
|
|
1036
1016
|
const api = GraphqlApi.fromGraphqlApiAttributes(stack, toId("graphql", id), {
|
|
1037
1017
|
graphqlApiId: Fn.importValue(toId("graphql", id))
|
|
@@ -1054,6 +1034,272 @@ var graphqlPlugin = definePlugin({
|
|
|
1054
1034
|
}
|
|
1055
1035
|
});
|
|
1056
1036
|
|
|
1037
|
+
// src/plugins/pubsub.ts
|
|
1038
|
+
import { z as z21 } from "zod";
|
|
1039
|
+
import { CfnTopicRule } from "aws-cdk-lib/aws-iot";
|
|
1040
|
+
import { PolicyStatement as PolicyStatement2 } from "aws-cdk-lib/aws-iam";
|
|
1041
|
+
import { snakeCase } from "change-case";
|
|
1042
|
+
var pubsubPlugin = definePlugin({
|
|
1043
|
+
name: "pubsub",
|
|
1044
|
+
schema: z21.object({
|
|
1045
|
+
stacks: z21.object({
|
|
1046
|
+
pubsub: z21.record(ResourceIdSchema, z21.object({
|
|
1047
|
+
sql: z21.string(),
|
|
1048
|
+
sqlVersion: z21.enum(["2015-10-08", "2016-03-23", "beta"]).default("2016-03-23"),
|
|
1049
|
+
consumer: FunctionSchema
|
|
1050
|
+
})).optional()
|
|
1051
|
+
}).array()
|
|
1052
|
+
}),
|
|
1053
|
+
onStack(ctx) {
|
|
1054
|
+
const { stack, stackConfig, bind } = ctx;
|
|
1055
|
+
bind((lambda) => {
|
|
1056
|
+
lambda.addToRolePolicy(new PolicyStatement2({
|
|
1057
|
+
actions: ["iot:publish"],
|
|
1058
|
+
resources: ["*"]
|
|
1059
|
+
}));
|
|
1060
|
+
});
|
|
1061
|
+
return Object.entries(stackConfig.pubsub || {}).map(([id, props]) => {
|
|
1062
|
+
const lambda = toFunction(ctx, id, props.consumer);
|
|
1063
|
+
new CfnTopicRule(stack, toId("pubsub", id), {
|
|
1064
|
+
ruleName: snakeCase(toName(stack, id)),
|
|
1065
|
+
topicRulePayload: {
|
|
1066
|
+
sql: props.sql,
|
|
1067
|
+
awsIotSqlVersion: props.sqlVersion,
|
|
1068
|
+
actions: [{
|
|
1069
|
+
lambda: {
|
|
1070
|
+
functionArn: lambda.functionArn
|
|
1071
|
+
}
|
|
1072
|
+
}]
|
|
1073
|
+
}
|
|
1074
|
+
});
|
|
1075
|
+
return lambda;
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
});
|
|
1079
|
+
|
|
1080
|
+
// src/plugins/http/index.ts
|
|
1081
|
+
import { z as z23 } from "zod";
|
|
1082
|
+
import { Peer, Port, SecurityGroup, SubnetType, Vpc } from "aws-cdk-lib/aws-ec2";
|
|
1083
|
+
import { ApplicationListener, ApplicationListenerRule, ApplicationLoadBalancer, ApplicationProtocol, ApplicationTargetGroup, ListenerAction, ListenerCondition } from "aws-cdk-lib/aws-elasticloadbalancingv2";
|
|
1084
|
+
import { HostedZone, RecordSet, RecordType, RecordTarget } from "aws-cdk-lib/aws-route53";
|
|
1085
|
+
import { LoadBalancerTarget } from "aws-cdk-lib/aws-route53-targets";
|
|
1086
|
+
import { LambdaTarget } from "aws-cdk-lib/aws-elasticloadbalancingv2-targets";
|
|
1087
|
+
import { CfnOutput as CfnOutput3, Fn as Fn2, Token } from "aws-cdk-lib";
|
|
1088
|
+
import { Certificate } from "aws-cdk-lib/aws-certificatemanager";
|
|
1089
|
+
import { paramCase as paramCase3 } from "change-case";
|
|
1090
|
+
|
|
1091
|
+
// src/plugins/http/schema/route.ts
|
|
1092
|
+
import { z as z22 } from "zod";
|
|
1093
|
+
var RouteSchema = z22.custom((route) => {
|
|
1094
|
+
return z22.string().regex(/^(POST|GET|PUT|DELETE|HEAD|OPTIONS)(\s\/[a-z0-9\+\_\-\/]*)$/ig).safeParse(route).success;
|
|
1095
|
+
}, "Invalid route");
|
|
1096
|
+
|
|
1097
|
+
// src/plugins/http/util/priority.ts
|
|
1098
|
+
var strToInt = (str) => {
|
|
1099
|
+
return parseInt(Buffer.from(str, "utf8").toString("hex"), 16);
|
|
1100
|
+
};
|
|
1101
|
+
var generatePriority = (stackName, route) => {
|
|
1102
|
+
const start = strToInt(stackName) % 500 + 1;
|
|
1103
|
+
const end = strToInt(route) % 100;
|
|
1104
|
+
const priority = start + "" + end;
|
|
1105
|
+
return parseInt(priority, 10);
|
|
1106
|
+
};
|
|
1107
|
+
|
|
1108
|
+
// src/plugins/http/index.ts
|
|
1109
|
+
var httpPlugin = definePlugin({
|
|
1110
|
+
name: "http",
|
|
1111
|
+
schema: z23.object({
|
|
1112
|
+
defaults: z23.object({
|
|
1113
|
+
http: z23.record(
|
|
1114
|
+
ResourceIdSchema,
|
|
1115
|
+
z23.object({
|
|
1116
|
+
domain: z23.string(),
|
|
1117
|
+
subDomain: z23.string()
|
|
1118
|
+
})
|
|
1119
|
+
).optional()
|
|
1120
|
+
}).default({}),
|
|
1121
|
+
stacks: z23.object({
|
|
1122
|
+
http: z23.record(
|
|
1123
|
+
ResourceIdSchema,
|
|
1124
|
+
z23.record(RouteSchema, FunctionSchema)
|
|
1125
|
+
).optional()
|
|
1126
|
+
}).array()
|
|
1127
|
+
}),
|
|
1128
|
+
onBootstrap({ stack, config }) {
|
|
1129
|
+
if (Object.keys(config.defaults?.http || {}).length === 0) {
|
|
1130
|
+
return;
|
|
1131
|
+
}
|
|
1132
|
+
const vpc = new Vpc(stack, toId("vpc", "http"), {
|
|
1133
|
+
subnetConfiguration: [{
|
|
1134
|
+
name: "public",
|
|
1135
|
+
subnetType: SubnetType.PUBLIC,
|
|
1136
|
+
cidrMask: 24
|
|
1137
|
+
}],
|
|
1138
|
+
availabilityZones: [
|
|
1139
|
+
config.region + "a",
|
|
1140
|
+
config.region + "b",
|
|
1141
|
+
config.region + "c"
|
|
1142
|
+
]
|
|
1143
|
+
});
|
|
1144
|
+
const securityGroup = new SecurityGroup(stack, toId("security-group", "http"), {
|
|
1145
|
+
vpc
|
|
1146
|
+
});
|
|
1147
|
+
securityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(443));
|
|
1148
|
+
securityGroup.addIngressRule(Peer.anyIpv6(), Port.tcp(443));
|
|
1149
|
+
new CfnOutput3(stack, toId("output", "http-vpc"), {
|
|
1150
|
+
exportName: "http-vpc-id",
|
|
1151
|
+
value: vpc.vpcId
|
|
1152
|
+
});
|
|
1153
|
+
new CfnOutput3(stack, toId("output", "http-security-group"), {
|
|
1154
|
+
exportName: "http-security-group-id",
|
|
1155
|
+
value: securityGroup.securityGroupId
|
|
1156
|
+
});
|
|
1157
|
+
Object.entries(config.defaults?.http || {}).forEach(([id, props]) => {
|
|
1158
|
+
const loadBalancer = new ApplicationLoadBalancer(stack, toId("load-balancer", id), {
|
|
1159
|
+
vpc,
|
|
1160
|
+
securityGroup
|
|
1161
|
+
});
|
|
1162
|
+
const zone = HostedZone.fromHostedZoneAttributes(
|
|
1163
|
+
stack,
|
|
1164
|
+
toId("hosted-zone", id),
|
|
1165
|
+
{
|
|
1166
|
+
hostedZoneId: Token.asString(Fn2.ref(toId("hosted-zone", props.domain))),
|
|
1167
|
+
zoneName: props.domain + "."
|
|
1168
|
+
}
|
|
1169
|
+
);
|
|
1170
|
+
const certificate = Certificate.fromCertificateArn(
|
|
1171
|
+
stack,
|
|
1172
|
+
toId("certificate", id),
|
|
1173
|
+
Token.asString(Fn2.ref(toId("certificate", props.domain)))
|
|
1174
|
+
);
|
|
1175
|
+
const target = RecordTarget.fromAlias(new LoadBalancerTarget(loadBalancer));
|
|
1176
|
+
const recordName = props.subDomain ? `${props.subDomain}.${props.domain}` : props.domain;
|
|
1177
|
+
new RecordSet(stack, toId("record-set", id), {
|
|
1178
|
+
zone,
|
|
1179
|
+
target,
|
|
1180
|
+
recordName,
|
|
1181
|
+
recordType: RecordType.A
|
|
1182
|
+
});
|
|
1183
|
+
const listener = loadBalancer.addListener(toId("listener", id), {
|
|
1184
|
+
port: 443,
|
|
1185
|
+
protocol: ApplicationProtocol.HTTPS,
|
|
1186
|
+
certificates: [certificate],
|
|
1187
|
+
defaultAction: ListenerAction.fixedResponse(404, {
|
|
1188
|
+
contentType: "application/json",
|
|
1189
|
+
messageBody: JSON.stringify({
|
|
1190
|
+
message: "Route not found"
|
|
1191
|
+
})
|
|
1192
|
+
})
|
|
1193
|
+
});
|
|
1194
|
+
new CfnOutput3(stack, toId("output", `http-${id}-listener`), {
|
|
1195
|
+
exportName: `http-${id}-listener-arn`,
|
|
1196
|
+
value: listener.listenerArn
|
|
1197
|
+
});
|
|
1198
|
+
});
|
|
1199
|
+
},
|
|
1200
|
+
onStack(ctx) {
|
|
1201
|
+
const { stack, stackConfig } = ctx;
|
|
1202
|
+
return Object.entries(stackConfig.http || {}).map(([id, routes]) => {
|
|
1203
|
+
const listener = ApplicationListener.fromApplicationListenerAttributes(stack, toId("listener", id), {
|
|
1204
|
+
listenerArn: Fn2.importValue(`http-${id}-listener-arn`),
|
|
1205
|
+
securityGroup: SecurityGroup.fromLookupById(
|
|
1206
|
+
stack,
|
|
1207
|
+
toId("security-group", id),
|
|
1208
|
+
"http-security-group-id"
|
|
1209
|
+
)
|
|
1210
|
+
});
|
|
1211
|
+
return Object.entries(routes).map(([route, props]) => {
|
|
1212
|
+
const lambda = toFunction(ctx, paramCase3(route), props);
|
|
1213
|
+
const [method, ...paths] = route.split(" ");
|
|
1214
|
+
const path = paths.join(" ");
|
|
1215
|
+
new ApplicationListenerRule(stack, toId("listener-rule", route), {
|
|
1216
|
+
listener,
|
|
1217
|
+
priority: generatePriority(stackConfig.name, route),
|
|
1218
|
+
action: ListenerAction.forward([
|
|
1219
|
+
new ApplicationTargetGroup(stack, toId("target-group", route), {
|
|
1220
|
+
targets: [new LambdaTarget(lambda)]
|
|
1221
|
+
})
|
|
1222
|
+
]),
|
|
1223
|
+
conditions: [
|
|
1224
|
+
ListenerCondition.httpRequestMethods([method]),
|
|
1225
|
+
ListenerCondition.pathPatterns([path])
|
|
1226
|
+
]
|
|
1227
|
+
});
|
|
1228
|
+
return lambda;
|
|
1229
|
+
});
|
|
1230
|
+
}).flat();
|
|
1231
|
+
}
|
|
1232
|
+
});
|
|
1233
|
+
|
|
1234
|
+
// src/plugins/domain/index.ts
|
|
1235
|
+
import { z as z26 } from "zod";
|
|
1236
|
+
import { HostedZone as HostedZone2, CfnRecordSetGroup } from "aws-cdk-lib/aws-route53";
|
|
1237
|
+
import { Certificate as Certificate2, CertificateValidation } from "aws-cdk-lib/aws-certificatemanager";
|
|
1238
|
+
|
|
1239
|
+
// src/plugins/domain/schema/record-type.ts
|
|
1240
|
+
import { RecordType as RecordType2 } from "aws-cdk-lib/aws-route53";
|
|
1241
|
+
import { z as z24 } from "zod";
|
|
1242
|
+
var types4 = {
|
|
1243
|
+
"A": RecordType2.A,
|
|
1244
|
+
"AAAA": RecordType2.AAAA,
|
|
1245
|
+
"MX": RecordType2.MX,
|
|
1246
|
+
"TXT": RecordType2.TXT,
|
|
1247
|
+
"CNAME": RecordType2.CNAME
|
|
1248
|
+
};
|
|
1249
|
+
var RecordTypeSchema = z24.enum(Object.keys(types4)).transform((value) => types4[value]);
|
|
1250
|
+
|
|
1251
|
+
// src/plugins/domain/schema/domain-name.ts
|
|
1252
|
+
import { z as z25 } from "zod";
|
|
1253
|
+
var DomainNameSchema = z25.string().regex(/[a-z\-\_\.]/g, "Invalid domain name");
|
|
1254
|
+
|
|
1255
|
+
// src/plugins/domain/index.ts
|
|
1256
|
+
import { CfnOutput as CfnOutput4 } from "aws-cdk-lib";
|
|
1257
|
+
var domainPlugin = definePlugin({
|
|
1258
|
+
name: "domain",
|
|
1259
|
+
schema: z26.object({
|
|
1260
|
+
domains: z26.record(DomainNameSchema, z26.object({
|
|
1261
|
+
name: DomainNameSchema.optional(),
|
|
1262
|
+
type: RecordTypeSchema,
|
|
1263
|
+
ttl: DurationSchema,
|
|
1264
|
+
records: z26.string().array()
|
|
1265
|
+
}).array()).optional()
|
|
1266
|
+
}),
|
|
1267
|
+
onBootstrap({ config, stack }) {
|
|
1268
|
+
Object.entries(config.domains || {}).forEach(([domain, dnsRecords]) => {
|
|
1269
|
+
const hostedZone = new HostedZone2(stack, toId("hosted-zone", domain), {
|
|
1270
|
+
zoneName: domain,
|
|
1271
|
+
addTrailingDot: true
|
|
1272
|
+
});
|
|
1273
|
+
hostedZone.node.defaultChild.overrideLogicalId(toId("hosted-zone", domain));
|
|
1274
|
+
const certificate = new Certificate2(stack, toId("certificate", domain), {
|
|
1275
|
+
domainName: domain,
|
|
1276
|
+
validation: CertificateValidation.fromDns(hostedZone),
|
|
1277
|
+
subjectAlternativeNames: [`*.${domain}`]
|
|
1278
|
+
});
|
|
1279
|
+
certificate.node.defaultChild.overrideLogicalId(toId("certificate", domain));
|
|
1280
|
+
new CfnOutput4(stack, toId("output-hosted-zone", domain), {
|
|
1281
|
+
exportName: toExportName(`hosted-zone-${domain}-id`),
|
|
1282
|
+
value: hostedZone.hostedZoneId
|
|
1283
|
+
});
|
|
1284
|
+
new CfnOutput4(stack, toId("output-certificate", domain), {
|
|
1285
|
+
exportName: toExportName(`certificate-${domain}-arn`),
|
|
1286
|
+
value: certificate.certificateArn
|
|
1287
|
+
});
|
|
1288
|
+
if (dnsRecords.length > 0) {
|
|
1289
|
+
new CfnRecordSetGroup(stack, toId("record-set-group", domain), {
|
|
1290
|
+
hostedZoneId: hostedZone.hostedZoneId,
|
|
1291
|
+
recordSets: dnsRecords.map((props) => ({
|
|
1292
|
+
name: props.name || "",
|
|
1293
|
+
type: props.type,
|
|
1294
|
+
ttl: props.ttl.toSeconds().toString(),
|
|
1295
|
+
resourceRecords: props.records
|
|
1296
|
+
}))
|
|
1297
|
+
});
|
|
1298
|
+
}
|
|
1299
|
+
});
|
|
1300
|
+
}
|
|
1301
|
+
});
|
|
1302
|
+
|
|
1057
1303
|
// src/plugins/index.ts
|
|
1058
1304
|
var defaultPlugins = [
|
|
1059
1305
|
functionPlugin,
|
|
@@ -1062,22 +1308,25 @@ var defaultPlugins = [
|
|
|
1062
1308
|
tablePlugin,
|
|
1063
1309
|
storePlugin,
|
|
1064
1310
|
topicPlugin,
|
|
1065
|
-
searchPlugin,
|
|
1066
|
-
graphqlPlugin
|
|
1311
|
+
// searchPlugin,
|
|
1312
|
+
graphqlPlugin,
|
|
1313
|
+
pubsubPlugin,
|
|
1314
|
+
domainPlugin,
|
|
1315
|
+
httpPlugin
|
|
1067
1316
|
];
|
|
1068
1317
|
|
|
1069
1318
|
// src/stack/app-bootstrap.ts
|
|
1070
|
-
var appBootstrapStack = ({ config
|
|
1319
|
+
var appBootstrapStack = ({ config, app, assets }) => {
|
|
1071
1320
|
const stack = new Stack3(app, "bootstrap", {
|
|
1072
|
-
stackName: `${
|
|
1321
|
+
stackName: `${config.name}-bootstrap`
|
|
1073
1322
|
});
|
|
1074
1323
|
const plugins = [
|
|
1075
1324
|
...defaultPlugins,
|
|
1076
|
-
...
|
|
1325
|
+
...config.plugins || []
|
|
1077
1326
|
];
|
|
1078
1327
|
debug("Run plugin onBootstrap listeners");
|
|
1079
1328
|
const functions = plugins.map((plugin) => plugin.onBootstrap?.({
|
|
1080
|
-
config
|
|
1329
|
+
config,
|
|
1081
1330
|
app,
|
|
1082
1331
|
stack,
|
|
1083
1332
|
assets
|
|
@@ -1101,9 +1350,9 @@ var flattenDependencyTree = (stacks) => {
|
|
|
1101
1350
|
return list3;
|
|
1102
1351
|
};
|
|
1103
1352
|
var createDependencyTree = (stacks, startingLevel) => {
|
|
1104
|
-
const list3 = stacks.map(({ stack, config
|
|
1353
|
+
const list3 = stacks.map(({ stack, config }) => ({
|
|
1105
1354
|
stack,
|
|
1106
|
-
depends:
|
|
1355
|
+
depends: config?.depends?.map((dep) => dep.name) || []
|
|
1107
1356
|
}));
|
|
1108
1357
|
const findChildren = (list4, parents, level) => {
|
|
1109
1358
|
const children = [];
|
|
@@ -1175,11 +1424,11 @@ var Assets = class {
|
|
|
1175
1424
|
};
|
|
1176
1425
|
|
|
1177
1426
|
// src/app.ts
|
|
1178
|
-
var makeApp = (
|
|
1427
|
+
var makeApp = (config) => {
|
|
1179
1428
|
return new App4({
|
|
1180
1429
|
outdir: assemblyDir,
|
|
1181
1430
|
defaultStackSynthesizer: new DefaultStackSynthesizer({
|
|
1182
|
-
fileAssetsBucketName: assetBucketName(
|
|
1431
|
+
fileAssetsBucketName: assetBucketName(config),
|
|
1183
1432
|
fileAssetPublishingRoleArn: "",
|
|
1184
1433
|
generateBootstrapVersionRule: false
|
|
1185
1434
|
})
|
|
@@ -1196,26 +1445,26 @@ var getAllDepends = (filters) => {
|
|
|
1196
1445
|
walk(filters);
|
|
1197
1446
|
return list3;
|
|
1198
1447
|
};
|
|
1199
|
-
var toApp = async (
|
|
1448
|
+
var toApp = async (config, filters) => {
|
|
1200
1449
|
const assets = new Assets();
|
|
1201
|
-
const app = makeApp(
|
|
1450
|
+
const app = makeApp(config);
|
|
1202
1451
|
const stacks = [];
|
|
1203
1452
|
const plugins = [
|
|
1204
1453
|
...defaultPlugins,
|
|
1205
|
-
...
|
|
1454
|
+
...config.plugins || []
|
|
1206
1455
|
];
|
|
1207
1456
|
debug("Plugins detected:", plugins.map((plugin) => style.info(plugin.name)).join(", "));
|
|
1208
1457
|
debug("Run plugin onApp listeners");
|
|
1209
|
-
plugins.forEach((plugin) => plugin.onApp?.({ config
|
|
1210
|
-
const bootstrap2 = appBootstrapStack({ config
|
|
1458
|
+
plugins.forEach((plugin) => plugin.onApp?.({ config, app, assets }));
|
|
1459
|
+
const bootstrap2 = appBootstrapStack({ config, app, assets });
|
|
1211
1460
|
debug("Stack filters:", filters.map((filter) => style.info(filter)).join(", "));
|
|
1212
|
-
const filterdStacks = filters.length === 0 ?
|
|
1461
|
+
const filterdStacks = filters.length === 0 ? config.stacks : getAllDepends(
|
|
1213
1462
|
// config.stacks,
|
|
1214
|
-
|
|
1463
|
+
config.stacks.filter((stack) => filters.includes(stack.name))
|
|
1215
1464
|
);
|
|
1216
1465
|
for (const stackConfig of filterdStacks) {
|
|
1217
1466
|
const { stack, bindings } = toStack({
|
|
1218
|
-
config
|
|
1467
|
+
config,
|
|
1219
1468
|
stackConfig,
|
|
1220
1469
|
assets,
|
|
1221
1470
|
plugins,
|
|
@@ -1243,63 +1492,6 @@ var toApp = async (config2, filters) => {
|
|
|
1243
1492
|
};
|
|
1244
1493
|
};
|
|
1245
1494
|
|
|
1246
|
-
// src/cli/ui/layout/basic.ts
|
|
1247
|
-
var br = () => {
|
|
1248
|
-
return "\n";
|
|
1249
|
-
};
|
|
1250
|
-
var hr = () => {
|
|
1251
|
-
return (term) => {
|
|
1252
|
-
term.out.write([
|
|
1253
|
-
style.placeholder("\u2500".repeat(term.out.width())),
|
|
1254
|
-
br()
|
|
1255
|
-
]);
|
|
1256
|
-
};
|
|
1257
|
-
};
|
|
1258
|
-
|
|
1259
|
-
// src/cli/ui/layout/logs.ts
|
|
1260
|
-
import wrapAnsi from "wrap-ansi";
|
|
1261
|
-
var previous = /* @__PURE__ */ new Date();
|
|
1262
|
-
var logs = () => {
|
|
1263
|
-
if (!process.env.VERBOSE) {
|
|
1264
|
-
return [];
|
|
1265
|
-
}
|
|
1266
|
-
const logs2 = flushDebug();
|
|
1267
|
-
return (term) => {
|
|
1268
|
-
term.out.write([
|
|
1269
|
-
hr(),
|
|
1270
|
-
br(),
|
|
1271
|
-
" ".repeat(3),
|
|
1272
|
-
style.label("Debug Logs:"),
|
|
1273
|
-
br(),
|
|
1274
|
-
br(),
|
|
1275
|
-
logs2.map((log) => {
|
|
1276
|
-
const diff = log.date.getTime() - previous.getTime();
|
|
1277
|
-
const time = `+${diff}`.padStart(8);
|
|
1278
|
-
previous = log.date;
|
|
1279
|
-
return wrapAnsi([
|
|
1280
|
-
style.attr(`${time}${style.attr.dim("ms")}`),
|
|
1281
|
-
" [ ",
|
|
1282
|
-
log.type,
|
|
1283
|
-
" ] ",
|
|
1284
|
-
log.message,
|
|
1285
|
-
br(),
|
|
1286
|
-
log.type === "error" ? br() : ""
|
|
1287
|
-
].join(""), term.out.width(), { hard: true, trim: false });
|
|
1288
|
-
}),
|
|
1289
|
-
br(),
|
|
1290
|
-
hr()
|
|
1291
|
-
]);
|
|
1292
|
-
};
|
|
1293
|
-
};
|
|
1294
|
-
|
|
1295
|
-
// src/cli/ui/layout/footer.ts
|
|
1296
|
-
var footer = () => {
|
|
1297
|
-
return [
|
|
1298
|
-
br(),
|
|
1299
|
-
logs()
|
|
1300
|
-
];
|
|
1301
|
-
};
|
|
1302
|
-
|
|
1303
1495
|
// src/config.ts
|
|
1304
1496
|
import { join as join6 } from "path";
|
|
1305
1497
|
|
|
@@ -1320,17 +1512,17 @@ var getCredentials = (profile) => {
|
|
|
1320
1512
|
};
|
|
1321
1513
|
|
|
1322
1514
|
// src/schema/app.ts
|
|
1323
|
-
import { z as
|
|
1515
|
+
import { z as z30 } from "zod";
|
|
1324
1516
|
|
|
1325
1517
|
// src/schema/stack.ts
|
|
1326
|
-
import { z as
|
|
1327
|
-
var StackSchema =
|
|
1518
|
+
import { z as z27 } from "zod";
|
|
1519
|
+
var StackSchema = z27.object({
|
|
1328
1520
|
name: ResourceIdSchema,
|
|
1329
|
-
depends:
|
|
1521
|
+
depends: z27.array(z27.lazy(() => StackSchema)).optional()
|
|
1330
1522
|
});
|
|
1331
1523
|
|
|
1332
1524
|
// src/schema/region.ts
|
|
1333
|
-
import { z as
|
|
1525
|
+
import { z as z28 } from "zod";
|
|
1334
1526
|
var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
|
|
1335
1527
|
var AF = ["af-south-1"];
|
|
1336
1528
|
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"];
|
|
@@ -1347,34 +1539,34 @@ var regions = [
|
|
|
1347
1539
|
...ME,
|
|
1348
1540
|
...SA
|
|
1349
1541
|
];
|
|
1350
|
-
var RegionSchema =
|
|
1542
|
+
var RegionSchema = z28.enum(regions);
|
|
1351
1543
|
|
|
1352
1544
|
// src/schema/plugin.ts
|
|
1353
|
-
import { z as
|
|
1354
|
-
var PluginSchema =
|
|
1355
|
-
name:
|
|
1356
|
-
schema:
|
|
1545
|
+
import { z as z29 } from "zod";
|
|
1546
|
+
var PluginSchema = z29.object({
|
|
1547
|
+
name: z29.string(),
|
|
1548
|
+
schema: z29.custom().optional(),
|
|
1357
1549
|
// depends: z.array(z.lazy(() => PluginSchema)).optional(),
|
|
1358
|
-
onBootstrap:
|
|
1359
|
-
onStack:
|
|
1360
|
-
onApp:
|
|
1550
|
+
onBootstrap: z29.function().returns(z29.any()).optional(),
|
|
1551
|
+
onStack: z29.function().returns(z29.any()).optional(),
|
|
1552
|
+
onApp: z29.function().returns(z29.void()).optional()
|
|
1361
1553
|
// bind: z.function().optional(),
|
|
1362
1554
|
});
|
|
1363
1555
|
|
|
1364
1556
|
// src/schema/app.ts
|
|
1365
|
-
var AppSchema =
|
|
1557
|
+
var AppSchema = z30.object({
|
|
1366
1558
|
name: ResourceIdSchema,
|
|
1367
1559
|
region: RegionSchema,
|
|
1368
|
-
profile:
|
|
1369
|
-
stage:
|
|
1370
|
-
defaults:
|
|
1371
|
-
stacks:
|
|
1372
|
-
plugins:
|
|
1560
|
+
profile: z30.string(),
|
|
1561
|
+
stage: z30.string().regex(/[a-z]+/).default("prod"),
|
|
1562
|
+
defaults: z30.object({}).default({}),
|
|
1563
|
+
stacks: z30.array(StackSchema).min(1),
|
|
1564
|
+
plugins: z30.array(PluginSchema).optional()
|
|
1373
1565
|
});
|
|
1374
1566
|
|
|
1375
1567
|
// src/util/import.ts
|
|
1376
1568
|
import { transformFile } from "@swc/core";
|
|
1377
|
-
import { dirname as
|
|
1569
|
+
import { dirname as dirname3, join as join5 } from "path";
|
|
1378
1570
|
import { lstat, mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
1379
1571
|
var resolveFileNameExtension = async (path) => {
|
|
1380
1572
|
const options = [
|
|
@@ -1385,7 +1577,7 @@ var resolveFileNameExtension = async (path) => {
|
|
|
1385
1577
|
"/index.js"
|
|
1386
1578
|
];
|
|
1387
1579
|
for (const option of options) {
|
|
1388
|
-
const file = path + option;
|
|
1580
|
+
const file = path.replace(/\.js$/, "") + option;
|
|
1389
1581
|
let stat;
|
|
1390
1582
|
try {
|
|
1391
1583
|
stat = await lstat(file);
|
|
@@ -1399,21 +1591,22 @@ var resolveFileNameExtension = async (path) => {
|
|
|
1399
1591
|
throw new Error(`Failed to load file: ${path}`);
|
|
1400
1592
|
};
|
|
1401
1593
|
var resolveDir = (path) => {
|
|
1402
|
-
return
|
|
1594
|
+
return dirname3(path).replace(rootDir + "/", "");
|
|
1403
1595
|
};
|
|
1404
1596
|
var importFile = async (path) => {
|
|
1405
1597
|
const load = async (file) => {
|
|
1598
|
+
debug("Load file", file);
|
|
1406
1599
|
let { code: code2 } = await transformFile(file, {
|
|
1407
1600
|
isModule: true
|
|
1408
1601
|
});
|
|
1409
|
-
const path2 =
|
|
1602
|
+
const path2 = dirname3(file);
|
|
1410
1603
|
const dir = resolveDir(file);
|
|
1411
1604
|
code2 = code2.replaceAll("__dirname", `"${dir}"`);
|
|
1412
|
-
const matches = code2.match(/import\s*{\s*[a-z0-9\_]+\s*}\s*from\s*('|")(
|
|
1605
|
+
const matches = code2.match(/(import|export)\s*{\s*[a-z0-9\_\,\s\*]+\s*}\s*from\s*('|")(\.\.?[\/a-z0-9\_\-\.]+)('|");?/ig);
|
|
1413
1606
|
if (!matches)
|
|
1414
1607
|
return code2;
|
|
1415
1608
|
await Promise.all(matches?.map(async (match) => {
|
|
1416
|
-
const parts = /('|")(
|
|
1609
|
+
const parts = /('|")(\.\.?[\/a-z0-9\_\-\.]+)('|")/ig.exec(match);
|
|
1417
1610
|
const from = parts[2];
|
|
1418
1611
|
const file2 = await resolveFileNameExtension(join5(path2, from));
|
|
1419
1612
|
const result = await load(file2);
|
|
@@ -1433,11 +1626,7 @@ var importConfig = async (options) => {
|
|
|
1433
1626
|
debug("Import config file");
|
|
1434
1627
|
const fileName = join6(process.cwd(), options.configFile || "awsless.config.ts");
|
|
1435
1628
|
const module = await importFile(fileName);
|
|
1436
|
-
const appConfig = typeof module.default === "function" ? await module.default(
|
|
1437
|
-
profile: options.profile,
|
|
1438
|
-
region: options.region,
|
|
1439
|
-
stage: options.stage
|
|
1440
|
-
}) : module.default;
|
|
1629
|
+
const appConfig = typeof module.default === "function" ? await module.default(options) : module.default;
|
|
1441
1630
|
debug("Validate config file");
|
|
1442
1631
|
const plugins = [
|
|
1443
1632
|
...defaultPlugins,
|
|
@@ -1449,19 +1638,32 @@ var importConfig = async (options) => {
|
|
|
1449
1638
|
schema2 = schema2.and(plugin.schema);
|
|
1450
1639
|
}
|
|
1451
1640
|
}
|
|
1452
|
-
const
|
|
1453
|
-
debug("Load credentials", style.info(
|
|
1454
|
-
const credentials = getCredentials(
|
|
1641
|
+
const config = await schema2.parseAsync(appConfig);
|
|
1642
|
+
debug("Load credentials", style.info(config.profile));
|
|
1643
|
+
const credentials = getCredentials(config.profile);
|
|
1455
1644
|
debug("Load AWS account ID");
|
|
1456
|
-
const account = await getAccountId(credentials,
|
|
1645
|
+
const account = await getAccountId(credentials, config.region);
|
|
1457
1646
|
debug("Account ID:", style.info(account));
|
|
1458
1647
|
return {
|
|
1459
|
-
...
|
|
1648
|
+
...config,
|
|
1460
1649
|
account,
|
|
1461
1650
|
credentials
|
|
1462
1651
|
};
|
|
1463
1652
|
};
|
|
1464
1653
|
|
|
1654
|
+
// src/cli/ui/layout/basic.ts
|
|
1655
|
+
var br = () => {
|
|
1656
|
+
return "\n";
|
|
1657
|
+
};
|
|
1658
|
+
var hr = () => {
|
|
1659
|
+
return (term) => {
|
|
1660
|
+
term.out.write([
|
|
1661
|
+
style.placeholder("\u2500".repeat(term.out.width())),
|
|
1662
|
+
br()
|
|
1663
|
+
]);
|
|
1664
|
+
};
|
|
1665
|
+
};
|
|
1666
|
+
|
|
1465
1667
|
// src/cli/ui/layout/list.ts
|
|
1466
1668
|
var list = (data) => {
|
|
1467
1669
|
const padding = 3;
|
|
@@ -1469,26 +1671,26 @@ var list = (data) => {
|
|
|
1469
1671
|
const size = Object.keys(data).reduce((total, name) => {
|
|
1470
1672
|
return name.length > total ? name.length : total;
|
|
1471
1673
|
}, 0);
|
|
1472
|
-
return
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1674
|
+
return (term) => {
|
|
1675
|
+
term.out.gap();
|
|
1676
|
+
term.out.write(Object.entries(data).map(([name, value]) => [
|
|
1677
|
+
" ".repeat(padding),
|
|
1678
|
+
style.label((name + ":").padEnd(size + gap + 1)),
|
|
1679
|
+
value,
|
|
1680
|
+
br()
|
|
1681
|
+
]));
|
|
1682
|
+
term.out.gap();
|
|
1683
|
+
};
|
|
1478
1684
|
};
|
|
1479
1685
|
|
|
1480
1686
|
// src/cli/ui/layout/header.ts
|
|
1481
|
-
var header = (
|
|
1482
|
-
return
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
Profile: config2.profile
|
|
1489
|
-
}),
|
|
1490
|
-
br()
|
|
1491
|
-
];
|
|
1687
|
+
var header = (config) => {
|
|
1688
|
+
return list({
|
|
1689
|
+
App: config.name,
|
|
1690
|
+
Stage: config.stage,
|
|
1691
|
+
Region: config.region,
|
|
1692
|
+
Profile: config.profile
|
|
1693
|
+
});
|
|
1492
1694
|
};
|
|
1493
1695
|
|
|
1494
1696
|
// src/util/timer.ts
|
|
@@ -1555,16 +1757,16 @@ var createSpinner = () => {
|
|
|
1555
1757
|
};
|
|
1556
1758
|
|
|
1557
1759
|
// src/cli/ui/layout/dialog.ts
|
|
1558
|
-
import
|
|
1760
|
+
import wrapAnsi from "wrap-ansi";
|
|
1559
1761
|
var dialog = (type, lines) => {
|
|
1560
1762
|
const padding = 3;
|
|
1561
1763
|
const icon = style[type](symbol[type].padEnd(padding));
|
|
1562
1764
|
return (term) => {
|
|
1563
1765
|
term.out.write(lines.map((line, i) => {
|
|
1564
1766
|
if (i === 0) {
|
|
1565
|
-
return icon +
|
|
1767
|
+
return icon + wrapAnsi(line, term.out.width(), { hard: true });
|
|
1566
1768
|
}
|
|
1567
|
-
return
|
|
1769
|
+
return wrapAnsi(" ".repeat(padding) + line, term.out.width(), { hard: true });
|
|
1568
1770
|
}).join(br()) + br());
|
|
1569
1771
|
};
|
|
1570
1772
|
};
|
|
@@ -1706,6 +1908,7 @@ var Renderer = class {
|
|
|
1706
1908
|
fragments = [];
|
|
1707
1909
|
unsubs = [];
|
|
1708
1910
|
timeout;
|
|
1911
|
+
flushing = false;
|
|
1709
1912
|
screen = [];
|
|
1710
1913
|
width() {
|
|
1711
1914
|
return this.output.columns;
|
|
@@ -1725,14 +1928,58 @@ var Renderer = class {
|
|
|
1725
1928
|
this.update();
|
|
1726
1929
|
return fragment;
|
|
1727
1930
|
}
|
|
1931
|
+
gap() {
|
|
1932
|
+
const walk = (fragment) => {
|
|
1933
|
+
if (typeof fragment === "string") {
|
|
1934
|
+
return fragment;
|
|
1935
|
+
}
|
|
1936
|
+
if (Array.isArray(fragment)) {
|
|
1937
|
+
return fragment.map(walk).join("");
|
|
1938
|
+
}
|
|
1939
|
+
return walk(fragment.get());
|
|
1940
|
+
};
|
|
1941
|
+
const end = walk(this.fragments.slice(-2));
|
|
1942
|
+
if (end.endsWith("\n\n")) {
|
|
1943
|
+
} else if (end.endsWith("\n")) {
|
|
1944
|
+
this.fragments.push("\n");
|
|
1945
|
+
} else {
|
|
1946
|
+
this.fragments.push("\n\n");
|
|
1947
|
+
}
|
|
1948
|
+
this.update();
|
|
1949
|
+
}
|
|
1728
1950
|
update() {
|
|
1729
1951
|
clearTimeout(this.timeout);
|
|
1730
1952
|
this.timeout = setTimeout(() => {
|
|
1731
1953
|
this.flush();
|
|
1732
1954
|
}, 0);
|
|
1733
1955
|
}
|
|
1734
|
-
|
|
1956
|
+
async end() {
|
|
1957
|
+
this.gap();
|
|
1958
|
+
await this.flush();
|
|
1959
|
+
const y = this.screen.length - 1;
|
|
1960
|
+
await this.setCursor(0, y);
|
|
1961
|
+
}
|
|
1962
|
+
setCursor(x, y) {
|
|
1963
|
+
return new Promise((resolve) => {
|
|
1964
|
+
this.output.cursorTo?.(x, y, () => resolve(void 0));
|
|
1965
|
+
});
|
|
1966
|
+
}
|
|
1967
|
+
writeString(value) {
|
|
1968
|
+
return new Promise((resolve) => {
|
|
1969
|
+
this.output.write?.(value, () => resolve(void 0));
|
|
1970
|
+
});
|
|
1971
|
+
}
|
|
1972
|
+
clearLine() {
|
|
1973
|
+
return new Promise((resolve) => {
|
|
1974
|
+
this.output.clearLine?.(1, () => resolve(void 0));
|
|
1975
|
+
});
|
|
1976
|
+
}
|
|
1977
|
+
async flush() {
|
|
1735
1978
|
clearTimeout(this.timeout);
|
|
1979
|
+
if (this.flushing) {
|
|
1980
|
+
this.update();
|
|
1981
|
+
return;
|
|
1982
|
+
}
|
|
1736
1983
|
const walk = (fragment) => {
|
|
1737
1984
|
if (typeof fragment === "string") {
|
|
1738
1985
|
return fragment;
|
|
@@ -1748,34 +1995,40 @@ var Renderer = class {
|
|
|
1748
1995
|
this.unsubs.forEach((unsub) => unsub());
|
|
1749
1996
|
this.unsubs = [];
|
|
1750
1997
|
const screen = walk(this.fragments).split("\n");
|
|
1998
|
+
const height = this.height();
|
|
1751
1999
|
const oldSize = this.screen.length;
|
|
1752
2000
|
const newSize = screen.length;
|
|
1753
2001
|
const size = Math.max(oldSize, newSize);
|
|
1754
|
-
const height = this.height();
|
|
1755
2002
|
const start = Math.max(oldSize - height, 0);
|
|
2003
|
+
this.flushing = true;
|
|
1756
2004
|
for (let y = start; y < size; y++) {
|
|
1757
|
-
const
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
2005
|
+
const newLine = screen[y];
|
|
2006
|
+
const oldLine = this.screen[y];
|
|
2007
|
+
if (newLine !== oldLine) {
|
|
2008
|
+
if (y >= oldSize && y !== 0) {
|
|
2009
|
+
const p = y - start - 1;
|
|
2010
|
+
const x = screen[y - 1]?.length || 0;
|
|
2011
|
+
await this.setCursor(x, p);
|
|
2012
|
+
await this.writeString("\n" + newLine);
|
|
1763
2013
|
} else {
|
|
1764
|
-
this.
|
|
1765
|
-
this.
|
|
2014
|
+
await this.setCursor(0, y - start);
|
|
2015
|
+
await this.writeString(newLine);
|
|
2016
|
+
await this.clearLine();
|
|
1766
2017
|
}
|
|
1767
|
-
this.output.clearLine?.(1);
|
|
1768
2018
|
}
|
|
1769
2019
|
}
|
|
1770
2020
|
this.screen = screen;
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
2021
|
+
this.flushing = false;
|
|
2022
|
+
}
|
|
2023
|
+
async clear() {
|
|
2024
|
+
await this.setCursor(0, 0);
|
|
2025
|
+
await this.writeString("\n".repeat(this.height()));
|
|
2026
|
+
await this.setCursor(0, 0);
|
|
2027
|
+
if (this.output.clearScreenDown) {
|
|
2028
|
+
await new Promise((resolve) => {
|
|
2029
|
+
this.output.clearScreenDown(() => resolve(void 0));
|
|
2030
|
+
});
|
|
1776
2031
|
}
|
|
1777
|
-
this.output.cursorTo?.(0, 0);
|
|
1778
|
-
this.output.clearScreenDown?.();
|
|
1779
2032
|
}
|
|
1780
2033
|
};
|
|
1781
2034
|
|
|
@@ -1791,22 +2044,62 @@ var logo = () => {
|
|
|
1791
2044
|
return [
|
|
1792
2045
|
style.warning("\u26A1\uFE0F "),
|
|
1793
2046
|
style.primary("AWS"),
|
|
1794
|
-
style.primary.dim("LESS")
|
|
1795
|
-
br()
|
|
2047
|
+
style.primary.dim("LESS")
|
|
1796
2048
|
];
|
|
1797
2049
|
};
|
|
1798
2050
|
|
|
2051
|
+
// src/cli/ui/layout/logs.ts
|
|
2052
|
+
import wrapAnsi2 from "wrap-ansi";
|
|
2053
|
+
var previous = /* @__PURE__ */ new Date();
|
|
2054
|
+
var logs = () => {
|
|
2055
|
+
if (!process.env.VERBOSE) {
|
|
2056
|
+
return [];
|
|
2057
|
+
}
|
|
2058
|
+
const logs2 = flushDebug();
|
|
2059
|
+
return (term) => {
|
|
2060
|
+
term.out.gap();
|
|
2061
|
+
term.out.write([
|
|
2062
|
+
hr(),
|
|
2063
|
+
br(),
|
|
2064
|
+
" ".repeat(3),
|
|
2065
|
+
style.label("Debug Logs:"),
|
|
2066
|
+
br(),
|
|
2067
|
+
br(),
|
|
2068
|
+
logs2.map((log) => {
|
|
2069
|
+
const diff = log.date.getTime() - previous.getTime();
|
|
2070
|
+
const time = `+${diff}`.padStart(8);
|
|
2071
|
+
previous = log.date;
|
|
2072
|
+
return wrapAnsi2([
|
|
2073
|
+
style.attr(`${time}${style.attr.dim("ms")}`),
|
|
2074
|
+
" [ ",
|
|
2075
|
+
log.type,
|
|
2076
|
+
" ] ",
|
|
2077
|
+
log.message,
|
|
2078
|
+
br(),
|
|
2079
|
+
log.type === "error" ? br() : ""
|
|
2080
|
+
].join(""), term.out.width(), { hard: true, trim: false });
|
|
2081
|
+
}),
|
|
2082
|
+
br(),
|
|
2083
|
+
hr()
|
|
2084
|
+
]);
|
|
2085
|
+
};
|
|
2086
|
+
};
|
|
2087
|
+
|
|
1799
2088
|
// src/cli/ui/layout/layout.ts
|
|
1800
2089
|
var layout = async (cb) => {
|
|
1801
2090
|
const term = createTerminal();
|
|
1802
|
-
term.out.clear();
|
|
2091
|
+
await term.out.clear();
|
|
2092
|
+
term.out.write(br());
|
|
1803
2093
|
term.out.write(logo());
|
|
2094
|
+
term.out.gap();
|
|
1804
2095
|
try {
|
|
1805
2096
|
const options = program.optsWithGlobals();
|
|
1806
|
-
const
|
|
1807
|
-
term.out.write(header(
|
|
1808
|
-
|
|
2097
|
+
const config = await importConfig(options);
|
|
2098
|
+
term.out.write(header(config));
|
|
2099
|
+
term.out.gap();
|
|
2100
|
+
await cb(config, term.out.write.bind(term.out), term);
|
|
1809
2101
|
} catch (error) {
|
|
2102
|
+
term.out.gap();
|
|
1810
2103
|
if (error instanceof Error) {
|
|
1811
2104
|
term.out.write(dialog("error", [error.message]));
|
|
1812
2105
|
} else if (typeof error === "string") {
|
|
@@ -1817,7 +2110,9 @@ var layout = async (cb) => {
|
|
|
1817
2110
|
debugError(error);
|
|
1818
2111
|
} finally {
|
|
1819
2112
|
debug("Exit");
|
|
1820
|
-
term.out.
|
|
2113
|
+
term.out.gap();
|
|
2114
|
+
term.out.write(logs());
|
|
2115
|
+
await term.out.end();
|
|
1821
2116
|
term.in.unref();
|
|
1822
2117
|
setTimeout(() => {
|
|
1823
2118
|
process.exit(0);
|
|
@@ -1849,7 +2144,8 @@ var flexLine = (term, left, right, reserveSpace = 0) => {
|
|
|
1849
2144
|
var assetBuilder = (assets) => {
|
|
1850
2145
|
return async (term) => {
|
|
1851
2146
|
const done = term.out.write(loadingDialog("Building stack assets..."));
|
|
1852
|
-
const groups = new Signal([
|
|
2147
|
+
const groups = new Signal([""]);
|
|
2148
|
+
term.out.gap();
|
|
1853
2149
|
term.out.write(groups);
|
|
1854
2150
|
const stackNameSize = Math.max(...Object.keys(assets.list()).map((stack) => stack.length));
|
|
1855
2151
|
const resourceSize = Math.max(...Object.values(assets.list()).map((assets2) => assets2.map((asset) => asset.resource.length)).flat());
|
|
@@ -1895,6 +2191,7 @@ var assetBuilder = (assets) => {
|
|
|
1895
2191
|
}));
|
|
1896
2192
|
}));
|
|
1897
2193
|
done("Done building stack assets");
|
|
2194
|
+
term.out.gap();
|
|
1898
2195
|
};
|
|
1899
2196
|
};
|
|
1900
2197
|
|
|
@@ -1920,8 +2217,8 @@ var cleanUp = async () => {
|
|
|
1920
2217
|
// src/cli/command/build.ts
|
|
1921
2218
|
var build = (program2) => {
|
|
1922
2219
|
program2.command("build").argument("[stack...]", "Optionally filter stacks to build").description("Build your app").action(async (filters) => {
|
|
1923
|
-
await layout(async (
|
|
1924
|
-
const { app, assets } = await toApp(
|
|
2220
|
+
await layout(async (config, write) => {
|
|
2221
|
+
const { app, assets } = await toApp(config, filters);
|
|
1925
2222
|
await cleanUp();
|
|
1926
2223
|
await write(assetBuilder(assets));
|
|
1927
2224
|
app.synth();
|
|
@@ -1934,11 +2231,11 @@ import { CloudFormationClient, CreateStackCommand, DeleteStackCommand, DescribeS
|
|
|
1934
2231
|
import { S3Client as S3Client2, PutObjectCommand as PutObjectCommand2, ObjectCannedACL as ObjectCannedACL2, StorageClass as StorageClass2 } from "@aws-sdk/client-s3";
|
|
1935
2232
|
var StackClient = class {
|
|
1936
2233
|
// 30 seconds
|
|
1937
|
-
constructor(
|
|
1938
|
-
this.config =
|
|
2234
|
+
constructor(config) {
|
|
2235
|
+
this.config = config;
|
|
1939
2236
|
this.client = new CloudFormationClient({
|
|
1940
|
-
credentials:
|
|
1941
|
-
region:
|
|
2237
|
+
credentials: config.credentials,
|
|
2238
|
+
region: config.region
|
|
1942
2239
|
});
|
|
1943
2240
|
}
|
|
1944
2241
|
client;
|
|
@@ -2167,12 +2464,12 @@ var confirmPrompt = (label, options = {}) => {
|
|
|
2167
2464
|
};
|
|
2168
2465
|
|
|
2169
2466
|
// src/cli/ui/complex/bootstrap.ts
|
|
2170
|
-
var bootstrapDeployer = (
|
|
2467
|
+
var bootstrapDeployer = (config) => {
|
|
2171
2468
|
return async (term) => {
|
|
2172
2469
|
debug("Initializing bootstrap");
|
|
2173
|
-
const app = makeApp(
|
|
2174
|
-
const client = new StackClient(
|
|
2175
|
-
const bootstrap2 = bootstrapStack(
|
|
2470
|
+
const app = makeApp(config);
|
|
2471
|
+
const client = new StackClient(config);
|
|
2472
|
+
const bootstrap2 = bootstrapStack(config, app);
|
|
2176
2473
|
const shouldDeploy = await shouldDeployBootstrap(client, bootstrap2.stackName);
|
|
2177
2474
|
if (shouldDeploy) {
|
|
2178
2475
|
term.out.write(dialog("warning", [`Your app hasn't been bootstrapped yet`]));
|
|
@@ -2196,8 +2493,8 @@ var bootstrapDeployer = (config2) => {
|
|
|
2196
2493
|
// src/cli/command/bootstrap.ts
|
|
2197
2494
|
var bootstrap = (program2) => {
|
|
2198
2495
|
program2.command("bootstrap").description("Create the awsless bootstrap stack").action(async () => {
|
|
2199
|
-
await layout(async (
|
|
2200
|
-
await write(bootstrapDeployer(
|
|
2496
|
+
await layout(async (config, write) => {
|
|
2497
|
+
await write(bootstrapDeployer(config));
|
|
2201
2498
|
});
|
|
2202
2499
|
});
|
|
2203
2500
|
};
|
|
@@ -2234,29 +2531,28 @@ var stackTree = (nodes, statuses) => {
|
|
|
2234
2531
|
render(node.children, deep + 1, [...parents, more]);
|
|
2235
2532
|
});
|
|
2236
2533
|
};
|
|
2534
|
+
term.out.gap();
|
|
2237
2535
|
render(nodes);
|
|
2536
|
+
term.out.gap();
|
|
2238
2537
|
};
|
|
2239
2538
|
};
|
|
2240
2539
|
|
|
2241
2540
|
// src/cli/command/status.ts
|
|
2242
2541
|
var status = (program2) => {
|
|
2243
2542
|
program2.command("status").argument("[stacks...]", "Optionally filter stacks to lookup status").description("View the application status").action(async (filters) => {
|
|
2244
|
-
await layout(async (
|
|
2245
|
-
const { app, assets, dependencyTree } = await toApp(
|
|
2543
|
+
await layout(async (config, write) => {
|
|
2544
|
+
const { app, assets, dependencyTree } = await toApp(config, filters);
|
|
2246
2545
|
await cleanUp();
|
|
2247
2546
|
await write(assetBuilder(assets));
|
|
2248
|
-
write(br());
|
|
2249
2547
|
const assembly = app.synth();
|
|
2250
2548
|
const doneLoading = write(loadingDialog("Loading stack information..."));
|
|
2251
|
-
const client = new StackClient(
|
|
2549
|
+
const client = new StackClient(config);
|
|
2252
2550
|
const statuses = [];
|
|
2253
2551
|
const stackStatuses = {};
|
|
2254
2552
|
assembly.stacks.forEach((stack) => {
|
|
2255
2553
|
stackStatuses[stack.id] = new Signal(style.info("Loading..."));
|
|
2256
2554
|
});
|
|
2257
|
-
write(br());
|
|
2258
2555
|
write(stackTree(dependencyTree, stackStatuses));
|
|
2259
|
-
write(br());
|
|
2260
2556
|
debug("Load metadata for all deployed stacks on AWS");
|
|
2261
2557
|
await Promise.all(assembly.stacks.map(async (stack, i) => {
|
|
2262
2558
|
const info = await client.get(stack.stackName);
|
|
@@ -2288,9 +2584,9 @@ var status = (program2) => {
|
|
|
2288
2584
|
// src/cli/command/deploy.ts
|
|
2289
2585
|
var deploy = (program2) => {
|
|
2290
2586
|
program2.command("deploy").argument("[stacks...]", "Optionally filter stacks to deploy").description("Deploy your app to AWS").action(async (filters) => {
|
|
2291
|
-
await layout(async (
|
|
2292
|
-
await write(bootstrapDeployer(
|
|
2293
|
-
const { app, stackNames, assets, dependencyTree } = await toApp(
|
|
2587
|
+
await layout(async (config, write) => {
|
|
2588
|
+
await write(bootstrapDeployer(config));
|
|
2589
|
+
const { app, stackNames, assets, dependencyTree } = await toApp(config, filters);
|
|
2294
2590
|
const formattedFilter = stackNames.map((i) => style.info(i)).join(style.placeholder(", "));
|
|
2295
2591
|
debug("Stacks to deploy", formattedFilter);
|
|
2296
2592
|
const deployAll = filters.length === 0;
|
|
@@ -2301,8 +2597,6 @@ var deploy = (program2) => {
|
|
|
2301
2597
|
}
|
|
2302
2598
|
await cleanUp();
|
|
2303
2599
|
await write(assetBuilder(assets));
|
|
2304
|
-
write(br());
|
|
2305
|
-
write(br());
|
|
2306
2600
|
const donePublishing = write(loadingDialog("Publishing stack assets to AWS..."));
|
|
2307
2601
|
await Promise.all(assets.map(async (_, assets2) => {
|
|
2308
2602
|
await Promise.all(assets2.map(async (asset) => {
|
|
@@ -2316,10 +2610,8 @@ var deploy = (program2) => {
|
|
|
2316
2610
|
statuses[stack.id] = new Signal(style.info("waiting"));
|
|
2317
2611
|
});
|
|
2318
2612
|
const doneDeploying = write(loadingDialog("Deploying stacks to AWS..."));
|
|
2319
|
-
write(br());
|
|
2320
2613
|
write(stackTree(dependencyTree, statuses));
|
|
2321
|
-
|
|
2322
|
-
const client = new StackClient(config2);
|
|
2614
|
+
const client = new StackClient(config);
|
|
2323
2615
|
const deploymentLine = createDeploymentLine(dependencyTree);
|
|
2324
2616
|
for (const stacks of deploymentLine) {
|
|
2325
2617
|
const results = await Promise.allSettled(stacks.map(async (stack) => {
|
|
@@ -2408,36 +2700,34 @@ var textPrompt = (label, options = {}) => {
|
|
|
2408
2700
|
};
|
|
2409
2701
|
};
|
|
2410
2702
|
|
|
2411
|
-
// src/cli/command/
|
|
2703
|
+
// src/cli/command/secrets/set.ts
|
|
2412
2704
|
var set = (program2) => {
|
|
2413
|
-
program2.command("set <name>").description("Set a
|
|
2414
|
-
await layout(async (
|
|
2415
|
-
const params = new Params(
|
|
2705
|
+
program2.command("set <name>").description("Set a secret value").action(async (name) => {
|
|
2706
|
+
await layout(async (config, write) => {
|
|
2707
|
+
const params = new Params(config);
|
|
2416
2708
|
write(list({
|
|
2417
|
-
"Set
|
|
2709
|
+
"Set secret parameter": style.info(name)
|
|
2418
2710
|
}));
|
|
2419
|
-
write(
|
|
2420
|
-
const value = await write(textPrompt("Enter config value"));
|
|
2711
|
+
const value = await write(textPrompt("Enter secret value"));
|
|
2421
2712
|
if (value === "") {
|
|
2422
|
-
write(dialog("error", [`Provided
|
|
2713
|
+
write(dialog("error", [`Provided secret value can't be empty`]));
|
|
2423
2714
|
} else {
|
|
2424
|
-
const done = write(loadingDialog(`Saving remote
|
|
2715
|
+
const done = write(loadingDialog(`Saving remote secret parameter`));
|
|
2425
2716
|
await params.set(name, value);
|
|
2426
|
-
done(`Done saving remote
|
|
2717
|
+
done(`Done saving remote secret parameter`);
|
|
2427
2718
|
}
|
|
2428
2719
|
});
|
|
2429
2720
|
});
|
|
2430
2721
|
};
|
|
2431
2722
|
|
|
2432
|
-
// src/cli/command/
|
|
2723
|
+
// src/cli/command/secrets/get.ts
|
|
2433
2724
|
var get = (program2) => {
|
|
2434
|
-
program2.command("get <name>").description("Get a
|
|
2435
|
-
await layout(async (
|
|
2436
|
-
const params = new Params(
|
|
2437
|
-
const done = write(loadingDialog(`Getting remote
|
|
2725
|
+
program2.command("get <name>").description("Get a secret value").action(async (name) => {
|
|
2726
|
+
await layout(async (config, write) => {
|
|
2727
|
+
const params = new Params(config);
|
|
2728
|
+
const done = write(loadingDialog(`Getting remote secret parameter`));
|
|
2438
2729
|
const value = await params.get(name);
|
|
2439
|
-
done(`Done getting remote
|
|
2440
|
-
write(br());
|
|
2730
|
+
done(`Done getting remote secret parameter`);
|
|
2441
2731
|
write(list({
|
|
2442
2732
|
Name: name,
|
|
2443
2733
|
Value: value || style.error("(empty)")
|
|
@@ -2446,21 +2736,20 @@ var get = (program2) => {
|
|
|
2446
2736
|
});
|
|
2447
2737
|
};
|
|
2448
2738
|
|
|
2449
|
-
// src/cli/command/
|
|
2739
|
+
// src/cli/command/secrets/delete.ts
|
|
2450
2740
|
var del = (program2) => {
|
|
2451
|
-
program2.command("delete <name>").description("Delete a
|
|
2452
|
-
await layout(async (
|
|
2453
|
-
const params = new Params(
|
|
2454
|
-
write(dialog("warning", [`Your deleting the ${style.info(name)}
|
|
2741
|
+
program2.command("delete <name>").description("Delete a secret value").action(async (name) => {
|
|
2742
|
+
await layout(async (config, write) => {
|
|
2743
|
+
const params = new Params(config);
|
|
2744
|
+
write(dialog("warning", [`Your deleting the ${style.info(name)} secret parameter`]));
|
|
2455
2745
|
const confirm = await write(confirmPrompt("Are you sure?"));
|
|
2456
2746
|
if (!confirm) {
|
|
2457
2747
|
throw new Cancelled();
|
|
2458
2748
|
}
|
|
2459
|
-
const done = write(loadingDialog(`Deleting remote
|
|
2749
|
+
const done = write(loadingDialog(`Deleting remote secret parameter`));
|
|
2460
2750
|
const value = await params.get(name);
|
|
2461
2751
|
await params.delete(name);
|
|
2462
|
-
done(`Done deleting remote
|
|
2463
|
-
write(br());
|
|
2752
|
+
done(`Done deleting remote secret parameter`);
|
|
2464
2753
|
write(list({
|
|
2465
2754
|
Name: name,
|
|
2466
2755
|
Value: value || style.error("(empty)")
|
|
@@ -2469,45 +2758,47 @@ var del = (program2) => {
|
|
|
2469
2758
|
});
|
|
2470
2759
|
};
|
|
2471
2760
|
|
|
2472
|
-
// src/cli/command/
|
|
2761
|
+
// src/cli/command/secrets/list.ts
|
|
2473
2762
|
var list2 = (program2) => {
|
|
2474
|
-
program2.command("list").description(`List all
|
|
2475
|
-
await layout(async (
|
|
2476
|
-
const params = new Params(
|
|
2477
|
-
const done = write(loadingDialog("Loading
|
|
2763
|
+
program2.command("list").description(`List all secret value's`).action(async () => {
|
|
2764
|
+
await layout(async (config, write) => {
|
|
2765
|
+
const params = new Params(config);
|
|
2766
|
+
const done = write(loadingDialog("Loading secret parameters..."));
|
|
2478
2767
|
const values = await params.list();
|
|
2479
|
-
done("Done loading
|
|
2768
|
+
done("Done loading secret values");
|
|
2480
2769
|
if (Object.keys(values).length > 0) {
|
|
2481
|
-
write(br());
|
|
2482
2770
|
write(list(values));
|
|
2483
2771
|
} else {
|
|
2484
|
-
write(dialog("warning", ["No
|
|
2772
|
+
write(dialog("warning", ["No secret parameters found"]));
|
|
2485
2773
|
}
|
|
2486
2774
|
});
|
|
2487
2775
|
});
|
|
2488
2776
|
};
|
|
2489
2777
|
|
|
2490
|
-
// src/cli/command/
|
|
2778
|
+
// src/cli/command/secrets/index.ts
|
|
2491
2779
|
var commands = [
|
|
2492
2780
|
set,
|
|
2493
2781
|
get,
|
|
2494
2782
|
del,
|
|
2495
2783
|
list2
|
|
2496
2784
|
];
|
|
2497
|
-
var
|
|
2498
|
-
const command = program2.command("
|
|
2785
|
+
var secrets = (program2) => {
|
|
2786
|
+
const command = program2.command("secrets").description(`Manage app secrets`);
|
|
2499
2787
|
commands.forEach((cb) => cb(command));
|
|
2500
2788
|
};
|
|
2501
2789
|
|
|
2502
2790
|
// src/cli/program.ts
|
|
2503
2791
|
var program = new Command();
|
|
2504
|
-
program.name("
|
|
2792
|
+
program.name(logo().join("").replace(/\s+/, ""));
|
|
2505
2793
|
program.option("--config-file <string>", "The config file location");
|
|
2506
2794
|
program.option("--stage <string>", "The stage to use, defaults to prod stage", "prod");
|
|
2507
2795
|
program.option("--profile <string>", "The AWS profile to use");
|
|
2508
2796
|
program.option("--region <string>", "The AWS region to use");
|
|
2509
2797
|
program.option("-m --mute", "Mute sound effects");
|
|
2510
2798
|
program.option("-v --verbose", "Print verbose logs");
|
|
2799
|
+
program.exitOverride(() => {
|
|
2800
|
+
process.exit(0);
|
|
2801
|
+
});
|
|
2511
2802
|
program.on("option:verbose", () => {
|
|
2512
2803
|
process.env.VERBOSE = program.opts().verbose ? "1" : void 0;
|
|
2513
2804
|
});
|
|
@@ -2516,13 +2807,11 @@ var commands2 = [
|
|
|
2516
2807
|
status,
|
|
2517
2808
|
build,
|
|
2518
2809
|
deploy,
|
|
2519
|
-
|
|
2810
|
+
secrets
|
|
2520
2811
|
// diff,
|
|
2521
2812
|
// remove,
|
|
2522
|
-
// test,
|
|
2523
|
-
// test2,
|
|
2524
2813
|
];
|
|
2525
|
-
commands2.forEach((
|
|
2814
|
+
commands2.forEach((fn) => fn(program));
|
|
2526
2815
|
|
|
2527
2816
|
// src/bin.ts
|
|
2528
2817
|
program.parse(process.argv);
|