@jaypie/constructs 1.2.41 → 1.2.43
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/cjs/JaypieApiGateway.d.ts +9 -0
- package/dist/cjs/JaypieDistribution.d.ts +9 -0
- package/dist/cjs/JaypieDynamoDb.d.ts +11 -16
- package/dist/cjs/index.cjs +32 -34
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/JaypieApiGateway.d.ts +9 -0
- package/dist/esm/JaypieDistribution.d.ts +9 -0
- package/dist/esm/JaypieDynamoDb.d.ts +11 -16
- package/dist/esm/index.js +33 -35
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -6,6 +6,15 @@ import * as route53 from "aws-cdk-lib/aws-route53";
|
|
|
6
6
|
import { HostConfig } from "./helpers";
|
|
7
7
|
export interface JaypieApiGatewayProps extends apiGateway.LambdaRestApiProps {
|
|
8
8
|
certificate?: boolean | acm.ICertificate;
|
|
9
|
+
/**
|
|
10
|
+
* Force-delete any existing Route53 A record with the same name before
|
|
11
|
+
* creating the alias record. Useful when migrating from another construct
|
|
12
|
+
* (e.g., JaypieDistribution) that already owns the same hostname, where the
|
|
13
|
+
* default CloudFormation create-before-delete ordering would otherwise
|
|
14
|
+
* collide on the record name.
|
|
15
|
+
* @default false
|
|
16
|
+
*/
|
|
17
|
+
deleteExistingRecord?: boolean;
|
|
9
18
|
/**
|
|
10
19
|
* The domain name for the API Gateway.
|
|
11
20
|
*
|
|
@@ -66,6 +66,15 @@ export interface JaypieDistributionProps extends Omit<cloudfront.DistributionPro
|
|
|
66
66
|
* Override default behavior (optional if handler is provided)
|
|
67
67
|
*/
|
|
68
68
|
defaultBehavior?: cloudfront.BehaviorOptions;
|
|
69
|
+
/**
|
|
70
|
+
* Force-delete any existing Route53 A and AAAA records with the same name
|
|
71
|
+
* before creating the alias records. Useful when migrating from another
|
|
72
|
+
* construct (e.g., JaypieApiGateway) that already owns the same hostname,
|
|
73
|
+
* where the default CloudFormation create-before-delete ordering would
|
|
74
|
+
* otherwise collide on the record name.
|
|
75
|
+
* @default false
|
|
76
|
+
*/
|
|
77
|
+
deleteExistingRecord?: boolean;
|
|
69
78
|
/**
|
|
70
79
|
* Log destination configuration for CloudFront access logs
|
|
71
80
|
* - LambdaDestination: Use a specific Lambda destination for S3 notifications
|
|
@@ -6,25 +6,23 @@ export interface JaypieDynamoDbProps extends Omit<dynamodb.TablePropsV2, "global
|
|
|
6
6
|
/**
|
|
7
7
|
* Configure GSIs for the table using @jaypie/fabric IndexDefinition format.
|
|
8
8
|
* - `undefined`: No GSIs (default)
|
|
9
|
-
* - Array of IndexDefinition: Use the specified indexes
|
|
9
|
+
* - Array of IndexDefinition: Use the specified indexes (prefer fabricIndex())
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
12
12
|
* // No GSIs (default)
|
|
13
13
|
* new JaypieDynamoDb(this, "myTable");
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
|
-
* // With
|
|
16
|
+
* // With fabricIndex-shaped indexes
|
|
17
|
+
* import { fabricIndex } from "@jaypie/fabric";
|
|
17
18
|
* new JaypieDynamoDb(this, "myTable", {
|
|
18
|
-
* indexes: [
|
|
19
|
-
* { pk: ["scope", "model"], sk: ["sequence"] },
|
|
20
|
-
* { pk: ["scope", "model", "type"], sk: ["sequence"], sparse: true },
|
|
21
|
-
* ],
|
|
19
|
+
* indexes: [fabricIndex(), fabricIndex("alias"), fabricIndex("xid")],
|
|
22
20
|
* });
|
|
23
21
|
*/
|
|
24
22
|
indexes?: IndexDefinition[];
|
|
25
23
|
/**
|
|
26
24
|
* Partition key attribute definition.
|
|
27
|
-
* @default { name: "
|
|
25
|
+
* @default { name: "id", type: AttributeType.STRING }
|
|
28
26
|
*/
|
|
29
27
|
partitionKey?: dynamodb.Attribute;
|
|
30
28
|
/**
|
|
@@ -40,8 +38,8 @@ export interface JaypieDynamoDbProps extends Omit<dynamodb.TablePropsV2, "global
|
|
|
40
38
|
*/
|
|
41
39
|
service?: string;
|
|
42
40
|
/**
|
|
43
|
-
* Sort key attribute definition.
|
|
44
|
-
*
|
|
41
|
+
* Sort key attribute definition. Defaults to `undefined` (no sort key) —
|
|
42
|
+
* the Jaypie single-table pattern uses `id` as a unique partition key.
|
|
45
43
|
*/
|
|
46
44
|
sortKey?: dynamodb.Attribute;
|
|
47
45
|
/**
|
|
@@ -53,8 +51,7 @@ export interface JaypieDynamoDbProps extends Omit<dynamodb.TablePropsV2, "global
|
|
|
53
51
|
* DynamoDB table with Jaypie single-table design patterns.
|
|
54
52
|
*
|
|
55
53
|
* Creates a table with:
|
|
56
|
-
* - Partition key: `
|
|
57
|
-
* - Sort key: `id` (String)
|
|
54
|
+
* - Partition key: `id` (String), no sort key
|
|
58
55
|
* - Billing: PAY_PER_REQUEST (on-demand)
|
|
59
56
|
* - Removal policy: RETAIN in production, DESTROY otherwise
|
|
60
57
|
* - No GSIs by default (use `indexes` prop to add them)
|
|
@@ -65,13 +62,11 @@ export interface JaypieDynamoDbProps extends Omit<dynamodb.TablePropsV2, "global
|
|
|
65
62
|
* const table = new JaypieDynamoDb(this, "myApp");
|
|
66
63
|
*
|
|
67
64
|
* @example
|
|
68
|
-
* // With
|
|
65
|
+
* // With fabricIndex() for GSIs
|
|
66
|
+
* import { fabricIndex } from "@jaypie/fabric";
|
|
69
67
|
* const table = new JaypieDynamoDb(this, "MyTable", {
|
|
70
68
|
* tableName: "custom-table-name",
|
|
71
|
-
* indexes: [
|
|
72
|
-
* { pk: ["scope", "model"] },
|
|
73
|
-
* { pk: ["scope", "model", "type"], sparse: true },
|
|
74
|
-
* ],
|
|
69
|
+
* indexes: [fabricIndex(), fabricIndex("alias"), fabricIndex("xid")],
|
|
75
70
|
* });
|
|
76
71
|
*/
|
|
77
72
|
export declare class JaypieDynamoDb extends Construct implements dynamodb.ITableV2 {
|
package/dist/esm/index.js
CHANGED
|
@@ -26,7 +26,7 @@ import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
|
|
|
26
26
|
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
|
|
27
27
|
import * as wafv2 from 'aws-cdk-lib/aws-wafv2';
|
|
28
28
|
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
|
|
29
|
-
import {
|
|
29
|
+
import { getGsiAttributeNames } from '@jaypie/fabric';
|
|
30
30
|
import * as cr from 'aws-cdk-lib/custom-resources';
|
|
31
31
|
import { Nextjs } from 'cdk-nextjs-standalone';
|
|
32
32
|
import * as path from 'path';
|
|
@@ -1134,7 +1134,7 @@ function clearAllSecretsCaches() {
|
|
|
1134
1134
|
class JaypieApiGateway extends Construct {
|
|
1135
1135
|
constructor(scope, id, props) {
|
|
1136
1136
|
super(scope, id);
|
|
1137
|
-
const { certificate = true, handler, host: propsHost, name, roleTag = CDK$2.ROLE.API, zone: propsZone, } = props;
|
|
1137
|
+
const { certificate = true, deleteExistingRecord = false, handler, host: propsHost, name, roleTag = CDK$2.ROLE.API, zone: propsZone, } = props;
|
|
1138
1138
|
// Determine zone from props or environment
|
|
1139
1139
|
let zone = propsZone;
|
|
1140
1140
|
if (!zone && process.env.CDK_ENV_API_HOSTED_ZONE) {
|
|
@@ -1180,7 +1180,7 @@ class JaypieApiGateway extends Construct {
|
|
|
1180
1180
|
// * `...lambdaRestApiProps` cannot be moved to the first const destructuring because it needs to exclude the custom properties first.
|
|
1181
1181
|
// Ignore the variables we already assigned to other properties
|
|
1182
1182
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
1183
|
-
certificate: _certificate, host: _host, name: _name, roleTag: _roleTag, zone: _zone, handler: _handler,
|
|
1183
|
+
certificate: _certificate, deleteExistingRecord: _deleteExistingRecord, host: _host, name: _name, roleTag: _roleTag, zone: _zone, handler: _handler,
|
|
1184
1184
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
1185
1185
|
...lambdaRestApiProps } = props;
|
|
1186
1186
|
this._api = new apiGateway.LambdaRestApi(this, apiGatewayName, {
|
|
@@ -1195,6 +1195,7 @@ class JaypieApiGateway extends Construct {
|
|
|
1195
1195
|
});
|
|
1196
1196
|
Tags.of(this._domainName).add(CDK$2.TAG.ROLE, roleTag);
|
|
1197
1197
|
const record = new route53.ARecord(this, "AliasRecord", {
|
|
1198
|
+
deleteExisting: deleteExistingRecord,
|
|
1198
1199
|
recordName: host,
|
|
1199
1200
|
target: route53.RecordTarget.fromAlias(new route53Targets.ApiGatewayDomain(this._domainName)),
|
|
1200
1201
|
zone: hostedZone,
|
|
@@ -2358,7 +2359,7 @@ const DEFAULT_MANAGED_RULES = [
|
|
|
2358
2359
|
class JaypieDistribution extends Construct {
|
|
2359
2360
|
constructor(scope, id, props) {
|
|
2360
2361
|
super(scope, id);
|
|
2361
|
-
const { certificate: certificateProp = true, defaultBehavior: propsDefaultBehavior, destination: destinationProp = true, handler, host: propsHost, logBucket: logBucketProp, originReadTimeout = Duration.seconds(CDK$2.DURATION.CLOUDFRONT_API), responseHeadersPolicy: responseHeadersPolicyProp, roleTag = CDK$2.ROLE.API, securityHeaders: securityHeadersProp, streaming = false, waf: wafProp = true, zone: propsZone, ...distributionProps } = props;
|
|
2362
|
+
const { certificate: certificateProp = true, defaultBehavior: propsDefaultBehavior, deleteExistingRecord = false, destination: destinationProp = true, handler, host: propsHost, logBucket: logBucketProp, originReadTimeout = Duration.seconds(CDK$2.DURATION.CLOUDFRONT_API), responseHeadersPolicy: responseHeadersPolicyProp, roleTag = CDK$2.ROLE.API, securityHeaders: securityHeadersProp, streaming = false, waf: wafProp = true, zone: propsZone, ...distributionProps } = props;
|
|
2362
2363
|
// Validate environment variables
|
|
2363
2364
|
if (process.env.CDK_ENV_API_SUBDOMAIN &&
|
|
2364
2365
|
!isValidSubdomain(process.env.CDK_ENV_API_SUBDOMAIN)) {
|
|
@@ -2718,12 +2719,14 @@ class JaypieDistribution extends Construct {
|
|
|
2718
2719
|
// Create DNS records if we have host and zone
|
|
2719
2720
|
if (host && hostedZone) {
|
|
2720
2721
|
const aRecord = new route53.ARecord(this, "AliasRecord", {
|
|
2722
|
+
deleteExisting: deleteExistingRecord,
|
|
2721
2723
|
recordName: host,
|
|
2722
2724
|
target: route53.RecordTarget.fromAlias(new route53Targets.CloudFrontTarget(this.distribution)),
|
|
2723
2725
|
zone: hostedZone,
|
|
2724
2726
|
});
|
|
2725
2727
|
Tags.of(aRecord).add(CDK$2.TAG.ROLE, CDK$2.ROLE.NETWORKING);
|
|
2726
2728
|
const aaaaRecord = new route53.AaaaRecord(this, "AaaaAliasRecord", {
|
|
2729
|
+
deleteExisting: deleteExistingRecord,
|
|
2727
2730
|
recordName: host,
|
|
2728
2731
|
target: route53.RecordTarget.fromAlias(new route53Targets.CloudFrontTarget(this.distribution)),
|
|
2729
2732
|
zone: hostedZone,
|
|
@@ -2892,41 +2895,39 @@ class JaypieDnsRecord extends Construct {
|
|
|
2892
2895
|
}
|
|
2893
2896
|
}
|
|
2894
2897
|
|
|
2895
|
-
//
|
|
2896
|
-
//
|
|
2897
|
-
// Constants
|
|
2898
|
-
//
|
|
2899
|
-
/** Composite key separator used in GSI partition keys */
|
|
2900
|
-
const SEPARATOR = "#";
|
|
2901
2898
|
//
|
|
2902
2899
|
//
|
|
2903
2900
|
// Helper Functions
|
|
2904
2901
|
//
|
|
2905
2902
|
/**
|
|
2906
|
-
* Convert IndexDefinition[] from @jaypie/fabric to CDK GlobalSecondaryIndexPropsV2[]
|
|
2903
|
+
* Convert IndexDefinition[] from @jaypie/fabric to CDK GlobalSecondaryIndexPropsV2[].
|
|
2907
2904
|
*
|
|
2908
|
-
*
|
|
2909
|
-
*
|
|
2905
|
+
* Uses `getGsiAttributeNames` as the single source of truth so runtime writes
|
|
2906
|
+
* and CDK provisioning agree on attribute names. Composite sk indexes
|
|
2907
|
+
* (sk.length > 1) get a dedicated STRING `{indexName}Sk` attribute; single-field
|
|
2908
|
+
* sk indexes reference the field directly (STRING in the general case, NUMBER
|
|
2909
|
+
* for the legacy `sequence` name).
|
|
2910
2910
|
*/
|
|
2911
2911
|
function indexesToGsi(indexes) {
|
|
2912
2912
|
return indexes.map((index) => {
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2913
|
+
const { pk, sk } = getGsiAttributeNames(index);
|
|
2914
|
+
let sortKey;
|
|
2915
|
+
if (sk) {
|
|
2916
|
+
if (sk === "sequence") {
|
|
2917
|
+
sortKey = { name: "sequence", type: dynamodb.AttributeType.NUMBER };
|
|
2918
|
+
}
|
|
2919
|
+
else {
|
|
2920
|
+
sortKey = { name: sk, type: dynamodb.AttributeType.STRING };
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2917
2923
|
return {
|
|
2918
|
-
indexName,
|
|
2924
|
+
indexName: pk,
|
|
2919
2925
|
partitionKey: {
|
|
2920
|
-
name:
|
|
2926
|
+
name: pk,
|
|
2921
2927
|
type: dynamodb.AttributeType.STRING,
|
|
2922
2928
|
},
|
|
2923
2929
|
projectionType: dynamodb.ProjectionType.ALL,
|
|
2924
|
-
sortKey
|
|
2925
|
-
? { name: "sequence", type: dynamodb.AttributeType.NUMBER }
|
|
2926
|
-
: {
|
|
2927
|
-
name: skFields.join(SEPARATOR),
|
|
2928
|
-
type: dynamodb.AttributeType.STRING,
|
|
2929
|
-
},
|
|
2930
|
+
...(sortKey && { sortKey }),
|
|
2930
2931
|
};
|
|
2931
2932
|
});
|
|
2932
2933
|
}
|
|
@@ -2938,8 +2939,7 @@ function indexesToGsi(indexes) {
|
|
|
2938
2939
|
* DynamoDB table with Jaypie single-table design patterns.
|
|
2939
2940
|
*
|
|
2940
2941
|
* Creates a table with:
|
|
2941
|
-
* - Partition key: `
|
|
2942
|
-
* - Sort key: `id` (String)
|
|
2942
|
+
* - Partition key: `id` (String), no sort key
|
|
2943
2943
|
* - Billing: PAY_PER_REQUEST (on-demand)
|
|
2944
2944
|
* - Removal policy: RETAIN in production, DESTROY otherwise
|
|
2945
2945
|
* - No GSIs by default (use `indexes` prop to add them)
|
|
@@ -2950,13 +2950,11 @@ function indexesToGsi(indexes) {
|
|
|
2950
2950
|
* const table = new JaypieDynamoDb(this, "myApp");
|
|
2951
2951
|
*
|
|
2952
2952
|
* @example
|
|
2953
|
-
* // With
|
|
2953
|
+
* // With fabricIndex() for GSIs
|
|
2954
|
+
* import { fabricIndex } from "@jaypie/fabric";
|
|
2954
2955
|
* const table = new JaypieDynamoDb(this, "MyTable", {
|
|
2955
2956
|
* tableName: "custom-table-name",
|
|
2956
|
-
* indexes: [
|
|
2957
|
-
* { pk: ["scope", "model"] },
|
|
2958
|
-
* { pk: ["scope", "model", "type"], sparse: true },
|
|
2959
|
-
* ],
|
|
2957
|
+
* indexes: [fabricIndex(), fabricIndex("alias"), fabricIndex("xid")],
|
|
2960
2958
|
* });
|
|
2961
2959
|
*/
|
|
2962
2960
|
class JaypieDynamoDb extends Construct {
|
|
@@ -2968,11 +2966,11 @@ class JaypieDynamoDb extends Construct {
|
|
|
2968
2966
|
const constructId = isShorthand ? `JaypieDynamoDb-${id}` : id;
|
|
2969
2967
|
super(scope, constructId);
|
|
2970
2968
|
const { billing = dynamodb.Billing.onDemand(), indexes, partitionKey = {
|
|
2971
|
-
name: "
|
|
2969
|
+
name: "id",
|
|
2972
2970
|
type: dynamodb.AttributeType.STRING,
|
|
2973
2971
|
}, project, removalPolicy = isProductionEnv()
|
|
2974
2972
|
? RemovalPolicy.RETAIN
|
|
2975
|
-
: RemovalPolicy.DESTROY, roleTag = CDK$2.ROLE.STORAGE, service, sortKey
|
|
2973
|
+
: RemovalPolicy.DESTROY, roleTag = CDK$2.ROLE.STORAGE, service, sortKey, vendorTag, ...restProps } = props;
|
|
2976
2974
|
// Convert IndexDefinition[] to CDK GSI props
|
|
2977
2975
|
const globalSecondaryIndexes = indexes ? indexesToGsi(indexes) : undefined;
|
|
2978
2976
|
this._table = new dynamodb.TableV2(this, "Table", {
|
|
@@ -2980,7 +2978,7 @@ class JaypieDynamoDb extends Construct {
|
|
|
2980
2978
|
globalSecondaryIndexes,
|
|
2981
2979
|
partitionKey,
|
|
2982
2980
|
removalPolicy,
|
|
2983
|
-
sortKey,
|
|
2981
|
+
...(sortKey && { sortKey }),
|
|
2984
2982
|
...restProps,
|
|
2985
2983
|
});
|
|
2986
2984
|
// Apply tags
|