@awsless/awsless 0.0.8 → 0.0.9
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 +300 -168
- package/dist/bin.js +289 -158
- package/dist/chunk-PFTL6L4F.js +6 -0
- package/dist/index.cjs +33 -2
- package/dist/index.d.ts +395 -11
- package/dist/index.js +28 -2
- package/package.json +3 -1
- package/dist/chunk-6KILQ5DR.js +0 -15
package/dist/bin.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
__require,
|
|
4
3
|
definePlugin
|
|
5
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PFTL6L4F.js";
|
|
6
5
|
|
|
7
6
|
// src/cli/program.ts
|
|
8
7
|
import { Command } from "commander";
|
|
@@ -196,6 +195,8 @@ var toStack = ({ config: config2, assets, app, stackConfig, plugins }) => {
|
|
|
196
195
|
functions.forEach((lambda) => lambda.addToRolePolicy(allowConfigParameters));
|
|
197
196
|
return {
|
|
198
197
|
stack,
|
|
198
|
+
functions,
|
|
199
|
+
bindings,
|
|
199
200
|
depends: stackConfig.depends
|
|
200
201
|
};
|
|
201
202
|
};
|
|
@@ -205,7 +206,8 @@ import { join } from "path";
|
|
|
205
206
|
var rootDir = process.cwd();
|
|
206
207
|
var outDir = join(rootDir, ".awsless");
|
|
207
208
|
var assemblyDir = join(outDir, "assembly");
|
|
208
|
-
var
|
|
209
|
+
var assetDir = join(outDir, "asset");
|
|
210
|
+
var cacheDir = join(outDir, "cache");
|
|
209
211
|
|
|
210
212
|
// src/stack/app-bootstrap.ts
|
|
211
213
|
import { Stack as Stack3 } from "aws-cdk-lib";
|
|
@@ -250,7 +252,7 @@ var ScheduleExpressionSchema = RateExpressionSchema.or(CronExpressionSchema);
|
|
|
250
252
|
import { Rule } from "aws-cdk-lib/aws-events";
|
|
251
253
|
|
|
252
254
|
// src/util/resource.ts
|
|
253
|
-
import {
|
|
255
|
+
import { paramCase, pascalCase } from "change-case";
|
|
254
256
|
var toId = (resource, id) => {
|
|
255
257
|
return pascalCase(`${resource}-${id}`);
|
|
256
258
|
};
|
|
@@ -258,7 +260,7 @@ var toName = (stack, id) => {
|
|
|
258
260
|
return paramCase(`${stack.stackName}-${id}`);
|
|
259
261
|
};
|
|
260
262
|
var toEnvKey = (resource, id) => {
|
|
261
|
-
return
|
|
263
|
+
return `RESOURCE_${resource.toUpperCase()}_${id}`;
|
|
262
264
|
};
|
|
263
265
|
var addResourceEnvironment = (stack, resource, id, lambda) => {
|
|
264
266
|
const key = toEnvKey(resource, id);
|
|
@@ -357,75 +359,53 @@ var SizeSchema = z7.custom((value) => {
|
|
|
357
359
|
return z7.string().regex(/[0-9]+ (KB|MB|GB)/).safeParse(value).success;
|
|
358
360
|
}, "Invalid size").transform(toSize);
|
|
359
361
|
|
|
360
|
-
// src/plugins/function/util/
|
|
361
|
-
import {
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
import {
|
|
365
|
-
import { createHash } from "crypto";
|
|
366
|
-
import { parentPort, workerData } from "worker_threads";
|
|
367
|
-
`;
|
|
368
|
-
var importCJS = `
|
|
369
|
-
const { bundle } = require("@awsless/code");
|
|
370
|
-
const { createHash } = require("crypto");
|
|
371
|
-
const { parentPort, workerData } = require("worker_threads");
|
|
372
|
-
`;
|
|
373
|
-
var workerCode = `
|
|
374
|
-
${cjs ? importCJS : importESM}
|
|
375
|
-
|
|
376
|
-
const build = async (file) => {
|
|
377
|
-
const { code, map } = await bundle(file, {
|
|
378
|
-
format: 'esm',
|
|
379
|
-
sourceMap: true,
|
|
380
|
-
minimize: true,
|
|
381
|
-
onwarn: () => {},
|
|
382
|
-
moduleSideEffects: (id) => file === id,
|
|
383
|
-
external: (importee) => (
|
|
384
|
-
importee.startsWith('aws-sdk') ||
|
|
385
|
-
importee.startsWith('@aws-sdk')
|
|
386
|
-
),
|
|
387
|
-
})
|
|
388
|
-
|
|
389
|
-
const hash = createHash('sha1').update(code).digest('hex')
|
|
390
|
-
|
|
391
|
-
parentPort.postMessage(JSON.stringify({
|
|
392
|
-
handler: 'index.default',
|
|
393
|
-
hash,
|
|
394
|
-
files: [
|
|
395
|
-
{ name: 'index.js', code, map: map?.toString() }
|
|
396
|
-
]
|
|
397
|
-
}))
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
build(workerData)
|
|
401
|
-
`;
|
|
362
|
+
// src/plugins/function/util/esbuild.ts
|
|
363
|
+
import { build } from "esbuild";
|
|
364
|
+
import { createHash, randomUUID } from "crypto";
|
|
365
|
+
import { join as join2 } from "path";
|
|
366
|
+
import { readFile, rm } from "fs/promises";
|
|
402
367
|
var defaultBuild = async (file) => {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
});
|
|
368
|
+
const random = randomUUID();
|
|
369
|
+
const codeFile = join2(cacheDir, `${random}.mjs`);
|
|
370
|
+
const mapFile = join2(cacheDir, `${random}.mjs.map`);
|
|
371
|
+
await build({
|
|
372
|
+
entryPoints: [file],
|
|
373
|
+
minify: true,
|
|
374
|
+
bundle: true,
|
|
375
|
+
external: [
|
|
376
|
+
"@aws-sdk/*",
|
|
377
|
+
"@aws-sdk",
|
|
378
|
+
"aws-sdk"
|
|
379
|
+
],
|
|
380
|
+
sourcemap: "external",
|
|
381
|
+
target: "esnext",
|
|
382
|
+
treeShaking: true,
|
|
383
|
+
// jsxSideEffects:
|
|
384
|
+
format: "esm",
|
|
385
|
+
platform: "node",
|
|
386
|
+
outfile: codeFile
|
|
423
387
|
});
|
|
388
|
+
const code = await readFile(codeFile, "utf8");
|
|
389
|
+
const map = await readFile(mapFile, "utf8");
|
|
390
|
+
await rm(codeFile);
|
|
391
|
+
await rm(mapFile);
|
|
392
|
+
const hash = createHash("sha1").update(code).digest("hex");
|
|
393
|
+
return {
|
|
394
|
+
handler: "index.default",
|
|
395
|
+
hash,
|
|
396
|
+
files: [
|
|
397
|
+
{
|
|
398
|
+
name: "index.mjs",
|
|
399
|
+
code,
|
|
400
|
+
map
|
|
401
|
+
}
|
|
402
|
+
]
|
|
403
|
+
};
|
|
424
404
|
};
|
|
425
405
|
|
|
426
406
|
// src/plugins/function/util/build.ts
|
|
427
407
|
import JSZip from "jszip";
|
|
428
|
-
import { basename, join as
|
|
408
|
+
import { basename, join as join3 } from "path";
|
|
429
409
|
import { mkdir, writeFile } from "fs/promises";
|
|
430
410
|
import { filesize } from "filesize";
|
|
431
411
|
var zipFiles = (files) => {
|
|
@@ -442,24 +422,24 @@ var zipFiles = (files) => {
|
|
|
442
422
|
});
|
|
443
423
|
};
|
|
444
424
|
var writeBuildHash = async (config2, stack, id, hash) => {
|
|
445
|
-
const funcPath =
|
|
446
|
-
const versionFile =
|
|
425
|
+
const funcPath = join3(assetDir, "function", config2.name, stack.artifactId, id);
|
|
426
|
+
const versionFile = join3(funcPath, "HASH");
|
|
447
427
|
await writeFile(versionFile, hash);
|
|
448
428
|
};
|
|
449
429
|
var writeBuildFiles = async (config2, stack, id, files) => {
|
|
450
430
|
const bundle = await zipFiles(files);
|
|
451
|
-
const funcPath =
|
|
452
|
-
const filesPath =
|
|
453
|
-
const bundleFile =
|
|
454
|
-
debug("Bundle size of", style.info(
|
|
431
|
+
const funcPath = join3(assetDir, "function", config2.name, stack.artifactId, id);
|
|
432
|
+
const filesPath = join3(funcPath, "files");
|
|
433
|
+
const bundleFile = join3(funcPath, "bundle.zip");
|
|
434
|
+
debug("Bundle size of", style.info(join3(config2.name, stack.artifactId, id)), "is", style.attr(filesize(bundle.byteLength)));
|
|
455
435
|
await mkdir(filesPath, { recursive: true });
|
|
456
436
|
await writeFile(bundleFile, bundle);
|
|
457
437
|
await Promise.all(files.map(async (file) => {
|
|
458
|
-
const fileName =
|
|
438
|
+
const fileName = join3(filesPath, file.name);
|
|
459
439
|
await mkdir(basename(fileName), { recursive: true });
|
|
460
440
|
await writeFile(fileName, file.code);
|
|
461
441
|
if (file.map) {
|
|
462
|
-
const mapName =
|
|
442
|
+
const mapName = join3(filesPath, `${file.name}.map`);
|
|
463
443
|
await writeFile(mapName, file.map);
|
|
464
444
|
}
|
|
465
445
|
}));
|
|
@@ -470,8 +450,8 @@ var writeBuildFiles = async (config2, stack, id, files) => {
|
|
|
470
450
|
};
|
|
471
451
|
|
|
472
452
|
// src/plugins/function/util/publish.ts
|
|
473
|
-
import { join as
|
|
474
|
-
import { readFile } from "fs/promises";
|
|
453
|
+
import { join as join4 } from "path";
|
|
454
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
475
455
|
import { GetObjectCommand, ObjectCannedACL, PutObjectCommand, S3Client, StorageClass } from "@aws-sdk/client-s3";
|
|
476
456
|
|
|
477
457
|
// src/stack/bootstrap.ts
|
|
@@ -511,11 +491,11 @@ var shouldDeployBootstrap = async (client, name) => {
|
|
|
511
491
|
var publishFunctionAsset = async (config2, stack, id) => {
|
|
512
492
|
const bucket = assetBucketName(config2);
|
|
513
493
|
const key = `${config2.name}/${stack.artifactId}/function/${id}.zip`;
|
|
514
|
-
const funcPath =
|
|
515
|
-
const bundleFile =
|
|
516
|
-
const hashFile =
|
|
517
|
-
const hash = await
|
|
518
|
-
const file = await
|
|
494
|
+
const funcPath = join4(assetDir, "function", config2.name, stack.artifactId, id);
|
|
495
|
+
const bundleFile = join4(funcPath, "bundle.zip");
|
|
496
|
+
const hashFile = join4(funcPath, "HASH");
|
|
497
|
+
const hash = await readFile2(hashFile, "utf8");
|
|
498
|
+
const file = await readFile2(bundleFile);
|
|
519
499
|
const client = new S3Client({
|
|
520
500
|
credentials: config2.credentials,
|
|
521
501
|
region: config2.region
|
|
@@ -601,7 +581,7 @@ var functionPlugin = definePlugin({
|
|
|
601
581
|
});
|
|
602
582
|
}
|
|
603
583
|
});
|
|
604
|
-
var toFunction = ({ config: config2, stack,
|
|
584
|
+
var toFunction = ({ config: config2, stack, assets }, id, fileOrProps) => {
|
|
605
585
|
const props = typeof fileOrProps === "string" ? { ...config2.defaults?.function, file: fileOrProps } : { ...config2.defaults?.function, ...fileOrProps };
|
|
606
586
|
const lambda = new Function(stack, toId("function", id), {
|
|
607
587
|
functionName: toName(stack, id),
|
|
@@ -612,14 +592,14 @@ var toFunction = ({ config: config2, stack, stackConfig, assets }, id, fileOrPro
|
|
|
612
592
|
});
|
|
613
593
|
lambda.addEnvironment("APP", config2.name, { removeInEdge: true });
|
|
614
594
|
lambda.addEnvironment("STAGE", config2.stage, { removeInEdge: true });
|
|
615
|
-
lambda.addEnvironment("STACK",
|
|
595
|
+
lambda.addEnvironment("STACK", stack.artifactId, { removeInEdge: true });
|
|
616
596
|
if (lambda.runtime.toString().startsWith("nodejs")) {
|
|
617
597
|
lambda.addEnvironment("AWS_NODEJS_CONNECTION_REUSE_ENABLED", "1", {
|
|
618
598
|
removeInEdge: true
|
|
619
599
|
});
|
|
620
600
|
}
|
|
621
601
|
assets.add({
|
|
622
|
-
|
|
602
|
+
stackName: stack.artifactId,
|
|
623
603
|
resource: "function",
|
|
624
604
|
resourceName: id,
|
|
625
605
|
async build() {
|
|
@@ -865,7 +845,6 @@ import { z as z18 } from "zod";
|
|
|
865
845
|
import { Topic } from "aws-cdk-lib/aws-sns";
|
|
866
846
|
import { SnsEventSource } from "aws-cdk-lib/aws-lambda-event-sources";
|
|
867
847
|
import { Arn as Arn2, ArnFormat } from "aws-cdk-lib";
|
|
868
|
-
import { PolicyStatement as PolicyStatement2 } from "aws-cdk-lib/aws-iam";
|
|
869
848
|
var topicPlugin = definePlugin({
|
|
870
849
|
name: "topic",
|
|
871
850
|
schema: z18.object({
|
|
@@ -887,12 +866,6 @@ var topicPlugin = definePlugin({
|
|
|
887
866
|
},
|
|
888
867
|
onStack(ctx) {
|
|
889
868
|
const { config: config2, stack, stackConfig, bind } = ctx;
|
|
890
|
-
bind((lambda) => {
|
|
891
|
-
lambda.addToRolePolicy(new PolicyStatement2({
|
|
892
|
-
actions: ["sns:publish"],
|
|
893
|
-
resources: ["*"]
|
|
894
|
-
}));
|
|
895
|
-
});
|
|
896
869
|
return Object.entries(stackConfig.topics || {}).map(([id, props]) => {
|
|
897
870
|
const lambda = toFunction(ctx, id, props);
|
|
898
871
|
const topic = Topic.fromTopicArn(
|
|
@@ -905,6 +878,10 @@ var topicPlugin = definePlugin({
|
|
|
905
878
|
}, stack)
|
|
906
879
|
);
|
|
907
880
|
lambda.addEventSource(new SnsEventSource(topic));
|
|
881
|
+
bind((lambda2) => {
|
|
882
|
+
addResourceEnvironment(stack, "topic", id, lambda2);
|
|
883
|
+
topic.grantPublish(lambda2);
|
|
884
|
+
});
|
|
908
885
|
return lambda;
|
|
909
886
|
});
|
|
910
887
|
}
|
|
@@ -913,7 +890,7 @@ var topicPlugin = definePlugin({
|
|
|
913
890
|
// src/plugins/search.ts
|
|
914
891
|
import { z as z19 } from "zod";
|
|
915
892
|
import { CfnCollection } from "aws-cdk-lib/aws-opensearchserverless";
|
|
916
|
-
import { PolicyStatement as
|
|
893
|
+
import { PolicyStatement as PolicyStatement2 } from "aws-cdk-lib/aws-iam";
|
|
917
894
|
var searchPlugin = definePlugin({
|
|
918
895
|
name: "search",
|
|
919
896
|
schema: z19.object({
|
|
@@ -928,7 +905,7 @@ var searchPlugin = definePlugin({
|
|
|
928
905
|
type: "SEARCH"
|
|
929
906
|
});
|
|
930
907
|
bind((lambda) => {
|
|
931
|
-
lambda.addToRolePolicy(new
|
|
908
|
+
lambda.addToRolePolicy(new PolicyStatement2({
|
|
932
909
|
actions: ["aoss:APIAccessAll"],
|
|
933
910
|
resources: [collection.attrArn]
|
|
934
911
|
}));
|
|
@@ -937,6 +914,138 @@ var searchPlugin = definePlugin({
|
|
|
937
914
|
}
|
|
938
915
|
});
|
|
939
916
|
|
|
917
|
+
// src/plugins/graphql/index.ts
|
|
918
|
+
import { z as z21 } from "zod";
|
|
919
|
+
import { AuthorizationType, CfnGraphQLApi, CfnGraphQLSchema, GraphqlApi, MappingTemplate } from "aws-cdk-lib/aws-appsync";
|
|
920
|
+
import { mergeTypeDefs } from "@graphql-tools/merge";
|
|
921
|
+
import { mkdir as mkdir2, readFile as readFile3, writeFile as writeFile2 } from "fs/promises";
|
|
922
|
+
|
|
923
|
+
// src/util/array.ts
|
|
924
|
+
var toArray = (value) => {
|
|
925
|
+
if (Array.isArray(value)) {
|
|
926
|
+
return value;
|
|
927
|
+
}
|
|
928
|
+
return [value];
|
|
929
|
+
};
|
|
930
|
+
|
|
931
|
+
// src/plugins/graphql/index.ts
|
|
932
|
+
import { dirname, join as join5 } from "path";
|
|
933
|
+
import { print } from "graphql";
|
|
934
|
+
import { paramCase as paramCase2 } from "change-case";
|
|
935
|
+
|
|
936
|
+
// src/plugins/graphql/schema/resolver-field.ts
|
|
937
|
+
import { z as z20 } from "zod";
|
|
938
|
+
var ResolverFieldSchema = z20.custom((value) => {
|
|
939
|
+
return z20.string().regex(/([a-z0-9\_]+)(\s){1}([a-z0-9\_]+)/gi).safeParse(value).success;
|
|
940
|
+
}, `Invalid resolver field. Valid example: "Query list"`);
|
|
941
|
+
|
|
942
|
+
// src/plugins/graphql/index.ts
|
|
943
|
+
import { CfnOutput as CfnOutput2, Fn } from "aws-cdk-lib";
|
|
944
|
+
var graphqlPlugin = definePlugin({
|
|
945
|
+
name: "graphql",
|
|
946
|
+
schema: z21.object({
|
|
947
|
+
defaults: z21.object({
|
|
948
|
+
graphql: z21.record(ResourceIdSchema, z21.object({
|
|
949
|
+
authorization: z21.object({
|
|
950
|
+
authorizer: FunctionSchema,
|
|
951
|
+
ttl: DurationSchema.default("1 hour")
|
|
952
|
+
}).optional(),
|
|
953
|
+
mappingTemplate: z21.object({
|
|
954
|
+
request: LocalFileSchema.optional(),
|
|
955
|
+
response: LocalFileSchema.optional()
|
|
956
|
+
}).optional()
|
|
957
|
+
})).optional()
|
|
958
|
+
}).default({}),
|
|
959
|
+
stacks: z21.object({
|
|
960
|
+
graphql: z21.record(ResourceIdSchema, z21.object({
|
|
961
|
+
schema: z21.union([
|
|
962
|
+
LocalFileSchema,
|
|
963
|
+
z21.array(LocalFileSchema).min(1)
|
|
964
|
+
]).optional(),
|
|
965
|
+
resolvers: z21.record(ResolverFieldSchema, FunctionSchema).optional()
|
|
966
|
+
})).optional()
|
|
967
|
+
}).array()
|
|
968
|
+
}),
|
|
969
|
+
onBootstrap({ config: config2, stack, assets }) {
|
|
970
|
+
const list3 = /* @__PURE__ */ new Set();
|
|
971
|
+
Object.values(config2.stacks).forEach((stackConfig) => {
|
|
972
|
+
Object.keys(stackConfig.graphql || {}).forEach((id) => {
|
|
973
|
+
list3.add(id);
|
|
974
|
+
});
|
|
975
|
+
});
|
|
976
|
+
list3.forEach((id) => {
|
|
977
|
+
const file = join5(assetDir, "graphql", config2.name, id, "schema.graphql");
|
|
978
|
+
const authorization = config2.defaults.graphql?.[id]?.authorization;
|
|
979
|
+
const authProps = {};
|
|
980
|
+
if (authorization) {
|
|
981
|
+
const authorizer = toFunction({ config: config2, assets, stack }, `${id}-authorizer`, authorization.authorizer);
|
|
982
|
+
authProps.additionalAuthenticationProviders = [{
|
|
983
|
+
authenticationType: AuthorizationType.LAMBDA,
|
|
984
|
+
lambdaAuthorizerConfig: {
|
|
985
|
+
authorizerUri: authorizer.functionArn,
|
|
986
|
+
authorizerResultTtlInSeconds: authorization.ttl.toSeconds()
|
|
987
|
+
}
|
|
988
|
+
}];
|
|
989
|
+
}
|
|
990
|
+
const api = new CfnGraphQLApi(stack, toId("graphql", id), {
|
|
991
|
+
...authProps,
|
|
992
|
+
name: toName(stack, id),
|
|
993
|
+
authenticationType: AuthorizationType.API_KEY
|
|
994
|
+
});
|
|
995
|
+
new CfnOutput2(stack, toId("output", id), {
|
|
996
|
+
exportName: toId("graphql", id),
|
|
997
|
+
value: api.attrApiId
|
|
998
|
+
});
|
|
999
|
+
assets.add({
|
|
1000
|
+
stackName: stack.artifactId,
|
|
1001
|
+
resource: "schema",
|
|
1002
|
+
resourceName: id,
|
|
1003
|
+
async build() {
|
|
1004
|
+
const schemas = [];
|
|
1005
|
+
await Promise.all(Object.values(config2.stacks).map(async (stackConfig) => {
|
|
1006
|
+
const schemaFiles = toArray(stackConfig.graphql?.[id].schema || []);
|
|
1007
|
+
await Promise.all(schemaFiles.map(async (schemaFile) => {
|
|
1008
|
+
const schema3 = await readFile3(schemaFile, "utf8");
|
|
1009
|
+
schemas.push(schema3);
|
|
1010
|
+
}));
|
|
1011
|
+
}));
|
|
1012
|
+
const schema2 = print(mergeTypeDefs(schemas));
|
|
1013
|
+
await mkdir2(dirname(file), { recursive: true });
|
|
1014
|
+
await writeFile2(file, schema2);
|
|
1015
|
+
new CfnGraphQLSchema(stack, toId("schema", id), {
|
|
1016
|
+
apiId: api.attrApiId,
|
|
1017
|
+
definition: schema2
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
});
|
|
1021
|
+
});
|
|
1022
|
+
},
|
|
1023
|
+
onStack(ctx) {
|
|
1024
|
+
const { config: config2, stack, stackConfig } = ctx;
|
|
1025
|
+
return Object.entries(stackConfig.graphql || {}).map(([id, props]) => {
|
|
1026
|
+
const defaults = config2.defaults.graphql?.[id] || {};
|
|
1027
|
+
return Object.entries(props.resolvers || {}).map(([typeAndField, functionProps]) => {
|
|
1028
|
+
const api = GraphqlApi.fromGraphqlApiAttributes(stack, toId("graphql", id), {
|
|
1029
|
+
graphqlApiId: Fn.importValue(toId("graphql", id))
|
|
1030
|
+
});
|
|
1031
|
+
const [typeName, fieldName] = typeAndField.split(/[\s]+/g);
|
|
1032
|
+
const functionId = paramCase2(`${id}-${typeName}-${fieldName}`);
|
|
1033
|
+
const lambda = toFunction(ctx, functionId, functionProps);
|
|
1034
|
+
const source = api.addLambdaDataSource(toId("data-source", functionId), lambda, {
|
|
1035
|
+
name: toId("data-source", functionId)
|
|
1036
|
+
});
|
|
1037
|
+
source.createResolver(toId("resolver", functionId), {
|
|
1038
|
+
typeName,
|
|
1039
|
+
fieldName,
|
|
1040
|
+
requestMappingTemplate: defaults.mappingTemplate?.request ? MappingTemplate.fromFile(defaults.mappingTemplate.request) : MappingTemplate.lambdaRequest(),
|
|
1041
|
+
responseMappingTemplate: defaults.mappingTemplate?.response ? MappingTemplate.fromFile(defaults.mappingTemplate.response) : MappingTemplate.lambdaResult()
|
|
1042
|
+
});
|
|
1043
|
+
return lambda;
|
|
1044
|
+
});
|
|
1045
|
+
}).flat();
|
|
1046
|
+
}
|
|
1047
|
+
});
|
|
1048
|
+
|
|
940
1049
|
// src/plugins/index.ts
|
|
941
1050
|
var defaultPlugins = [
|
|
942
1051
|
functionPlugin,
|
|
@@ -945,7 +1054,8 @@ var defaultPlugins = [
|
|
|
945
1054
|
tablePlugin,
|
|
946
1055
|
storePlugin,
|
|
947
1056
|
topicPlugin,
|
|
948
|
-
searchPlugin
|
|
1057
|
+
searchPlugin,
|
|
1058
|
+
graphqlPlugin
|
|
949
1059
|
];
|
|
950
1060
|
|
|
951
1061
|
// src/stack/app-bootstrap.ts
|
|
@@ -958,8 +1068,16 @@ var appBootstrapStack = ({ config: config2, app, assets }) => {
|
|
|
958
1068
|
...config2.plugins || []
|
|
959
1069
|
];
|
|
960
1070
|
debug("Run plugin onBootstrap listeners");
|
|
961
|
-
plugins.
|
|
962
|
-
|
|
1071
|
+
const functions = plugins.map((plugin) => plugin.onBootstrap?.({
|
|
1072
|
+
config: config2,
|
|
1073
|
+
app,
|
|
1074
|
+
stack,
|
|
1075
|
+
assets
|
|
1076
|
+
})).filter(Boolean).flat().filter(Boolean);
|
|
1077
|
+
return {
|
|
1078
|
+
stack,
|
|
1079
|
+
functions
|
|
1080
|
+
};
|
|
963
1081
|
};
|
|
964
1082
|
|
|
965
1083
|
// src/util/deployment.ts
|
|
@@ -1025,10 +1143,10 @@ var Assets = class {
|
|
|
1025
1143
|
assets = {};
|
|
1026
1144
|
id = 0;
|
|
1027
1145
|
add(opts) {
|
|
1028
|
-
if (!this.assets[opts.
|
|
1029
|
-
this.assets[opts.
|
|
1146
|
+
if (!this.assets[opts.stackName]) {
|
|
1147
|
+
this.assets[opts.stackName] = [];
|
|
1030
1148
|
}
|
|
1031
|
-
this.assets[opts.
|
|
1149
|
+
this.assets[opts.stackName].push({
|
|
1032
1150
|
...opts,
|
|
1033
1151
|
id: this.id++
|
|
1034
1152
|
});
|
|
@@ -1038,12 +1156,12 @@ var Assets = class {
|
|
|
1038
1156
|
}
|
|
1039
1157
|
forEach(cb) {
|
|
1040
1158
|
Object.values(this.assets).forEach((assets) => {
|
|
1041
|
-
cb(assets[0].
|
|
1159
|
+
cb(assets[0].stackName, assets);
|
|
1042
1160
|
});
|
|
1043
1161
|
}
|
|
1044
1162
|
map(cb) {
|
|
1045
1163
|
return Object.values(this.assets).map((assets) => {
|
|
1046
|
-
return cb(assets[0].
|
|
1164
|
+
return cb(assets[0].stackName, assets);
|
|
1047
1165
|
});
|
|
1048
1166
|
}
|
|
1049
1167
|
};
|
|
@@ -1081,13 +1199,14 @@ var toApp = async (config2, filters) => {
|
|
|
1081
1199
|
debug("Plugins detected:", plugins.map((plugin) => style.info(plugin.name)).join(", "));
|
|
1082
1200
|
debug("Run plugin onApp listeners");
|
|
1083
1201
|
plugins.forEach((plugin) => plugin.onApp?.({ config: config2, app, assets }));
|
|
1202
|
+
const bootstrap2 = appBootstrapStack({ config: config2, app, assets });
|
|
1084
1203
|
debug("Stack filters:", filters.map((filter) => style.info(filter)).join(", "));
|
|
1085
1204
|
const filterdStacks = filters.length === 0 ? config2.stacks : getAllDepends(
|
|
1086
1205
|
// config.stacks,
|
|
1087
1206
|
config2.stacks.filter((stack) => filters.includes(stack.name))
|
|
1088
1207
|
);
|
|
1089
1208
|
for (const stackConfig of filterdStacks) {
|
|
1090
|
-
const { stack } = toStack({
|
|
1209
|
+
const { stack, bindings } = toStack({
|
|
1091
1210
|
config: config2,
|
|
1092
1211
|
stackConfig,
|
|
1093
1212
|
assets,
|
|
@@ -1095,14 +1214,14 @@ var toApp = async (config2, filters) => {
|
|
|
1095
1214
|
app
|
|
1096
1215
|
});
|
|
1097
1216
|
stacks.push({ stack, config: stackConfig });
|
|
1217
|
+
bindings.forEach((cb) => bootstrap2.functions.forEach(cb));
|
|
1098
1218
|
}
|
|
1099
1219
|
let dependencyTree;
|
|
1100
|
-
|
|
1101
|
-
if (bootstrap2.node.children.length === 0) {
|
|
1220
|
+
if (bootstrap2.stack.node.children.length === 0) {
|
|
1102
1221
|
dependencyTree = createDependencyTree(stacks, 0);
|
|
1103
1222
|
} else {
|
|
1104
1223
|
dependencyTree = [{
|
|
1105
|
-
stack: bootstrap2,
|
|
1224
|
+
stack: bootstrap2.stack,
|
|
1106
1225
|
level: 0,
|
|
1107
1226
|
children: createDependencyTree(stacks, 1)
|
|
1108
1227
|
}];
|
|
@@ -1174,7 +1293,7 @@ var footer = () => {
|
|
|
1174
1293
|
};
|
|
1175
1294
|
|
|
1176
1295
|
// src/config.ts
|
|
1177
|
-
import { join as
|
|
1296
|
+
import { join as join7 } from "path";
|
|
1178
1297
|
|
|
1179
1298
|
// src/util/account.ts
|
|
1180
1299
|
import { STSClient, GetCallerIdentityCommand } from "@aws-sdk/client-sts";
|
|
@@ -1193,17 +1312,17 @@ var getCredentials = (profile) => {
|
|
|
1193
1312
|
};
|
|
1194
1313
|
|
|
1195
1314
|
// src/schema/app.ts
|
|
1196
|
-
import { z as
|
|
1315
|
+
import { z as z25 } from "zod";
|
|
1197
1316
|
|
|
1198
1317
|
// src/schema/stack.ts
|
|
1199
|
-
import { z as
|
|
1200
|
-
var StackSchema =
|
|
1318
|
+
import { z as z22 } from "zod";
|
|
1319
|
+
var StackSchema = z22.object({
|
|
1201
1320
|
name: ResourceIdSchema,
|
|
1202
|
-
depends:
|
|
1321
|
+
depends: z22.array(z22.lazy(() => StackSchema)).optional()
|
|
1203
1322
|
});
|
|
1204
1323
|
|
|
1205
1324
|
// src/schema/region.ts
|
|
1206
|
-
import { z as
|
|
1325
|
+
import { z as z23 } from "zod";
|
|
1207
1326
|
var US = ["us-east-2", "us-east-1", "us-west-1", "us-west-2"];
|
|
1208
1327
|
var AF = ["af-south-1"];
|
|
1209
1328
|
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"];
|
|
@@ -1220,35 +1339,35 @@ var regions = [
|
|
|
1220
1339
|
...ME,
|
|
1221
1340
|
...SA
|
|
1222
1341
|
];
|
|
1223
|
-
var RegionSchema =
|
|
1342
|
+
var RegionSchema = z23.enum(regions);
|
|
1224
1343
|
|
|
1225
1344
|
// src/schema/plugin.ts
|
|
1226
|
-
import { z as
|
|
1227
|
-
var PluginSchema =
|
|
1228
|
-
name:
|
|
1229
|
-
schema:
|
|
1230
|
-
depends:
|
|
1231
|
-
onBootstrap:
|
|
1232
|
-
onStack:
|
|
1233
|
-
onApp:
|
|
1345
|
+
import { z as z24 } from "zod";
|
|
1346
|
+
var PluginSchema = z24.object({
|
|
1347
|
+
name: z24.string(),
|
|
1348
|
+
schema: z24.custom().optional(),
|
|
1349
|
+
// depends: z.array(z.lazy(() => PluginSchema)).optional(),
|
|
1350
|
+
onBootstrap: z24.function().returns(z24.any()).optional(),
|
|
1351
|
+
onStack: z24.function().returns(z24.any()).optional(),
|
|
1352
|
+
onApp: z24.function().returns(z24.void()).optional()
|
|
1234
1353
|
// bind: z.function().optional(),
|
|
1235
1354
|
});
|
|
1236
1355
|
|
|
1237
1356
|
// src/schema/app.ts
|
|
1238
|
-
var AppSchema =
|
|
1357
|
+
var AppSchema = z25.object({
|
|
1239
1358
|
name: ResourceIdSchema,
|
|
1240
1359
|
region: RegionSchema,
|
|
1241
|
-
profile:
|
|
1242
|
-
stage:
|
|
1243
|
-
defaults:
|
|
1244
|
-
stacks:
|
|
1245
|
-
plugins:
|
|
1360
|
+
profile: z25.string(),
|
|
1361
|
+
stage: z25.string().regex(/[a-z]+/).default("prod"),
|
|
1362
|
+
defaults: z25.object({}).default({}),
|
|
1363
|
+
stacks: z25.array(StackSchema).min(1),
|
|
1364
|
+
plugins: z25.array(PluginSchema).optional()
|
|
1246
1365
|
});
|
|
1247
1366
|
|
|
1248
1367
|
// src/util/import.ts
|
|
1249
1368
|
import { transformFile } from "@swc/core";
|
|
1250
|
-
import { dirname, join as
|
|
1251
|
-
import { lstat, mkdir as
|
|
1369
|
+
import { dirname as dirname2, join as join6 } from "path";
|
|
1370
|
+
import { lstat, mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
1252
1371
|
var resolveFileNameExtension = async (path) => {
|
|
1253
1372
|
const options = [
|
|
1254
1373
|
"",
|
|
@@ -1272,14 +1391,14 @@ var resolveFileNameExtension = async (path) => {
|
|
|
1272
1391
|
throw new Error(`Failed to load file: ${path}`);
|
|
1273
1392
|
};
|
|
1274
1393
|
var resolveDir = (path) => {
|
|
1275
|
-
return
|
|
1394
|
+
return dirname2(path).replace(rootDir + "/", "");
|
|
1276
1395
|
};
|
|
1277
1396
|
var importFile = async (path) => {
|
|
1278
1397
|
const load = async (file) => {
|
|
1279
1398
|
let { code: code2 } = await transformFile(file, {
|
|
1280
1399
|
isModule: true
|
|
1281
1400
|
});
|
|
1282
|
-
const path2 =
|
|
1401
|
+
const path2 = dirname2(file);
|
|
1283
1402
|
const dir = resolveDir(file);
|
|
1284
1403
|
code2 = code2.replaceAll("__dirname", `"${dir}"`);
|
|
1285
1404
|
const matches = code2.match(/import\s*{\s*[a-z0-9\_]+\s*}\s*from\s*('|")(\.[\/a-z0-9\_\-]+)('|");?/ig);
|
|
@@ -1288,23 +1407,23 @@ var importFile = async (path) => {
|
|
|
1288
1407
|
await Promise.all(matches?.map(async (match) => {
|
|
1289
1408
|
const parts = /('|")(\.[\/a-z0-9\_\-]+)('|")/ig.exec(match);
|
|
1290
1409
|
const from = parts[2];
|
|
1291
|
-
const file2 = await resolveFileNameExtension(
|
|
1410
|
+
const file2 = await resolveFileNameExtension(join6(path2, from));
|
|
1292
1411
|
const result = await load(file2);
|
|
1293
1412
|
code2 = code2.replace(match, result);
|
|
1294
1413
|
}));
|
|
1295
1414
|
return code2;
|
|
1296
1415
|
};
|
|
1297
1416
|
const code = await load(path);
|
|
1298
|
-
const outputFile =
|
|
1299
|
-
await
|
|
1300
|
-
await
|
|
1417
|
+
const outputFile = join6(outDir, "config.js");
|
|
1418
|
+
await mkdir3(outDir, { recursive: true });
|
|
1419
|
+
await writeFile3(outputFile, code);
|
|
1301
1420
|
return import(outputFile);
|
|
1302
1421
|
};
|
|
1303
1422
|
|
|
1304
1423
|
// src/config.ts
|
|
1305
1424
|
var importConfig = async (options) => {
|
|
1306
1425
|
debug("Import config file");
|
|
1307
|
-
const fileName =
|
|
1426
|
+
const fileName = join7(process.cwd(), options.configFile || "awsless.config.ts");
|
|
1308
1427
|
const module = await importFile(fileName);
|
|
1309
1428
|
const appConfig = typeof module.default === "function" ? await module.default({
|
|
1310
1429
|
profile: options.profile,
|
|
@@ -1518,6 +1637,13 @@ var Interface = class {
|
|
|
1518
1637
|
if (this.input.isTTY) {
|
|
1519
1638
|
this.input.setRawMode(true);
|
|
1520
1639
|
}
|
|
1640
|
+
this.input.on("keypress", (_, key) => {
|
|
1641
|
+
const action = parseAction(key);
|
|
1642
|
+
if (action === "abort") {
|
|
1643
|
+
this.unref();
|
|
1644
|
+
process.exit(1);
|
|
1645
|
+
}
|
|
1646
|
+
});
|
|
1521
1647
|
}
|
|
1522
1648
|
// private subscriber: Actions | undefined
|
|
1523
1649
|
readline;
|
|
@@ -1667,12 +1793,6 @@ var layout = async (cb) => {
|
|
|
1667
1793
|
const term = createTerminal();
|
|
1668
1794
|
term.out.clear();
|
|
1669
1795
|
term.out.write(logo());
|
|
1670
|
-
term.in.captureInput({
|
|
1671
|
-
abort: () => {
|
|
1672
|
-
term.in.showCursor();
|
|
1673
|
-
process.exit(1);
|
|
1674
|
-
}
|
|
1675
|
-
});
|
|
1676
1796
|
try {
|
|
1677
1797
|
const options = program.optsWithGlobals();
|
|
1678
1798
|
const config2 = await importConfig(options);
|
|
@@ -1693,7 +1813,7 @@ var layout = async (cb) => {
|
|
|
1693
1813
|
term.in.unref();
|
|
1694
1814
|
setTimeout(() => {
|
|
1695
1815
|
process.exit(0);
|
|
1696
|
-
},
|
|
1816
|
+
}, 100);
|
|
1697
1817
|
}
|
|
1698
1818
|
};
|
|
1699
1819
|
|
|
@@ -1724,7 +1844,8 @@ var assetBuilder = (assets) => {
|
|
|
1724
1844
|
const groups = new Signal([br()]);
|
|
1725
1845
|
term.out.write(groups);
|
|
1726
1846
|
const stackNameSize = Math.max(...Object.keys(assets.list()).map((stack) => stack.length));
|
|
1727
|
-
|
|
1847
|
+
const resourceSize = Math.max(...Object.values(assets.list()).map((assets2) => assets2.map((asset) => asset.resource.length)).flat());
|
|
1848
|
+
await Promise.all(assets.map(async (stackName, assets2) => {
|
|
1728
1849
|
const group = new Signal([]);
|
|
1729
1850
|
groups.update((groups2) => [...groups2, group]);
|
|
1730
1851
|
await Promise.all(assets2.map(async (asset) => {
|
|
@@ -1733,12 +1854,13 @@ var assetBuilder = (assets) => {
|
|
|
1733
1854
|
const line = flexLine(term, [
|
|
1734
1855
|
icon,
|
|
1735
1856
|
" ",
|
|
1736
|
-
style.label(
|
|
1737
|
-
" ".repeat(stackNameSize -
|
|
1857
|
+
style.label(stackName),
|
|
1858
|
+
" ".repeat(stackNameSize - stackName.length),
|
|
1738
1859
|
" ",
|
|
1739
1860
|
style.placeholder(symbol.pointerSmall),
|
|
1740
1861
|
" ",
|
|
1741
1862
|
style.warning(asset.resource),
|
|
1863
|
+
" ".repeat(resourceSize - asset.resource.length),
|
|
1742
1864
|
" ",
|
|
1743
1865
|
style.placeholder(symbol.pointerSmall),
|
|
1744
1866
|
" ",
|
|
@@ -1769,25 +1891,26 @@ var assetBuilder = (assets) => {
|
|
|
1769
1891
|
};
|
|
1770
1892
|
|
|
1771
1893
|
// src/util/cleanup.ts
|
|
1772
|
-
import { mkdir as
|
|
1894
|
+
import { mkdir as mkdir4, rm as rm2 } from "fs/promises";
|
|
1773
1895
|
var cleanUp = async () => {
|
|
1774
1896
|
debug("Clean up assembly & asset files");
|
|
1775
1897
|
const paths = [
|
|
1776
1898
|
assemblyDir,
|
|
1777
|
-
|
|
1899
|
+
assetDir,
|
|
1900
|
+
cacheDir
|
|
1778
1901
|
];
|
|
1779
|
-
await Promise.all(paths.map((path) =>
|
|
1902
|
+
await Promise.all(paths.map((path) => rm2(path, {
|
|
1780
1903
|
recursive: true,
|
|
1781
1904
|
force: true,
|
|
1782
1905
|
maxRetries: 2
|
|
1783
1906
|
})));
|
|
1784
|
-
await Promise.all(paths.map((path) =>
|
|
1907
|
+
await Promise.all(paths.map((path) => mkdir4(path, {
|
|
1785
1908
|
recursive: true
|
|
1786
1909
|
})));
|
|
1787
1910
|
};
|
|
1788
1911
|
|
|
1789
1912
|
// src/cli/command/build.ts
|
|
1790
|
-
var
|
|
1913
|
+
var build2 = (program2) => {
|
|
1791
1914
|
program2.command("build").argument("[stack...]", "Optionally filter stacks to build").description("Build your app").action(async (filters) => {
|
|
1792
1915
|
await layout(async (config2, write) => {
|
|
1793
1916
|
const { app, assets } = await toApp(config2, filters);
|
|
@@ -1905,7 +2028,7 @@ var StackClient = class {
|
|
|
1905
2028
|
stack.Outputs?.forEach((output) => {
|
|
1906
2029
|
outputs[output.OutputKey] = output.OutputValue;
|
|
1907
2030
|
});
|
|
1908
|
-
debug("Status for:
|
|
2031
|
+
debug("Status for:", style.info(name), "is", style.attr(stack.StackStatus));
|
|
1909
2032
|
return {
|
|
1910
2033
|
status: stack.StackStatus,
|
|
1911
2034
|
reason: stack.StackStatusReason,
|
|
@@ -2171,6 +2294,7 @@ var deploy = (program2) => {
|
|
|
2171
2294
|
await cleanUp();
|
|
2172
2295
|
await write(assetBuilder(assets));
|
|
2173
2296
|
write(br());
|
|
2297
|
+
write(br());
|
|
2174
2298
|
const donePublishing = write(loadingDialog("Publishing stack assets to AWS..."));
|
|
2175
2299
|
await Promise.all(assets.map(async (_, assets2) => {
|
|
2176
2300
|
await Promise.all(assets2.map(async (asset) => {
|
|
@@ -2186,21 +2310,28 @@ var deploy = (program2) => {
|
|
|
2186
2310
|
const doneDeploying = write(loadingDialog("Deploying stacks to AWS..."));
|
|
2187
2311
|
write(br());
|
|
2188
2312
|
write(stackTree(dependencyTree, statuses));
|
|
2313
|
+
write(br());
|
|
2189
2314
|
const client = new StackClient(config2);
|
|
2190
2315
|
const deploymentLine = createDeploymentLine(dependencyTree);
|
|
2191
2316
|
for (const stacks of deploymentLine) {
|
|
2192
|
-
await Promise.allSettled(stacks.map(async (stack) => {
|
|
2317
|
+
const results = await Promise.allSettled(stacks.map(async (stack) => {
|
|
2318
|
+
const signal = statuses[stack.artifactId];
|
|
2193
2319
|
const stackArtifect = assembly.stacks.find((item) => item.id === stack.artifactId);
|
|
2194
|
-
|
|
2320
|
+
signal.set(style.warning("deploying"));
|
|
2195
2321
|
try {
|
|
2196
2322
|
await client.deploy(stackArtifect);
|
|
2197
2323
|
} catch (error) {
|
|
2198
2324
|
debugError(error);
|
|
2199
|
-
|
|
2325
|
+
signal.set(style.error("failed"));
|
|
2200
2326
|
throw error;
|
|
2201
2327
|
}
|
|
2202
|
-
|
|
2328
|
+
signal.set(style.success("deployed"));
|
|
2203
2329
|
}));
|
|
2330
|
+
for (const result of results) {
|
|
2331
|
+
if (result.status === "rejected") {
|
|
2332
|
+
throw result.reason;
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2204
2335
|
}
|
|
2205
2336
|
doneDeploying("Done deploying stacks to AWS");
|
|
2206
2337
|
});
|
|
@@ -2375,7 +2506,7 @@ program.on("option:verbose", () => {
|
|
|
2375
2506
|
var commands2 = [
|
|
2376
2507
|
bootstrap,
|
|
2377
2508
|
status,
|
|
2378
|
-
|
|
2509
|
+
build2,
|
|
2379
2510
|
deploy,
|
|
2380
2511
|
config
|
|
2381
2512
|
// diff,
|