@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/cjs/index.cjs
CHANGED
|
@@ -1170,7 +1170,7 @@ function clearAllSecretsCaches() {
|
|
|
1170
1170
|
class JaypieApiGateway extends constructs.Construct {
|
|
1171
1171
|
constructor(scope, id, props) {
|
|
1172
1172
|
super(scope, id);
|
|
1173
|
-
const { certificate = true, handler, host: propsHost, name, roleTag = CDK$2.ROLE.API, zone: propsZone, } = props;
|
|
1173
|
+
const { certificate = true, deleteExistingRecord = false, handler, host: propsHost, name, roleTag = CDK$2.ROLE.API, zone: propsZone, } = props;
|
|
1174
1174
|
// Determine zone from props or environment
|
|
1175
1175
|
let zone = propsZone;
|
|
1176
1176
|
if (!zone && process.env.CDK_ENV_API_HOSTED_ZONE) {
|
|
@@ -1216,7 +1216,7 @@ class JaypieApiGateway extends constructs.Construct {
|
|
|
1216
1216
|
// * `...lambdaRestApiProps` cannot be moved to the first const destructuring because it needs to exclude the custom properties first.
|
|
1217
1217
|
// Ignore the variables we already assigned to other properties
|
|
1218
1218
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
1219
|
-
certificate: _certificate, host: _host, name: _name, roleTag: _roleTag, zone: _zone, handler: _handler,
|
|
1219
|
+
certificate: _certificate, deleteExistingRecord: _deleteExistingRecord, host: _host, name: _name, roleTag: _roleTag, zone: _zone, handler: _handler,
|
|
1220
1220
|
/* eslint-enable @typescript-eslint/no-unused-vars */
|
|
1221
1221
|
...lambdaRestApiProps } = props;
|
|
1222
1222
|
this._api = new apiGateway__namespace.LambdaRestApi(this, apiGatewayName, {
|
|
@@ -1231,6 +1231,7 @@ class JaypieApiGateway extends constructs.Construct {
|
|
|
1231
1231
|
});
|
|
1232
1232
|
cdk.Tags.of(this._domainName).add(CDK$2.TAG.ROLE, roleTag);
|
|
1233
1233
|
const record = new route53__namespace.ARecord(this, "AliasRecord", {
|
|
1234
|
+
deleteExisting: deleteExistingRecord,
|
|
1234
1235
|
recordName: host,
|
|
1235
1236
|
target: route53__namespace.RecordTarget.fromAlias(new route53Targets__namespace.ApiGatewayDomain(this._domainName)),
|
|
1236
1237
|
zone: hostedZone,
|
|
@@ -2394,7 +2395,7 @@ const DEFAULT_MANAGED_RULES = [
|
|
|
2394
2395
|
class JaypieDistribution extends constructs.Construct {
|
|
2395
2396
|
constructor(scope, id, props) {
|
|
2396
2397
|
super(scope, id);
|
|
2397
|
-
const { certificate: certificateProp = true, defaultBehavior: propsDefaultBehavior, destination: destinationProp = true, handler, host: propsHost, logBucket: logBucketProp, originReadTimeout = cdk.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;
|
|
2398
|
+
const { certificate: certificateProp = true, defaultBehavior: propsDefaultBehavior, deleteExistingRecord = false, destination: destinationProp = true, handler, host: propsHost, logBucket: logBucketProp, originReadTimeout = cdk.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;
|
|
2398
2399
|
// Validate environment variables
|
|
2399
2400
|
if (process.env.CDK_ENV_API_SUBDOMAIN &&
|
|
2400
2401
|
!isValidSubdomain(process.env.CDK_ENV_API_SUBDOMAIN)) {
|
|
@@ -2754,12 +2755,14 @@ class JaypieDistribution extends constructs.Construct {
|
|
|
2754
2755
|
// Create DNS records if we have host and zone
|
|
2755
2756
|
if (host && hostedZone) {
|
|
2756
2757
|
const aRecord = new route53__namespace.ARecord(this, "AliasRecord", {
|
|
2758
|
+
deleteExisting: deleteExistingRecord,
|
|
2757
2759
|
recordName: host,
|
|
2758
2760
|
target: route53__namespace.RecordTarget.fromAlias(new route53Targets__namespace.CloudFrontTarget(this.distribution)),
|
|
2759
2761
|
zone: hostedZone,
|
|
2760
2762
|
});
|
|
2761
2763
|
cdk.Tags.of(aRecord).add(CDK$2.TAG.ROLE, CDK$2.ROLE.NETWORKING);
|
|
2762
2764
|
const aaaaRecord = new route53__namespace.AaaaRecord(this, "AaaaAliasRecord", {
|
|
2765
|
+
deleteExisting: deleteExistingRecord,
|
|
2763
2766
|
recordName: host,
|
|
2764
2767
|
target: route53__namespace.RecordTarget.fromAlias(new route53Targets__namespace.CloudFrontTarget(this.distribution)),
|
|
2765
2768
|
zone: hostedZone,
|
|
@@ -2928,41 +2931,39 @@ class JaypieDnsRecord extends constructs.Construct {
|
|
|
2928
2931
|
}
|
|
2929
2932
|
}
|
|
2930
2933
|
|
|
2931
|
-
//
|
|
2932
|
-
//
|
|
2933
|
-
// Constants
|
|
2934
|
-
//
|
|
2935
|
-
/** Composite key separator used in GSI partition keys */
|
|
2936
|
-
const SEPARATOR = "#";
|
|
2937
2934
|
//
|
|
2938
2935
|
//
|
|
2939
2936
|
// Helper Functions
|
|
2940
2937
|
//
|
|
2941
2938
|
/**
|
|
2942
|
-
* Convert IndexDefinition[] from @jaypie/fabric to CDK GlobalSecondaryIndexPropsV2[]
|
|
2939
|
+
* Convert IndexDefinition[] from @jaypie/fabric to CDK GlobalSecondaryIndexPropsV2[].
|
|
2943
2940
|
*
|
|
2944
|
-
*
|
|
2945
|
-
*
|
|
2941
|
+
* Uses `getGsiAttributeNames` as the single source of truth so runtime writes
|
|
2942
|
+
* and CDK provisioning agree on attribute names. Composite sk indexes
|
|
2943
|
+
* (sk.length > 1) get a dedicated STRING `{indexName}Sk` attribute; single-field
|
|
2944
|
+
* sk indexes reference the field directly (STRING in the general case, NUMBER
|
|
2945
|
+
* for the legacy `sequence` name).
|
|
2946
2946
|
*/
|
|
2947
2947
|
function indexesToGsi(indexes) {
|
|
2948
2948
|
return indexes.map((index) => {
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2949
|
+
const { pk, sk } = fabric.getGsiAttributeNames(index);
|
|
2950
|
+
let sortKey;
|
|
2951
|
+
if (sk) {
|
|
2952
|
+
if (sk === "sequence") {
|
|
2953
|
+
sortKey = { name: "sequence", type: dynamodb__namespace.AttributeType.NUMBER };
|
|
2954
|
+
}
|
|
2955
|
+
else {
|
|
2956
|
+
sortKey = { name: sk, type: dynamodb__namespace.AttributeType.STRING };
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2953
2959
|
return {
|
|
2954
|
-
indexName,
|
|
2960
|
+
indexName: pk,
|
|
2955
2961
|
partitionKey: {
|
|
2956
|
-
name:
|
|
2962
|
+
name: pk,
|
|
2957
2963
|
type: dynamodb__namespace.AttributeType.STRING,
|
|
2958
2964
|
},
|
|
2959
2965
|
projectionType: dynamodb__namespace.ProjectionType.ALL,
|
|
2960
|
-
sortKey
|
|
2961
|
-
? { name: "sequence", type: dynamodb__namespace.AttributeType.NUMBER }
|
|
2962
|
-
: {
|
|
2963
|
-
name: skFields.join(SEPARATOR),
|
|
2964
|
-
type: dynamodb__namespace.AttributeType.STRING,
|
|
2965
|
-
},
|
|
2966
|
+
...(sortKey && { sortKey }),
|
|
2966
2967
|
};
|
|
2967
2968
|
});
|
|
2968
2969
|
}
|
|
@@ -2974,8 +2975,7 @@ function indexesToGsi(indexes) {
|
|
|
2974
2975
|
* DynamoDB table with Jaypie single-table design patterns.
|
|
2975
2976
|
*
|
|
2976
2977
|
* Creates a table with:
|
|
2977
|
-
* - Partition key: `
|
|
2978
|
-
* - Sort key: `id` (String)
|
|
2978
|
+
* - Partition key: `id` (String), no sort key
|
|
2979
2979
|
* - Billing: PAY_PER_REQUEST (on-demand)
|
|
2980
2980
|
* - Removal policy: RETAIN in production, DESTROY otherwise
|
|
2981
2981
|
* - No GSIs by default (use `indexes` prop to add them)
|
|
@@ -2986,13 +2986,11 @@ function indexesToGsi(indexes) {
|
|
|
2986
2986
|
* const table = new JaypieDynamoDb(this, "myApp");
|
|
2987
2987
|
*
|
|
2988
2988
|
* @example
|
|
2989
|
-
* // With
|
|
2989
|
+
* // With fabricIndex() for GSIs
|
|
2990
|
+
* import { fabricIndex } from "@jaypie/fabric";
|
|
2990
2991
|
* const table = new JaypieDynamoDb(this, "MyTable", {
|
|
2991
2992
|
* tableName: "custom-table-name",
|
|
2992
|
-
* indexes: [
|
|
2993
|
-
* { pk: ["scope", "model"] },
|
|
2994
|
-
* { pk: ["scope", "model", "type"], sparse: true },
|
|
2995
|
-
* ],
|
|
2993
|
+
* indexes: [fabricIndex(), fabricIndex("alias"), fabricIndex("xid")],
|
|
2996
2994
|
* });
|
|
2997
2995
|
*/
|
|
2998
2996
|
class JaypieDynamoDb extends constructs.Construct {
|
|
@@ -3004,11 +3002,11 @@ class JaypieDynamoDb extends constructs.Construct {
|
|
|
3004
3002
|
const constructId = isShorthand ? `JaypieDynamoDb-${id}` : id;
|
|
3005
3003
|
super(scope, constructId);
|
|
3006
3004
|
const { billing = dynamodb__namespace.Billing.onDemand(), indexes, partitionKey = {
|
|
3007
|
-
name: "
|
|
3005
|
+
name: "id",
|
|
3008
3006
|
type: dynamodb__namespace.AttributeType.STRING,
|
|
3009
3007
|
}, project, removalPolicy = isProductionEnv()
|
|
3010
3008
|
? cdk.RemovalPolicy.RETAIN
|
|
3011
|
-
: cdk.RemovalPolicy.DESTROY, roleTag = CDK$2.ROLE.STORAGE, service, sortKey
|
|
3009
|
+
: cdk.RemovalPolicy.DESTROY, roleTag = CDK$2.ROLE.STORAGE, service, sortKey, vendorTag, ...restProps } = props;
|
|
3012
3010
|
// Convert IndexDefinition[] to CDK GSI props
|
|
3013
3011
|
const globalSecondaryIndexes = indexes ? indexesToGsi(indexes) : undefined;
|
|
3014
3012
|
this._table = new dynamodb__namespace.TableV2(this, "Table", {
|
|
@@ -3016,7 +3014,7 @@ class JaypieDynamoDb extends constructs.Construct {
|
|
|
3016
3014
|
globalSecondaryIndexes,
|
|
3017
3015
|
partitionKey,
|
|
3018
3016
|
removalPolicy,
|
|
3019
|
-
sortKey,
|
|
3017
|
+
...(sortKey && { sortKey }),
|
|
3020
3018
|
...restProps,
|
|
3021
3019
|
});
|
|
3022
3020
|
// Apply tags
|