@byaga/cdk-patterns 0.6.1 → 0.8.0

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.
Files changed (62) hide show
  1. package/.fleet/run.json +11 -0
  2. package/lib/ApiCertificate.d.ts +2 -2
  3. package/lib/ApiCertificate.js +4 -5
  4. package/lib/CognitoApiGatewayAuthorizer.d.ts +19 -0
  5. package/lib/CognitoApiGatewayAuthorizer.js +24 -0
  6. package/lib/DeployStack.d.ts +20 -0
  7. package/lib/DeployStack.js +48 -0
  8. package/lib/DynamoDbTable.d.ts +12 -0
  9. package/lib/DynamoDbTable.js +34 -0
  10. package/lib/FunctionIntegration.d.ts +21 -0
  11. package/lib/FunctionIntegration.js +61 -0
  12. package/lib/ICorsConfig.d.ts +5 -0
  13. package/lib/ICorsConfig.js +2 -0
  14. package/lib/NodeJsLambda.d.ts +13 -0
  15. package/lib/NodeJsLambda.js +28 -0
  16. package/lib/Output.d.ts +5 -0
  17. package/lib/Output.js +13 -0
  18. package/lib/RestApi.d.ts +28 -0
  19. package/lib/RestApi.js +142 -0
  20. package/lib/Role.d.ts +2 -2
  21. package/lib/Role.js +2 -5
  22. package/lib/SsmParameter.d.ts +18 -0
  23. package/lib/SsmParameter.js +40 -0
  24. package/lib/StaticWebSite.d.ts +12 -0
  25. package/lib/StaticWebSite.js +107 -0
  26. package/lib/index.d.ts +7 -1
  27. package/lib/index.js +15 -3
  28. package/lib/methods/apply-honeycomb-to-lambda.d.ts +3 -0
  29. package/lib/methods/apply-honeycomb-to-lambda.js +22 -0
  30. package/lib/methods/build-node-source.d.ts +13 -0
  31. package/lib/methods/build-node-source.js +105 -0
  32. package/lib/methods/duration.d.ts +8 -0
  33. package/lib/methods/duration.js +22 -0
  34. package/lib/methods/empty-directory.d.ts +2 -0
  35. package/lib/methods/empty-directory.js +47 -0
  36. package/lib/methods/generate-hash.d.ts +15 -0
  37. package/lib/methods/generate-hash.js +59 -0
  38. package/lib/methods/get-source-directory.d.ts +4 -0
  39. package/lib/methods/get-source-directory.js +37 -0
  40. package/lib/methods/walk-directory.d.ts +14 -0
  41. package/lib/methods/walk-directory.js +48 -0
  42. package/package.json +4 -2
  43. package/src/ApiCertificate.ts +6 -6
  44. package/src/CognitoApiGatewayAuthorizer.ts +25 -0
  45. package/src/{IDeployStack.ts → DeployStack.ts} +4 -4
  46. package/src/DynamoDbTable.ts +40 -0
  47. package/src/FunctionIntegration.ts +83 -0
  48. package/src/ICorsConfig.ts +5 -0
  49. package/src/NodeJsLambda.ts +31 -0
  50. package/src/Output.ts +11 -0
  51. package/src/RestApi.ts +178 -0
  52. package/src/Role.ts +5 -7
  53. package/src/SsmParameter.ts +47 -0
  54. package/src/StaticWebSite.ts +99 -0
  55. package/src/index.ts +7 -1
  56. package/src/methods/apply-honeycomb-to-lambda.ts +22 -0
  57. package/src/methods/build-node-source.ts +97 -0
  58. package/src/methods/duration.ts +24 -0
  59. package/src/methods/empty-directory.ts +19 -0
  60. package/src/methods/generate-hash.ts +49 -0
  61. package/src/methods/get-source-directory.ts +11 -0
  62. package/src/methods/walk-directory.ts +30 -0
