@jaypie/constructs 1.2.42 → 1.2.44

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.
@@ -1,10 +1,10 @@
1
1
  import { Construct } from "constructs";
2
2
  import { RemovalPolicy } from "aws-cdk-lib";
3
3
  import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
4
- import { type IndexDefinition } from "@jaypie/fabric";
4
+ import type { IndexDefinition } from "./types/IndexDefinition";
5
5
  export interface JaypieDynamoDbProps extends Omit<dynamodb.TablePropsV2, "globalSecondaryIndexes" | "partitionKey" | "sortKey"> {
6
6
  /**
7
- * Configure GSIs for the table using @jaypie/fabric IndexDefinition format.
7
+ * Configure GSIs for the table using the IndexDefinition format.
8
8
  * - `undefined`: No GSIs (default)
9
9
  * - Array of IndexDefinition: Use the specified indexes
10
10
  *
@@ -13,18 +13,18 @@ export interface JaypieDynamoDbProps extends Omit<dynamodb.TablePropsV2, "global
13
13
  * new JaypieDynamoDb(this, "myTable");
14
14
  *
15
15
  * @example
16
- * // With custom indexes
16
+ * // Inline indexes
17
17
  * new JaypieDynamoDb(this, "myTable", {
18
18
  * indexes: [
19
- * { pk: ["scope", "model"], sk: ["sequence"] },
20
- * { pk: ["scope", "model", "type"], sk: ["sequence"], sparse: true },
19
+ * { name: "indexModel", pk: ["model"], sk: ["scope", "updatedAt"] },
20
+ * { name: "indexModelAlias", pk: ["model", "alias"], sk: ["scope", "updatedAt"], sparse: true },
21
21
  * ],
22
22
  * });
23
23
  */
24
24
  indexes?: IndexDefinition[];
25
25
  /**
26
26
  * Partition key attribute definition.
27
- * @default { name: "model", type: AttributeType.STRING }
27
+ * @default { name: "id", type: AttributeType.STRING }
28
28
  */
29
29
  partitionKey?: dynamodb.Attribute;
30
30
  /**
@@ -40,8 +40,8 @@ export interface JaypieDynamoDbProps extends Omit<dynamodb.TablePropsV2, "global
40
40
  */
41
41
  service?: string;
42
42
  /**
43
- * Sort key attribute definition.
44
- * @default { name: "id", type: AttributeType.STRING }
43
+ * Sort key attribute definition. Defaults to `undefined` (no sort key) —
44
+ * the Jaypie single-table pattern uses `id` as a unique partition key.
45
45
  */
46
46
  sortKey?: dynamodb.Attribute;
47
47
  /**
@@ -53,8 +53,7 @@ export interface JaypieDynamoDbProps extends Omit<dynamodb.TablePropsV2, "global
53
53
  * DynamoDB table with Jaypie single-table design patterns.
54
54
  *
55
55
  * Creates a table with:
56
- * - Partition key: `model` (String)
57
- * - Sort key: `id` (String)
56
+ * - Partition key: `id` (String), no sort key
58
57
  * - Billing: PAY_PER_REQUEST (on-demand)
59
58
  * - Removal policy: RETAIN in production, DESTROY otherwise
60
59
  * - No GSIs by default (use `indexes` prop to add them)
@@ -65,12 +64,12 @@ export interface JaypieDynamoDbProps extends Omit<dynamodb.TablePropsV2, "global
65
64
  * const table = new JaypieDynamoDb(this, "myApp");
66
65
  *
67
66
  * @example
68
- * // With explicit table name (overrides CDK-generated name)
67
+ * // With inline IndexDefinition for GSIs
69
68
  * const table = new JaypieDynamoDb(this, "MyTable", {
70
69
  * tableName: "custom-table-name",
71
70
  * indexes: [
72
- * { pk: ["scope", "model"] },
73
- * { pk: ["scope", "model", "type"], sparse: true },
71
+ * { name: "indexModel", pk: ["model"], sk: ["scope", "updatedAt"] },
72
+ * { name: "indexModelAlias", pk: ["model", "alias"], sk: ["scope", "updatedAt"], sparse: true },
74
73
  * ],
75
74
  * });
76
75
  */
@@ -23,7 +23,6 @@ var cloudfront = require('aws-cdk-lib/aws-cloudfront');
23
23
  var origins = require('aws-cdk-lib/aws-cloudfront-origins');
24
24
  var wafv2 = require('aws-cdk-lib/aws-wafv2');
25
25
  var dynamodb = require('aws-cdk-lib/aws-dynamodb');
26
- var fabric = require('@jaypie/fabric');
27
26
  var cr = require('aws-cdk-lib/custom-resources');
28
27
  var cdkNextjsStandalone = require('cdk-nextjs-standalone');
29
28
  var path = require('path');
@@ -2931,41 +2930,65 @@ class JaypieDnsRecord extends constructs.Construct {
2931
2930
  }
2932
2931
  }
