@guardian/cdk 48.3.0 → 48.4.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.
@@ -22,7 +22,7 @@ class GuDnsRecordSet extends constructs_1.Construct {
22
22
  `id`, by definition, must be unique. `name` represents a fully qualified domain name, which must also be unique.
23
23
  `id` being given to the level 1 construct means it also becomes the logicalId in the template.
24
24
  */
25
- const level2ConstructId = name;
25
+ const level2ConstructId = `${name}-DnsRecordSet`;
26
26
  const level1ConstructId = id;
27
27
  super(scope, level2ConstructId);
28
28
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- more `RecordType`s will be added soon!
@@ -1 +1 @@
1
- {"version":3,"file":"dns-records.js","sourceRoot":"","sources":["../../../src/constructs/dns/dns-records.ts"],"names":[],"mappings":";;;AACA,6CAA0C;AAC1C,2CAAuC;AAIvC,IAAY,UAEX;AAFD,WAAY,UAAU;IACpB,6BAAe,CAAA;AACjB,CAAC,EAFW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAErB;AASD;;;;;GAKG;AACH,MAAa,cAAe,SAAQ,sBAAS;IAC3C,YAAY,KAAc,EAAE,EAAU,EAAE,KAA0B;QAChE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QACzD,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;QAExB;;;;WAIG;QACH,MAAM,iBAAiB,GAAG,IAAI,CAAC;QAC/B,MAAM,iBAAiB,GAAG,EAAE,CAAC;QAE7B,KAAK,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAEhC,iHAAiH;QACjH,IAAI,UAAU,KAAK,UAAU,CAAC,KAAK,EAAE;YACnC;;;;;;;;eAQG;YACH,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;gBAChC,MAAM,IAAI,KAAK,CACb,qHAAqH,CACtH,CAAC;aACH;SACF;QAED,6DAA6D;QAC7D,gHAAgH;QAChH,IAAI,yBAAW,CAAC,KAAK,EAAE,iBAAiB,EAAE;YACxC,IAAI,EAAE,0BAA0B;YAChC,UAAU,EAAE;gBACV,IAAI,EAAE,IAAI;gBACV,eAAe,EAAE,eAAe;gBAChC,UAAU,EAAE,UAAU;gBACtB,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE;gBACpB,KAAK,EAAE,KAAK;aACb;SACF,CAAC,CAAC;IACL,CAAC;CACF;AA9CD,wCA8CC;AASD;;;;GAIG;AACH,MAAa,OAAQ,SAAQ,cAAc;IACzC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAmB;QACzD,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QAExD,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACf,IAAI;YACJ,UAAU,EAAE,UAAU,CAAC,KAAK;YAC5B,eAAe,EAAE,CAAC,cAAc,CAAC;YACjC,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;CACF;AAXD,0BAWC","sourcesContent":["import type { Duration } from \"aws-cdk-lib\";\nimport { CfnResource } from \"aws-cdk-lib\";\nimport { Construct } from \"constructs\";\nimport type { GuDomainName } from \"../../types\";\nimport type { AppIdentity, GuStack } from \"../core\";\n\nexport enum RecordType {\n CNAME = \"CNAME\",\n}\n\nexport interface GuDnsRecordSetProps {\n name: string;\n recordType: RecordType;\n resourceRecords: string[];\n ttl: Duration;\n}\n\n/**\n * This construct can be used to create DNS records in NS1.\n *\n * Prefer to use [[`GuCname`]] when creating a CNAME for a load balancer,\n * as this requires less boilerplate.\n */\nexport class GuDnsRecordSet extends Construct {\n constructor(scope: GuStack, id: string, props: GuDnsRecordSetProps) {\n const { name, recordType, resourceRecords, ttl } = props;\n const { stage } = scope;\n\n /*\n Nodes in the CDK tree must have a unique ID. This class adds two nodes to the tree, so we have two IDs.\n `id`, by definition, must be unique. `name` represents a fully qualified domain name, which must also be unique.\n `id` being given to the level 1 construct means it also becomes the logicalId in the template.\n */\n const level2ConstructId = name;\n const level1ConstructId = id;\n\n super(scope, level2ConstructId);\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- more `RecordType`s will be added soon!\n if (recordType === RecordType.CNAME) {\n /*\n If you try to create a CNAME with multiple records within NS1, you are greeted with:\n\n According to RFC, a CNAME record should not return multiple answers.\n Doing so may cause problems during resolution.\n If you want to use multiple answers, you should ensure you have the correct filters in place (such as SELECT_FIRST_N 1) to limit them to a single answer at resolution time.\n\n `Guardian::DNS::RecordSet` does not implement \"correct filters\", so fail fast by throwing.\n */\n if (resourceRecords.length !== 1) {\n throw new Error(\n \"According to RFC, a CNAME record should not return multiple answers. Doing so may cause problems during resolution.\"\n );\n }\n }\n\n // The spec for this private resource type can be found here:\n // https://github.com/guardian/cfn-private-resource-types/tree/main/dns/guardian-dns-record-set-type/docs#syntax\n new CfnResource(scope, level1ConstructId, {\n type: \"Guardian::DNS::RecordSet\",\n properties: {\n Name: name,\n ResourceRecords: resourceRecords,\n RecordType: recordType,\n TTL: ttl.toSeconds(),\n Stage: stage,\n },\n });\n }\n}\n\nexport interface GuCnameProps extends GuDomainName, AppIdentity {\n /** The record your CNAME should point to, for example your Load Balancer DNS name */\n resourceRecord: string;\n /** The time to live for the DNS record */\n ttl: Duration;\n}\n\n/**\n * Construct for creating CNAME records in NS1.\n *\n * See [[`GuCnameProps`]] for configuration options.\n */\nexport class GuCname extends GuDnsRecordSet {\n constructor(scope: GuStack, id: string, props: GuCnameProps) {\n const { domainName: name, resourceRecord, ttl } = props;\n\n super(scope, id, {\n name,\n recordType: RecordType.CNAME,\n resourceRecords: [resourceRecord],\n ttl,\n });\n }\n}\n"]}
1
+ {"version":3,"file":"dns-records.js","sourceRoot":"","sources":["../../../src/constructs/dns/dns-records.ts"],"names":[],"mappings":";;;AACA,6CAA0C;AAC1C,2CAAuC;AAIvC,IAAY,UAEX;AAFD,WAAY,UAAU;IACpB,6BAAe,CAAA;AACjB,CAAC,EAFW,UAAU,GAAV,kBAAU,KAAV,kBAAU,QAErB;AASD;;;;;GAKG;AACH,MAAa,cAAe,SAAQ,sBAAS;IAC3C,YAAY,KAAc,EAAE,EAAU,EAAE,KAA0B;QAChE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,eAAe,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QACzD,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;QAExB;;;;WAIG;QACH,MAAM,iBAAiB,GAAG,GAAG,IAAI,eAAe,CAAC;QACjD,MAAM,iBAAiB,GAAG,EAAE,CAAC;QAE7B,KAAK,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAEhC,iHAAiH;QACjH,IAAI,UAAU,KAAK,UAAU,CAAC,KAAK,EAAE;YACnC;;;;;;;;eAQG;YACH,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE;gBAChC,MAAM,IAAI,KAAK,CACb,qHAAqH,CACtH,CAAC;aACH;SACF;QAED,6DAA6D;QAC7D,gHAAgH;QAChH,IAAI,yBAAW,CAAC,KAAK,EAAE,iBAAiB,EAAE;YACxC,IAAI,EAAE,0BAA0B;YAChC,UAAU,EAAE;gBACV,IAAI,EAAE,IAAI;gBACV,eAAe,EAAE,eAAe;gBAChC,UAAU,EAAE,UAAU;gBACtB,GAAG,EAAE,GAAG,CAAC,SAAS,EAAE;gBACpB,KAAK,EAAE,KAAK;aACb;SACF,CAAC,CAAC;IACL,CAAC;CACF;AA9CD,wCA8CC;AASD;;;;GAIG;AACH,MAAa,OAAQ,SAAQ,cAAc;IACzC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAmB;QACzD,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;QAExD,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACf,IAAI;YACJ,UAAU,EAAE,UAAU,CAAC,KAAK;YAC5B,eAAe,EAAE,CAAC,cAAc,CAAC;YACjC,GAAG;SACJ,CAAC,CAAC;IACL,CAAC;CACF;AAXD,0BAWC","sourcesContent":["import type { Duration } from \"aws-cdk-lib\";\nimport { CfnResource } from \"aws-cdk-lib\";\nimport { Construct } from \"constructs\";\nimport type { GuDomainName } from \"../../types\";\nimport type { AppIdentity, GuStack } from \"../core\";\n\nexport enum RecordType {\n CNAME = \"CNAME\",\n}\n\nexport interface GuDnsRecordSetProps {\n name: string;\n recordType: RecordType;\n resourceRecords: string[];\n ttl: Duration;\n}\n\n/**\n * This construct can be used to create DNS records in NS1.\n *\n * Prefer to use [[`GuCname`]] when creating a CNAME for a load balancer,\n * as this requires less boilerplate.\n */\nexport class GuDnsRecordSet extends Construct {\n constructor(scope: GuStack, id: string, props: GuDnsRecordSetProps) {\n const { name, recordType, resourceRecords, ttl } = props;\n const { stage } = scope;\n\n /*\n Nodes in the CDK tree must have a unique ID. This class adds two nodes to the tree, so we have two IDs.\n `id`, by definition, must be unique. `name` represents a fully qualified domain name, which must also be unique.\n `id` being given to the level 1 construct means it also becomes the logicalId in the template.\n */\n const level2ConstructId = `${name}-DnsRecordSet`;\n const level1ConstructId = id;\n\n super(scope, level2ConstructId);\n\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- more `RecordType`s will be added soon!\n if (recordType === RecordType.CNAME) {\n /*\n If you try to create a CNAME with multiple records within NS1, you are greeted with:\n\n According to RFC, a CNAME record should not return multiple answers.\n Doing so may cause problems during resolution.\n If you want to use multiple answers, you should ensure you have the correct filters in place (such as SELECT_FIRST_N 1) to limit them to a single answer at resolution time.\n\n `Guardian::DNS::RecordSet` does not implement \"correct filters\", so fail fast by throwing.\n */\n if (resourceRecords.length !== 1) {\n throw new Error(\n \"According to RFC, a CNAME record should not return multiple answers. Doing so may cause problems during resolution.\"\n );\n }\n }\n\n // The spec for this private resource type can be found here:\n // https://github.com/guardian/cfn-private-resource-types/tree/main/dns/guardian-dns-record-set-type/docs#syntax\n new CfnResource(scope, level1ConstructId, {\n type: \"Guardian::DNS::RecordSet\",\n properties: {\n Name: name,\n ResourceRecords: resourceRecords,\n RecordType: recordType,\n TTL: ttl.toSeconds(),\n Stage: stage,\n },\n });\n }\n}\n\nexport interface GuCnameProps extends GuDomainName, AppIdentity {\n /** The record your CNAME should point to, for example your Load Balancer DNS name */\n resourceRecord: string;\n /** The time to live for the DNS record */\n ttl: Duration;\n}\n\n/**\n * Construct for creating CNAME records in NS1.\n *\n * See [[`GuCnameProps`]] for configuration options.\n */\nexport class GuCname extends GuDnsRecordSet {\n constructor(scope: GuStack, id: string, props: GuCnameProps) {\n const { domainName: name, resourceRecord, ttl } = props;\n\n super(scope, id, {\n name,\n recordType: RecordType.CNAME,\n resourceRecords: [resourceRecord],\n ttl,\n });\n }\n}\n"]}
@@ -18,6 +18,10 @@ export interface ApiTarget {
18
18
  * The Lambda function responsible for handling the request.
19
19
  */
20
20
  lambda: GuLambdaFunction;
21
+ /**
22
+ * Whether an apiKey is required for this method.
23
+ */
24
+ apiKeyRequired?: true;
21
25
  }
22
26
  /**
23
27
  * Configuration for an alarm based on the percentage of 5XX responses served by the API Gateway instance.
@@ -1 +1 @@
1
- {"version":3,"file":"api-multiple-lambdas.d.ts","sourceRoot":"","sources":["../../src/patterns/api-multiple-lambdas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAqB,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,oBAAY,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAEhH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,UAAU,EAAE,UAAU,CAAC;IACvB;;OAEG;IACH,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,iBAAiB,CAAC;IAChC,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,iCAAkC,SAAQ,YAAY,EAAE,WAAW;IAClF;;OAEG;IACH,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB;;;;;;;OAOG;IACH,uBAAuB,EAAE,YAAY,GAAG,gBAAgB,CAAC;CAC1D;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,qBAAa,4BAA6B,SAAQ,SAAS;IACzD,SAAgB,GAAG,EAAE,OAAO,CAAC;gBAEjB,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,iCAAiC;CAsBrE"}
1
+ {"version":3,"file":"api-multiple-lambdas.d.ts","sourceRoot":"","sources":["../../src/patterns/api-multiple-lambdas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAqB,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,oBAAY,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAEhH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,UAAU,EAAE,UAAU,CAAC;IACvB;;OAEG;IACH,MAAM,EAAE,gBAAgB,CAAC;IACzB;;OAEG;IACH,cAAc,CAAC,EAAE,IAAI,CAAC;CACvB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,iBAAiB,CAAC;IAChC,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,iCAAkC,SAAQ,YAAY,EAAE,WAAW;IAClF;;OAEG;IACH,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB;;;;;;;OAOG;IACH,uBAAuB,EAAE,YAAY,GAAG,gBAAgB,CAAC;CAC1D;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,qBAAa,4BAA6B,SAAQ,SAAS;IACzD,SAAgB,GAAG,EAAE,OAAO,CAAC;gBAEjB,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,iCAAiC;CAwBrE"}
@@ -72,7 +72,9 @@ class GuApiGatewayWithLambdaByPath extends constructs_1.Construct {
72
72
  this.api = apiGateway;
73
73
  props.targets.map((target) => {
74
74
  const resource = apiGateway.root.resourceForPath(target.path);
75
- resource.addMethod(target.httpMethod, new aws_apigateway_1.LambdaIntegration(target.lambda));
75
+ resource.addMethod(target.httpMethod, new aws_apigateway_1.LambdaIntegration(target.lambda), {
76
+ apiKeyRequired: target.apiKeyRequired,
77
+ });
76
78
  });
77
79
  if (!isNoMonitoring(props.monitoringConfiguration)) {
78
80
  new api_gateway_alarms_1.GuApiGateway5xxPercentageAlarm(scope, {
@@ -1 +1 @@
1
- {"version":3,"file":"api-multiple-lambdas.js","sourceRoot":"","sources":["../../src/patterns/api-multiple-lambdas.ts"],"names":[],"mappings":";;;AACA,+DAAwE;AACxE,2CAAuC;AAEvC,oFAA6F;AA0D7F,SAAS,cAAc,CACrB,uBAAwD;IAExD,OAAsB,uBAAwB,CAAC,YAAY,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAa,4BAA6B,SAAQ,sBAAS;IAGzD,YAAY,KAAc,EAAE,KAAwC;QAClE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,oCAAoC;QAC7D,MAAM,UAAU,GAAG,IAAI,wBAAO,CAAC,KAAK,EAAE,SAAS,EAAE;YAC/C,4FAA4F;YAC5F,WAAW,EAAE,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,EAAE;YACzD,GAAG,KAAK;SACT,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC;QACtB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC3B,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9D,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,kCAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9E,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE;YAClD,IAAI,mDAA8B,CAAC,KAAK,EAAE;gBACxC,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,kBAAkB,EAAE,UAAU;gBAC9B,YAAY,EAAE,KAAK,CAAC,uBAAuB,CAAC,YAAY;gBACxD,GAAG,KAAK,CAAC,uBAAuB,CAAC,YAAY;aAC9C,CAAC,CAAC;SACJ;IACH,CAAC;CACF;AAzBD,oEAyBC","sourcesContent":["import type { RestApiProps } from \"aws-cdk-lib/aws-apigateway\";\nimport { LambdaIntegration, RestApi } from \"aws-cdk-lib/aws-apigateway\";\nimport { Construct } from \"constructs\";\nimport type { Http5xxAlarmProps, NoMonitoring } from \"../constructs/cloudwatch\";\nimport { GuApiGateway5xxPercentageAlarm } from \"../constructs/cloudwatch/api-gateway-alarms\";\nimport type { AppIdentity, GuStack } from \"../constructs/core\";\nimport type { GuLambdaFunction } from \"../constructs/lambda\";\n\n// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods\nexport type HttpMethod = \"GET\" | \"HEAD\" | \"POST\" | \"PUT\" | \"DELETE\" | \"CONNECT\" | \"OPTIONS\" | \"TRACE\" | \"PATCH\";\n\nexport interface ApiTarget {\n /**\n * The path for the request (e.g. /test).\n */\n path: string;\n /**\n * The [[`HttpMethod`]] for the target (e.g. GET, POST, PUT).\n */\n httpMethod: HttpMethod;\n /**\n * The Lambda function responsible for handling the request.\n */\n lambda: GuLambdaFunction;\n}\n\n/**\n * Configuration for an alarm based on the percentage of 5XX responses served by the API Gateway instance.\n *\n * For example:\n *\n * ```typescript\n * monitoringConfiguration: {\n * snsTopicName: \"my-topic-for-cloudwatch-alerts\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: <sensible_error_percentage_threshold>,\n * }\n * }\n * ```\n */\nexport interface ApiGatewayAlarms {\n snsTopicName: string;\n http5xxAlarm: Http5xxAlarmProps;\n noMonitoring?: false;\n}\n\nexport interface GuApiGatewayWithLambdaByPathProps extends RestApiProps, AppIdentity {\n /**\n * A list of [[`ApiTarget`]]s to configure for the API Gateway instance.\n */\n targets: ApiTarget[];\n /**\n * Alarm configuration for your API. For more details, see [[`ApiGatewayAlarms`]].\n *\n * If your team do not use CloudWatch, it's possible to opt-out with the following configuration:\n * ```typescript\n * monitoringConfiguration: { noMonitoring: true }\n * ```\n */\n monitoringConfiguration: NoMonitoring | ApiGatewayAlarms;\n}\n\nfunction isNoMonitoring(\n monitoringConfiguration: NoMonitoring | ApiGatewayAlarms\n): monitoringConfiguration is NoMonitoring {\n return (<NoMonitoring>monitoringConfiguration).noMonitoring;\n}\n\n/**\n * A pattern to create an API Gateway instance which uses path-based routing to route requests\n * to two or more Lambda functions.\n *\n * This pattern should be used if you need to configure path-based routing to serve different\n * requests with different Lambdas. If you intend to serve all traffic via a single Lambda, use\n * the [[`GuApiLambda`]] pattern instead.\n *\n * Example usage:\n *\n * ```typescript\n * // Configure lambdas\n * const lambdaOne = new GuLambdaFunction(this, \"lambda-one\", {\n * app: \"example-lambda-one\",\n * runtime: Runtime.NODEJS_14_X,\n * handler: \"lambda-one.handler\",\n * fileName: \"lambda-one.zip\",\n * });\n * const lambdaTwo = new GuLambdaFunction(this, \"lambda-two\", {\n * app: \"example-lambda-two\",\n * runtime: Runtime.NODEJS_14_X,\n * handler: \"lambda-two.handler\",\n * fileName: \"lambda-two.zip\",\n * });\n *\n * // Wire up the API\n * new GuApiGatewayWithLambdaByPath(this, {\n * app: \"example-api-gateway-instance\",\n * targets: [\n * {\n * path: \"lambda-one\",\n * httpMethod: \"GET\",\n * lambda: lambdaOne,\n * },\n * {\n * path: \"lambda-two\",\n * httpMethod: \"GET\",\n * lambda: lambdaTwo,\n * },\n * ],\n * // Create an alarm\n * monitoringConfiguration: {\n * snsTopicName: \"my-topic-for-cloudwatch-alerts\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: 1,\n * }\n * }\n * });\n * ```\n *\n * For all API configuration options, see [[`GuApiGatewayWithLambdaByPathProps`]].\n *\n * For details on configuring the individual Lambda functions, see [[`GuLambdaFunction`]].\n */\nexport class GuApiGatewayWithLambdaByPath extends Construct {\n public readonly api: RestApi;\n\n constructor(scope: GuStack, props: GuApiGatewayWithLambdaByPathProps) {\n super(scope, props.app); // The assumption is `app` is unique\n const apiGateway = new RestApi(scope, \"RestApi\", {\n // Override to avoid clashes as default is just api ID, which is often shared across stages.\n restApiName: `${scope.stack}-${scope.stage}-${props.app}`,\n ...props,\n });\n\n this.api = apiGateway;\n props.targets.map((target) => {\n const resource = apiGateway.root.resourceForPath(target.path);\n resource.addMethod(target.httpMethod, new LambdaIntegration(target.lambda));\n });\n if (!isNoMonitoring(props.monitoringConfiguration)) {\n new GuApiGateway5xxPercentageAlarm(scope, {\n app: props.app,\n apiGatewayInstance: apiGateway,\n snsTopicName: props.monitoringConfiguration.snsTopicName,\n ...props.monitoringConfiguration.http5xxAlarm,\n });\n }\n }\n}\n"]}
1
+ {"version":3,"file":"api-multiple-lambdas.js","sourceRoot":"","sources":["../../src/patterns/api-multiple-lambdas.ts"],"names":[],"mappings":";;;AACA,+DAAwE;AACxE,2CAAuC;AAEvC,oFAA6F;AA8D7F,SAAS,cAAc,CACrB,uBAAwD;IAExD,OAAsB,uBAAwB,CAAC,YAAY,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAa,4BAA6B,SAAQ,sBAAS;IAGzD,YAAY,KAAc,EAAE,KAAwC;QAClE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,oCAAoC;QAC7D,MAAM,UAAU,GAAG,IAAI,wBAAO,CAAC,KAAK,EAAE,SAAS,EAAE;YAC/C,4FAA4F;YAC5F,WAAW,EAAE,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,EAAE;YACzD,GAAG,KAAK;SACT,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC;QACtB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC3B,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9D,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,kCAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;gBAC1E,cAAc,EAAE,MAAM,CAAC,cAAc;aACtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE;YAClD,IAAI,mDAA8B,CAAC,KAAK,EAAE;gBACxC,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,kBAAkB,EAAE,UAAU;gBAC9B,YAAY,EAAE,KAAK,CAAC,uBAAuB,CAAC,YAAY;gBACxD,GAAG,KAAK,CAAC,uBAAuB,CAAC,YAAY;aAC9C,CAAC,CAAC;SACJ;IACH,CAAC;CACF;AA3BD,oEA2BC","sourcesContent":["import type { RestApiProps } from \"aws-cdk-lib/aws-apigateway\";\nimport { LambdaIntegration, RestApi } from \"aws-cdk-lib/aws-apigateway\";\nimport { Construct } from \"constructs\";\nimport type { Http5xxAlarmProps, NoMonitoring } from \"../constructs/cloudwatch\";\nimport { GuApiGateway5xxPercentageAlarm } from \"../constructs/cloudwatch/api-gateway-alarms\";\nimport type { AppIdentity, GuStack } from \"../constructs/core\";\nimport type { GuLambdaFunction } from \"../constructs/lambda\";\n\n// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods\nexport type HttpMethod = \"GET\" | \"HEAD\" | \"POST\" | \"PUT\" | \"DELETE\" | \"CONNECT\" | \"OPTIONS\" | \"TRACE\" | \"PATCH\";\n\nexport interface ApiTarget {\n /**\n * The path for the request (e.g. /test).\n */\n path: string;\n /**\n * The [[`HttpMethod`]] for the target (e.g. GET, POST, PUT).\n */\n httpMethod: HttpMethod;\n /**\n * The Lambda function responsible for handling the request.\n */\n lambda: GuLambdaFunction;\n /**\n * Whether an apiKey is required for this method.\n */\n apiKeyRequired?: true;\n}\n\n/**\n * Configuration for an alarm based on the percentage of 5XX responses served by the API Gateway instance.\n *\n * For example:\n *\n * ```typescript\n * monitoringConfiguration: {\n * snsTopicName: \"my-topic-for-cloudwatch-alerts\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: <sensible_error_percentage_threshold>,\n * }\n * }\n * ```\n */\nexport interface ApiGatewayAlarms {\n snsTopicName: string;\n http5xxAlarm: Http5xxAlarmProps;\n noMonitoring?: false;\n}\n\nexport interface GuApiGatewayWithLambdaByPathProps extends RestApiProps, AppIdentity {\n /**\n * A list of [[`ApiTarget`]]s to configure for the API Gateway instance.\n */\n targets: ApiTarget[];\n /**\n * Alarm configuration for your API. For more details, see [[`ApiGatewayAlarms`]].\n *\n * If your team do not use CloudWatch, it's possible to opt-out with the following configuration:\n * ```typescript\n * monitoringConfiguration: { noMonitoring: true }\n * ```\n */\n monitoringConfiguration: NoMonitoring | ApiGatewayAlarms;\n}\n\nfunction isNoMonitoring(\n monitoringConfiguration: NoMonitoring | ApiGatewayAlarms\n): monitoringConfiguration is NoMonitoring {\n return (<NoMonitoring>monitoringConfiguration).noMonitoring;\n}\n\n/**\n * A pattern to create an API Gateway instance which uses path-based routing to route requests\n * to two or more Lambda functions.\n *\n * This pattern should be used if you need to configure path-based routing to serve different\n * requests with different Lambdas. If you intend to serve all traffic via a single Lambda, use\n * the [[`GuApiLambda`]] pattern instead.\n *\n * Example usage:\n *\n * ```typescript\n * // Configure lambdas\n * const lambdaOne = new GuLambdaFunction(this, \"lambda-one\", {\n * app: \"example-lambda-one\",\n * runtime: Runtime.NODEJS_14_X,\n * handler: \"lambda-one.handler\",\n * fileName: \"lambda-one.zip\",\n * });\n * const lambdaTwo = new GuLambdaFunction(this, \"lambda-two\", {\n * app: \"example-lambda-two\",\n * runtime: Runtime.NODEJS_14_X,\n * handler: \"lambda-two.handler\",\n * fileName: \"lambda-two.zip\",\n * });\n *\n * // Wire up the API\n * new GuApiGatewayWithLambdaByPath(this, {\n * app: \"example-api-gateway-instance\",\n * targets: [\n * {\n * path: \"lambda-one\",\n * httpMethod: \"GET\",\n * lambda: lambdaOne,\n * },\n * {\n * path: \"lambda-two\",\n * httpMethod: \"GET\",\n * lambda: lambdaTwo,\n * },\n * ],\n * // Create an alarm\n * monitoringConfiguration: {\n * snsTopicName: \"my-topic-for-cloudwatch-alerts\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: 1,\n * }\n * }\n * });\n * ```\n *\n * For all API configuration options, see [[`GuApiGatewayWithLambdaByPathProps`]].\n *\n * For details on configuring the individual Lambda functions, see [[`GuLambdaFunction`]].\n */\nexport class GuApiGatewayWithLambdaByPath extends Construct {\n public readonly api: RestApi;\n\n constructor(scope: GuStack, props: GuApiGatewayWithLambdaByPathProps) {\n super(scope, props.app); // The assumption is `app` is unique\n const apiGateway = new RestApi(scope, \"RestApi\", {\n // Override to avoid clashes as default is just api ID, which is often shared across stages.\n restApiName: `${scope.stack}-${scope.stage}-${props.app}`,\n ...props,\n });\n\n this.api = apiGateway;\n props.targets.map((target) => {\n const resource = apiGateway.root.resourceForPath(target.path);\n resource.addMethod(target.httpMethod, new LambdaIntegration(target.lambda), {\n apiKeyRequired: target.apiKeyRequired,\n });\n });\n if (!isNoMonitoring(props.monitoringConfiguration)) {\n new GuApiGateway5xxPercentageAlarm(scope, {\n app: props.app,\n apiGatewayInstance: apiGateway,\n snsTopicName: props.monitoringConfiguration.snsTopicName,\n ...props.monitoringConfiguration.http5xxAlarm,\n });\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@guardian/cdk",
3
3
  "description": "Generic Guardian flavoured AWS CDK components",
4
- "version": "48.3.0",
4
+ "version": "48.4.0",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "files": [