@@ -0,0 +1,11 @@
1
+ {
2
+ "configurations": [
3
+ {
4
+ "type": "npm",
5
+ "name": "cdk-patterns build",
6
+ "command": "run",
7
+ "scripts": "build",
8
+ },
9
+
10
+ ]
11
+ }
@@ -1,10 +1,10 @@
1
1
  import { Certificate } from "aws-cdk-lib/aws-certificatemanager";
2
2
  import { IHostedZone } from "aws-cdk-lib/aws-route53";
3
- import IDeployStack from "./IDeployStack";
3
+ import DeployStack from "./DeployStack";
4
4
  import IDomainConfig from "./IDomainConfig";
5
5
  export declare class ApiCertificate extends Certificate {
6
6
  hostedZone: IHostedZone;
7
7
  domain: string;
8
- constructor(stack: IDeployStack, id: string, domain: IDomainConfig);
8
+ constructor(stack: DeployStack, id: string, domain: IDomainConfig);
9
9
  }
10
10
  export default ApiCertificate;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ApiCertificate = void 0;
4
4
  const aws_certificatemanager_1 = require("aws-cdk-lib/aws-certificatemanager");
5
5
  const aws_route53_1 = require("aws-cdk-lib/aws-route53");
6
- const aws_cdk_lib_1 = require("aws-cdk-lib");
6
+ const Output_1 = require("./Output");
7
7
  class ApiCertificate extends aws_certificatemanager_1.Certificate {
8
8
  hostedZone;
9
9
  domain;
@@ -12,19 +12,18 @@ class ApiCertificate extends aws_certificatemanager_1.Certificate {
12
12
  if (domain.subdomain)
13
13
  certDomain.splice(0, 0, domain.subdomain);
14
14
  const domainName = certDomain.join('.');
15
+ console.log('Getting Hosted Zone', domain.hostedZone.name);
15
16
  const hostedZone = aws_route53_1.HostedZone.fromHostedZoneAttributes(stack, stack.genId(id, 'hosted-zone'), {
16
17
  hostedZoneId: domain.hostedZone.id,
17
18
  zoneName: domain.hostedZone.name
18
19
  });
20
+ console.log('Defining Certificate For', domainName);
19
21
  super(stack, stack.genId(id), {
20
22
  domainName,
21
23
  validation: aws_certificatemanager_1.CertificateValidation.fromDns(hostedZone)
22
24
  });
23
25
  this.domain = domainName;
24
- new aws_cdk_lib_1.CfnOutput(this, stack.genId(id, "certificate-output"), {
25
- value: this.certificateArn,
26
- exportName: stack.genName(id)
27
- });
26
+ new Output_1.Output(stack, id, this.certificateArn);
28
27
  this.hostedZone = hostedZone;
29
28
  }
30
29
  }