2933
2932
 
2934
- //
2935
- //
2936
- // Constants
2937
- //
2938
- /** Composite key separator used in GSI partition keys */
2939
- const SEPARATOR = "#";
2940
2933
  //
2941
2934
  //
2942
2935
  // Helper Functions
2943
2936
  //
2944
2937
  /**
2945
- * Convert IndexDefinition[] from @jaypie/fabric to CDK GlobalSecondaryIndexPropsV2[]
2938
+ * Derive GSI attribute names for an index definition.
2939
+ *
2940
+ * Mirrors `@jaypie/fabric`'s `getGsiAttributeNames` so CDK provisioning and
2941
+ * any runtime write path agree on the attribute names. Kept local to avoid
2942
+ * a runtime dependency on the pre-1.0 `@jaypie/fabric` package.
2946
2943
  *
2947
- * @param indexes - Array of IndexDefinition from @jaypie/fabric
2948
- * @returns Array of CDK GlobalSecondaryIndexPropsV2
2944
+ * - `pk` is always the index name (`index.name` or generated from `index.pk`)
2945
+ * - `sk` is the single sk field name when `sk.length === 1`, or
2946
+ * `{indexName}Sk` when `sk.length > 1` (composite sk attribute)
2947
+ */
2948
+ function getGsiAttributeNames(index) {
2949
+ const name = index.name ?? generateIndexName(index.pk);
2950
+ let sk;
2951
+ if (index.sk && index.sk.length > 1) {
2952
+ sk = `${name}Sk`;
2953
+ }
2954
+ else if (index.sk && index.sk.length === 1) {
2955
+ sk = index.sk[0];
2956
+ }
2957
+ return { pk: name, sk };
2958
+ }
2959
+ function generateIndexName(pk) {
2960
+ const suffix = pk
2961
+ .map((field) => field.charAt(0).toUpperCase() + field.slice(1))
2962
+ .join("");
2963
+ return `index${suffix}`;
2964
+ }
2965
+ /**
2966
+ * Convert IndexDefinition[] to CDK GlobalSecondaryIndexPropsV2[].
2967
+ *
2968
+ * Composite sk indexes (sk.length > 1) get a dedicated STRING `{indexName}Sk`
2969
+ * attribute; single-field sk indexes reference the field directly (STRING in
2970
+ * the general case, NUMBER for the legacy `sequence` name).
2949
2971
  */