@@ -0,0 +1,19 @@
1
+ import { Construct } from 'constructs';
2
+ import { CfnAuthorizer, IAuthorizer } from 'aws-cdk-lib/aws-apigateway';
3
+ import { CfnAuthorizerProps } from 'aws-cdk-lib/aws-apigateway/lib/apigateway.generated';
4
+ /**
5
+ * Custom construct that implements a Cognito based API Gateway Authorizer.
6
+ *
7
+ * @see https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_author
8
+ *
9
+ * @see https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-apigateway.CfnAuthorizer.html
10
+ * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-authorizer.html
11
+ * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html
12
+ * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-enable-cognito-user-pool.html
13
+ *
14
+ * @see https://github.com/aws/aws-cdk/issues/5618#issuecomment-666922559
15
+ */
16
+ export declare class CognitoApiGatewayAuthorizer extends CfnAuthorizer implements IAuthorizer {
17
+ readonly authorizerId: string;
18
+ constructor(scope: Construct, id: string, props: CfnAuthorizerProps);
19
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CognitoApiGatewayAuthorizer = void 0;
4
+ const aws_apigateway_1 = require("aws-cdk-lib/aws-apigateway");
5
+ /**
6
+ * Custom construct that implements a Cognito based API Gateway Authorizer.
7
+ *
8
+ * @see https://docs.aws.amazon.com/cdk/latest/guide/constructs.html#constructs_author
9
+ *
10
+ * @see https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-apigateway.CfnAuthorizer.html
11
+ * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-authorizer.html
12
+ * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html
13
+ * @see https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-enable-cognito-user-pool.html
14
+ *
15
+ * @see https://github.com/aws/aws-cdk/issues/5618#issuecomment-666922559
16
+ */
17
+ class CognitoApiGatewayAuthorizer extends aws_apigateway_1.CfnAuthorizer {
18
+ authorizerId;
19
+ constructor(scope, id, props) {
20
+ super(scope, id, props);
21
+ this.authorizerId = this.ref;
22
+ }
23
+ }
24
+ exports.CognitoApiGatewayAuthorizer = CognitoApiGatewayAuthorizer;
@@ -0,0 +1,20 @@
1
+ import { Stack } from 'aws-cdk-lib';
2
+ import IStackArguments from './IStackArguments';
3
+ import { IConstruct } from "constructs";
4
+ export declare class DeployStack extends Stack {
5
+ registry: {
6
+ [t: string]: {
7
+ [n: string]: any;
8
+ };
9
+ };
10
+ stage: string;
11
+ name: string;
12
+ genName(...name: string[]): string;
13
+ genId(...name: string[]): string;
14
+ static genStackResourceName(stackName: string, resource: string, stage?: string): string;
15
+ static genStackResourceId(stackName: string, resource: string, stage?: string): string;
16
+ constructor(scope: IConstruct, props: IStackArguments);
17
+ get(type: string, name: string): any;
18
+ set(type: string, name: string, instance: any): any;
19
+ }
20
+ export default DeployStack;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeployStack = void 0;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ class DeployStack extends aws_cdk_lib_1.Stack {
6
+ registry = {};
7
+ stage;
8
+ name;
9
+ genName(...name) {
10
+ return DeployStack.genStackResourceName(this.name, this.stage, name.filter(n => !!n).join('-'));
11
+ }
12
+ genId(...name) {
13
+ return DeployStack.genStackResourceId(this.name, this.stage, name.filter(n => !!n).join('-'));
14
+ }
15
+ static genStackResourceName(stackName, resource, stage = 'develop') {
16
+ let name = stackName[0].toLowerCase() + stackName.substr(1);
17
+ name = name.replace(/[A-Z]/g, v => '-' + v.toLowerCase());
18
+ return `${name}-${resource}-${stage}`.toLowerCase();
19
+ }
20
+ static genStackResourceId(stackName, resource, stage = 'develop') {
21
+ const constructName = `${stackName}-${resource}-${stage}`;
22
+ return constructName[0].toUpperCase() + constructName.substr(1).replace(/-./g, v => (v[1] || '').toUpperCase());
23
+ }
24
+ constructor(scope, props) {
25
+ const options = (props || {});
26
+ const { stage = 'develop' } = options;
27
+ super(scope, props.stackName + '-' + stage, {
28
+ ...props,
29
+ stackName: props.stackName + '-' + stage
30
+ });
31
+ const stack = this;
32
+ stack.name = props.stackName || '';
33
+ stack.stage = stage;
34
+ stack.tags.setTag('Stage', stage);
35
+ stack.tags.setTag('Stack', this.genName('ui-stack'));
36
+ }
37
+ get(type, name) {
38
+ const items = this.registry[type];
39
+ return (items && items[name]) || null;
40
+ }
41
+ set(type, name, instance) {
42
+ this.registry[type] = this.registry[type] || {};
43
+ this.registry[type][name] = instance;
44
+ return instance;
45
+ }
46
+ }
47
+ exports.DeployStack = DeployStack;
48
+ exports.default = DeployStack;
@@ -0,0 +1,12 @@
1
+ import { Table } from 'aws-cdk-lib/aws-dynamodb';
2
+ import { Policy } from "aws-cdk-lib/aws-iam";
3
+ import { DeployStack } from "./DeployStack";
4
+ interface DynamoDbTableConfig {
5
+ partitionKey: string;
6
+ sortKey?: string;
7
+ }
8
+ export declare class DynamoDbTable extends Table {
9
+ getPolicy: Policy;
10
+ constructor(stack: DeployStack, id: string, props: DynamoDbTableConfig);
11
+ }
12
+ export {};
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DynamoDbTable = void 0;
4
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const aws_dynamodb_1 = require("aws-cdk-lib/aws-dynamodb");
6
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
7
+ class DynamoDbTable extends aws_dynamodb_1.Table {
8
+ getPolicy;
9
+ constructor(stack, id, props) {
10
+ console.log('Creating DynamoDb Table', stack.genName(id, 'data-table'));
11
+ super(stack, stack.genId(id, 'data-table'), {
12
+ tableName: stack.genName(id, 'data-table'),
13
+ partitionKey: { name: props.partitionKey, type: aws_dynamodb_1.AttributeType.STRING },
14
+ sortKey: props.sortKey ? { name: props.sortKey, type: aws_dynamodb_1.AttributeType.STRING } : undefined,
15
+ billingMode: aws_dynamodb_1.BillingMode.PAY_PER_REQUEST,
16
+ removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY
17
+ });
18
+ stack.set('dynamo', id, this);
19
+ new aws_cdk_lib_1.CfnOutput(stack, stack.genId(id, 'table'), {
20
+ value: this.tableName,
21
+ exportName: stack.genName(id, 'table')
22
+ });
23
+ this.getPolicy = new aws_iam_1.Policy(stack, stack.genId(id, 'get-policy'), {
24
+ statements: [
25
+ new aws_iam_1.PolicyStatement({
26
+ actions: ['dynamodb:GetItem'],
27
+ effect: aws_iam_1.Effect.ALLOW,
28
+ resources: [this.tableArn]
29
+ })
30
+ ]
31
+ });
32
+ }
33
+ }
34
+ exports.DynamoDbTable = DynamoDbTable;
@@ -0,0 +1,21 @@
1
+ import { DeployStack } from "./DeployStack";
2
+ import { Function, FunctionProps } from "aws-cdk-lib/aws-lambda";
3
+ import { JsonSchema, MethodOptions } from "aws-cdk-lib/aws-apigateway";
4
+ import { Duration } from "aws-cdk-lib";
5
+ import { RestApi } from "./RestApi";
6
+ interface AddToApiOptions {
7
+ requestSchema?: JsonSchema;
8
+ methodOptions?: MethodOptions;
9
+ }
10
+ export interface FunctionIntegrationProps {
11
+ funcProps: FunctionProps;
12
+ timeout?: Duration;
13
+ memory?: number;
14
+ }
15
+ export declare class FunctionIntegration extends Function {
16
+ stack: DeployStack;
17
+ name: string;
18
+ constructor(stack: DeployStack, id: string, options: FunctionIntegrationProps);
19
+ attach(api: RestApi, httpMethod: string, path: string, props: AddToApiOptions): void;
20
+ }
21
+ export {};
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FunctionIntegration = void 0;
4
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
5
+ const aws_apigateway_1 = require("aws-cdk-lib/aws-apigateway");
6
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
7
+ const apply_honeycomb_to_lambda_1 = require("./methods/apply-honeycomb-to-lambda");
8
+ const aws_logs_1 = require("aws-cdk-lib/aws-logs");
9
+ class FunctionIntegration extends aws_lambda_1.Function {
10
+ stack;
11
+ name;
12
+ constructor(stack, id, options) {
13
+ const props = (0, apply_honeycomb_to_lambda_1.applyHoneycombToLambda)(stack, {
14
+ functionName: stack.genName(id),
15
+ memorySize: options.memory || 256,
16
+ timeout: options.timeout || aws_cdk_lib_1.Duration.seconds(16),
17
+ logRetention: aws_logs_1.RetentionDays.ONE_WEEK,
18
+ ...options.funcProps
19
+ });
20
+ super(stack, stack.genId(id, 'lambda'), props);
21
+ this.stack = stack;
22
+ this.name = id;
23
+ stack.set('lambda', id, this);
24
+ new aws_cdk_lib_1.CfnOutput(stack, stack.genId(id, 'function-name'), {
25
+ value: this.functionName,
26
+ exportName: stack.genName(id, 'function-name')
27
+ });
28
+ }
29
+ attach(api, httpMethod, path, props) {
30
+ const resource = api.path(path);
31
+ const integration = new aws_apigateway_1.LambdaIntegration(this, {
32
+ requestTemplates: {
33
+ 'application/json': '{ "statusCode": "200" }'
34
+ }
35
+ });
36
+ let options = props?.methodOptions || {};
37
+ const schema = props?.requestSchema;
38
+ if (schema)
39
+ options = applySchema(this.stack, this.name, schema, options, resource);
40
+ const method = resource.addMethod(httpMethod, integration, options);
41
+ }
42
+ }
43
+ exports.FunctionIntegration = FunctionIntegration;
44
+ function applySchema(stack, name, schema, options, path) {
45
+ return {
46
+ ...options,
47
+ requestValidator: new aws_apigateway_1.RequestValidator(stack, stack.genId(name, 'validator'), {
48
+ restApi: path.api,
49
+ requestValidatorName: stack.genName(name, 'validator'),
50
+ validateRequestBody: true
51
+ }),
52
+ requestModels: {
53
+ 'application/json': new aws_apigateway_1.Model(stack, stack.genId(name, 'model'), {
54
+ schema: schema,
55
+ contentType: 'application/json',
56
+ restApi: path.api,
57
+ modelName: stack.genId(name, 'model')
58
+ })
59
+ }
60
+ };
61
+ }
@@ -0,0 +1,5 @@
1
+ export interface ICorsConfig {
2
+ maxAge?: number;
3
+ exposeHeaders?: string[];
4
+ allowOrigin?: string | string[];
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,13 @@
1
+ import { FunctionOptions } from "aws-cdk-lib/aws-lambda";
2
+ import { DeployStack } from "./DeployStack";
3
+ import { FunctionIntegration } from "./FunctionIntegration";
4
+ import { Duration } from "aws-cdk-lib";
5
+ interface NodeFunctionProps {
6
+ funcProps?: FunctionOptions;
7
+ timeout?: Duration;
8
+ memory?: number;
9
+ }
10
+ export declare class NodeJsLambda extends FunctionIntegration {
11
+ constructor(stack: DeployStack, id: string, options?: NodeFunctionProps);
12
+ }
13
+ export {};
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.NodeJsLambda = void 0;
7
+ const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
8
+ const FunctionIntegration_1 = require("./FunctionIntegration");
9
+ const build_node_source_1 = require("./methods/build-node-source");
10
+ const duration_1 = __importDefault(require("./methods/duration"));
11
+ class NodeJsLambda extends FunctionIntegration_1.FunctionIntegration {
12
+ constructor(stack, id, options) {
13
+ console.log('Defining Node Lambda', id);
14
+ const done = (0, duration_1.default)();
15
+ const { buildDir } = (0, build_node_source_1.buildNodeSource)('lambda', id);
16
+ console.log('Total Build Duration (ms)', done());
17
+ super(stack, id, {
18
+ ...options,
19
+ funcProps: {
20
+ ...options?.funcProps,
21
+ code: aws_lambda_1.Code.fromAsset(buildDir),
22
+ handler: `${id}.handler`,
23
+ runtime: aws_lambda_1.Runtime.NODEJS_18_X
24
+ }
25
+ });
26
+ }
27
+ }
28
+ exports.NodeJsLambda = NodeJsLambda;
@@ -0,0 +1,5 @@
1
+ import { CfnOutput } from 'aws-cdk-lib/core';
2
+ import { DeployStack } from './DeployStack';
3
+ export declare class Output extends CfnOutput {
4
+ constructor(stack: DeployStack, name: string, value: string);
5
+ }
package/lib/Output.js ADDED
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Output = void 0;
4
+ const core_1 = require("aws-cdk-lib/core");
5
+ class Output extends core_1.CfnOutput {
6
+ constructor(stack, name, value) {
7
+ super(stack, stack.genId(name, 'output'), {
8
+ value,
9
+ exportName: stack.genName(name)
10
+ });
11
+ }
12
+ }
13
+ exports.Output = Output;
@@ -0,0 +1,28 @@
1
+ import { RestApi as RestApiBase, IDomainName, IResource } from "aws-cdk-lib/aws-apigateway";
2
+ import { DeployStack } from "./DeployStack";
3
+ import { ICorsConfig } from "./ICorsConfig";
4
+ import { PolicyStatement } from "aws-cdk-lib/aws-iam";
5
+ interface IRestApiConfig {
6
+ cors?: ICorsConfig;
7
+ allowCredentials: boolean;
8
+ }
9
+ interface IBasePathMappingConfig {
10
+ domain?: IDomainName;
11
+ domainName?: string;
12
+ hostedZoneId?: string;
13
+ }
14
+ interface IResourceNode {
15
+ children: {
16
+ [key: string]: IResourceNode;
17
+ };
18
+ node: IResource;
19
+ }
20
+ export declare class RestApi extends RestApiBase {
21
+ _id: string;
22
+ _tree: IResourceNode;
23
+ constructor(stack: DeployStack, id: string, props: IRestApiConfig);
24
+ addBasePathMapping(stack: DeployStack, config: IBasePathMappingConfig): void;
25
+ addAuthorizedRole(stack: DeployStack, roleArn: string): PolicyStatement;
26
+ path(uri: string): IResource;
27
+ }
28
+ export {};
package/lib/RestApi.js ADDED
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RestApi = void 0;
4
+ const aws_apigateway_1 = require("aws-cdk-lib/aws-apigateway");
5
+ const aws_cdk_lib_1 = require("aws-cdk-lib");
6
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
7
+ const DEFAULT_EXPOSE_HEADERS = ['Date'];
8
+ class RestApi extends aws_apigateway_1.RestApi {
9
+ _id;
10
+ _tree;
11
+ constructor(stack, id, props) {
12
+ const { stage } = stack;
13
+ console.log('Defining Rest API', stack.genId(id, 'api'));
14
+ const cors = props.cors || {};
15
+ const allowOrigins = Array.isArray(cors.allowOrigin) ? cors.allowOrigin : [cors.allowOrigin || '*'];
16
+ super(stack, stack.genId(id, 'api'), {
17
+ restApiName: stack.genName('api'),
18
+ deploy: true,
19
+ deployOptions: {
20
+ stageName: stage,
21
+ tracingEnabled: true
22
+ },
23
+ minCompressionSize: aws_cdk_lib_1.Size.bytes(1000),
24
+ endpointConfiguration: {
25
+ types: [aws_apigateway_1.EndpointType.EDGE]
26
+ },
27
+ defaultCorsPreflightOptions: {
28
+ allowHeaders: ['*'],
29
+ allowMethods: ['*'],
30
+ allowCredentials: props.allowCredentials,
31
+ allowOrigins,
32
+ maxAge: aws_cdk_lib_1.Duration.seconds(cors.maxAge || 86400),
33
+ exposeHeaders: cors.exposeHeaders || DEFAULT_EXPOSE_HEADERS
34
+ }
35
+ });
36
+ this._id = id;
37
+ // APIs MUST have at least one endpoint, so this will give it one
38
+ console.log('Adding health endpoint', '/health');
39
+ const health = this.root.addResource('health');
40
+ health.addMethod("GET", new aws_apigateway_1.MockIntegration({
41
+ requestTemplates: {
42
+ "application/json": "{\"statusCode\": 200}"
43
+ },
44
+ integrationResponses: [{
45
+ statusCode: '200',
46
+ contentHandling: aws_apigateway_1.ContentHandling.CONVERT_TO_TEXT,
47
+ responseTemplates: {
48
+ 'application/json': `
49
+ ## See http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
50
+ ## This template will pass through all parameters including path, querystring, header, stage variables, and context through to the integration endpoint via the body/payload
51
+ #set($allParams = $input.params())
52
+ {
53
+ "body-json" : $input.json('$'),
54
+ "params" : {
55
+ #foreach($type in $allParams.keySet())
56
+ #set($params = $allParams.get($type))
57
+ "$type" : {
58
+ #foreach($paramName in $params.keySet())
59
+ "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
60
+ #if($foreach.hasNext),#end
61
+ #end
62
+ }
63
+ #if($foreach.hasNext),#end
64
+ #end
65
+ },
66
+ "stage-variables" : {
67
+ #foreach($key in $stageVariables.keySet())
68
+ "$key" : "$util.escapeJavaScript($stageVariables.get($key))"
69
+ #if($foreach.hasNext),#end
70
+ #end
71
+ },
72
+ "context" : {
73
+ "account-id" : "$context.identity.accountId",
74
+ "api-id" : "$context.apiId",
75
+ "api-key" : "$context.identity.apiKey",
76
+ "authorizer-principal-id" : "$context.authorizer.principalId",
77
+ "caller" : "$context.identity.caller",
78
+ "cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
79
+ "cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
80
+ "cognito-identity-id" : "$context.identity.cognitoIdentityId",
81
+ "cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
82
+ "http-method" : "$context.httpMethod",
83
+ "stage" : "$context.stage",
84
+ "source-ip" : "$context.identity.sourceIp",
85
+ "user" : "$context.identity.user",
86
+ "user-agent" : "$context.identity.userAgent",
87
+ "user-arn" : "$context.identity.userArn",
88
+ "request-id" : "$context.requestId",
89
+ "resource-id" : "$context.resourceId",
90
+ "resource-path" : "$context.resourcePath"
91
+ }
92
+ }`
93
+ }
94
+ }]
95
+ }), {
96
+ methodResponses: [{ statusCode: "200" }]
97
+ });
98
+ this._tree = { node: this.root, children: {} };
99
+ }
100
+ addBasePathMapping(stack, config) {
101
+ let domain = config.domain;
102
+ if (!domain && config.domainName && config.hostedZoneId) {
103
+ domain = aws_apigateway_1.DomainName.fromDomainNameAttributes(stack, stack.genName('domain-name'), {
104
+ domainName: config.domainName,
105
+ domainNameAliasHostedZoneId: config.hostedZoneId,
106
+ domainNameAliasTarget: this.restApiRootResourceId
107
+ });
108
+ }
109
+ if (!domain)
110
+ throw new Error('Missing Domain Configuration For Base Path Mapping');
111
+ new aws_apigateway_1.BasePathMapping(stack, stack.genId(this._id, 'base-path-mapping'), {
112
+ domainName: domain,
113
+ stage: this.deploymentStage,
114
+ restApi: this,
115
+ basePath: this._id
116
+ });
117
+ }
118
+ addAuthorizedRole(stack, roleArn) {
119
+ const policyStatement = new aws_iam_1.PolicyStatement({
120
+ effect: aws_iam_1.Effect.ALLOW,
121
+ actions: ['execute-api:Invoke']
122
+ });
123
+ const authRole = aws_iam_1.Role.fromRoleArn(stack, stack.genId('authenticated-role'), roleArn);
124
+ authRole.attachInlinePolicy(new aws_iam_1.Policy(stack, stack.genId('api-access-policy'), {
125
+ statements: [policyStatement]
126
+ }));
127
+ return policyStatement;
128
+ }
129
+ path(uri) {
130
+ const { node } = uri.split('/').reduce((resource, path) => {
131
+ if (!resource.children[path]) {
132
+ resource.children[path] = {
133
+ children: {},
134
+ node: resource.node.addResource(path)
135
+ };
136
+ }
137
+ return resource.children[path];
138
+ }, this._tree);
139
+ return node;
140
+ }
141
+ }
142
+ exports.RestApi = RestApi;
package/lib/Role.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IPrincipal, Role as CdkRole } from "aws-cdk-lib/aws-iam";
2
2
  import { Duration } from "aws-cdk-lib";
3
- import { IDeployStack } from "./IDeployStack";
3
+ import { DeployStack } from "./DeployStack";
4
4
  import { IManagedPolicy } from "aws-cdk-lib/aws-iam/lib/managed-policy";
5
5
  import { PolicyDocument } from "aws-cdk-lib/aws-iam/lib/policy-document";
6
6
  interface IRoleProps {
@@ -134,6 +134,6 @@ interface IRoleProps {
134
134
  readonly description?: string;
135
135
  }
136
136
  export declare class Role extends CdkRole {
137
- constructor(stack: IDeployStack, id: string, props: IRoleProps);
137
+ constructor(stack: DeployStack, id: string, props: IRoleProps);
138
138
  }
139
139
  export {};
package/lib/Role.js CHANGED
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Role = void 0;
4
4
  const aws_iam_1 = require("aws-cdk-lib/aws-iam");
5
- const aws_cdk_lib_1 = require("aws-cdk-lib");
5
+ const Output_1 = require("./Output");
6
6
  class Role extends aws_iam_1.Role {
7
7
  constructor(stack, id, props) {
8
8
  console.log('Defining Role', stack.genId(id));
@@ -21,10 +21,7 @@ class Role extends aws_iam_1.Role {
21
21
  roleName: stack.genName(props.roleName || id),
22
22
  assumedBy: props.assumedBy
23
23
  });
24
- new aws_cdk_lib_1.CfnOutput(stack, stack.genId(id, 'arn-output'), {
25
- value: this.roleArn,
26
- exportName: stack.genName(id, 'arn')
27
- });
24
+ new Output_1.Output(stack, `${id}-arn`, this.roleArn);
28
25
  }
29
26
  }
30
27
  exports.Role = Role;
@@ -0,0 +1,18 @@
1
+ import { DeployStack } from "./DeployStack";
2
+ import { IStringParameter } from "aws-cdk-lib/aws-ssm";
3
+ import { IGrantable } from "aws-cdk-lib/aws-iam";
4
+ import { IKey } from "aws-cdk-lib/aws-kms";
5
+ interface SsmParameterOptions {
6
+ decryptWithKey?: IKey;
7
+ }
8
+ export declare class SsmParameter {
9
+ parameterName: string;
10
+ parameterArn: string;
11
+ decryptWithKey?: IKey;
12
+ _stack: DeployStack;
13
+ constructor(stack: DeployStack, name: string, options?: SsmParameterOptions);
14
+ grantRead(grantee: IGrantable): void;
15
+ get stringValue(): string;
16
+ getParameter(): IStringParameter;
17
+ }
18
+ export {};
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SsmParameter = void 0;
4
+ const aws_ssm_1 = require("aws-cdk-lib/aws-ssm");
5
+ const aws_iam_1 = require("aws-cdk-lib/aws-iam");
6
+ const paramCache = {};
7
+ class SsmParameter {
8
+ parameterName;
9
+ parameterArn;
10
+ decryptWithKey;
11
+ _stack;
12
+ constructor(stack, name, options) {
13
+ if (name[0] !== '/')
14
+ name = '/' + name;
15
+ this.parameterName = `/${stack.name}${name}`;
16
+ this.parameterArn = `arn:aws:ssm:${stack.region}:${stack.account}:parameter${this.parameterName}`;
17
+ this._stack = stack;
18
+ this.decryptWithKey = options?.decryptWithKey;
19
+ }
20
+ grantRead(grantee) {
21
+ grantee.grantPrincipal.addToPrincipalPolicy(new aws_iam_1.PolicyStatement({
22
+ effect: aws_iam_1.Effect.ALLOW,
23
+ actions: ['ssm:GetParameter'],
24
+ resources: [this.parameterArn]
25
+ }));
26
+ if (this.decryptWithKey) {
27
+ this.decryptWithKey.grantDecrypt(grantee);
28
+ }
29
+ }
30
+ get stringValue() {
31
+ return this.getParameter().stringValue;
32
+ }
33
+ getParameter() {
34
+ if (!paramCache[this.parameterArn]) {
35
+ paramCache[this.parameterArn] = aws_ssm_1.StringParameter.fromStringParameterName(this._stack, this._stack.genId(this.parameterName.substring(1).replace('/', '_')), this.parameterName);
36
+ }
37
+ return paramCache[this.parameterArn];
38
+ }
39
+ }
40
+ exports.SsmParameter = SsmParameter;