2950
2972
  function indexesToGsi(indexes) {
2951
2973
  return indexes.map((index) => {
2952
- // Generate index name from pk fields if not provided
2953
- const indexName = index.name ?? fabric.generateIndexName(index.pk);
2954
- // Sort key defaults to ["sequence"] if not provided
2955
- const skFields = index.sk ?? fabric.DEFAULT_SORT_KEY;
2974
+ const { pk, sk } = getGsiAttributeNames(index);
2975
+ let sortKey;
2976
+ if (sk) {
2977
+ if (sk === "sequence") {
2978
+ sortKey = { name: "sequence", type: dynamodb__namespace.AttributeType.NUMBER };
2979
+ }
2980
+ else {
2981
+ sortKey = { name: sk, type: dynamodb__namespace.AttributeType.STRING };
2982
+ }
2983
+ }
2956
2984
  return {
2957
- indexName,
2985
+ indexName: pk,
2958
2986
  partitionKey: {
2959
- name: indexName,
2987
+ name: pk,
2960
2988
  type: dynamodb__namespace.AttributeType.STRING,
2961
2989
  },
2962
2990
  projectionType: dynamodb__namespace.ProjectionType.ALL,
2963
- sortKey: skFields.length === 1 && skFields[0] === "sequence"
2964
- ? { name: "sequence", type: dynamodb__namespace.AttributeType.NUMBER }
2965
- : {
2966
- name: skFields.join(SEPARATOR),
2967
- type: dynamodb__namespace.AttributeType.STRING,
2968
- },
2991
+ ...(sortKey && { sortKey }),
2969
2992
  };
2970
2993
  });
2971
2994
  }
@@ -2977,8 +3000,7 @@ function indexesToGsi(indexes) {
2977
3000
  * DynamoDB table with Jaypie single-table design patterns.
2978
3001
  *
2979
3002
  * Creates a table with:
2980
- * - Partition key: `model` (String)
2981
- * - Sort key: `id` (String)
3003
+ * - Partition key: `id` (String), no sort key
2982
3004
  * - Billing: PAY_PER_REQUEST (on-demand)
2983
3005
  * - Removal policy: RETAIN in production, DESTROY otherwise
2984
3006
  * - No GSIs by default (use `indexes` prop to add them)
@@ -2989,12 +3011,12 @@ function indexesToGsi(indexes) {
2989
3011
  * const table = new JaypieDynamoDb(this, "myApp");
2990
3012
  *
2991
3013
  * @example
2992
- * // With explicit table name (overrides CDK-generated name)
3014
+ * // With inline IndexDefinition for GSIs
2993
3015
  * const table = new JaypieDynamoDb(this, "MyTable", {
2994
3016
  * tableName: "custom-table-name",
2995
3017
  * indexes: [
2996
- * { pk: ["scope", "model"] },
2997
- * { pk: ["scope", "model", "type"], sparse: true },
3018
+ * { name: "indexModel", pk: ["model"], sk: ["scope", "updatedAt"] },
3019
+ * { name: "indexModelAlias", pk: ["model", "alias"], sk: ["scope", "updatedAt"], sparse: true },
2998
3020
  * ],
2999
3021
  * });
3000
3022
  */
@@ -3007,11 +3029,11 @@ class JaypieDynamoDb extends constructs.Construct {
3007
3029
  const constructId = isShorthand ? `JaypieDynamoDb-${id}` : id;
3008
3030
  super(scope, constructId);
3009
3031
  const { billing = dynamodb__namespace.Billing.onDemand(), indexes, partitionKey = {
3010
- name: "model",
3032
+ name: "id",
3011
3033
  type: dynamodb__namespace.AttributeType.STRING,
3012
3034
  }, project, removalPolicy = isProductionEnv()
3013
3035
  ? cdk.RemovalPolicy.RETAIN
3014
- : cdk.RemovalPolicy.DESTROY, roleTag = CDK$2.ROLE.STORAGE, service, sortKey = { name: "id", type: dynamodb__namespace.AttributeType.STRING }, vendorTag, ...restProps } = props;
3036
+ : cdk.RemovalPolicy.DESTROY, roleTag = CDK$2.ROLE.STORAGE, service, sortKey, vendorTag, ...restProps } = props;
3015
3037
  // Convert IndexDefinition[] to CDK GSI props
3016
3038
  const globalSecondaryIndexes = indexes ? indexesToGsi(indexes) : undefined;
3017
3039
  this._table = new dynamodb__namespace.TableV2(this, "Table", {
@@ -3019,7 +3041,7 @@ class JaypieDynamoDb extends constructs.Construct {
3019
3041
  globalSecondaryIndexes,
3020
3042
  partitionKey,
3021
3043
  removalPolicy,
3022
- sortKey,
3044
+ ...(sortKey && { sortKey }),
3023
3045
  ...restProps,
3024
3046
  });
3025
3047
  // Apply tags