@fjall/components-infrastructure 0.86.0 → 0.87.3

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 (112) hide show
  1. package/README.md +3 -3
  2. package/dist/lib/app.d.ts +166 -6
  3. package/dist/lib/app.js +212 -20
  4. package/dist/lib/aspects/resourceInventory.d.ts +4 -4
  5. package/dist/lib/aspects/resourceInventory.js +3 -3
  6. package/dist/lib/config/aws/backupGlobalSettings.js +1 -2
  7. package/dist/lib/config/aws/identityCenter.js +1 -5
  8. package/dist/lib/config/aws/organisation.js +1 -4
  9. package/dist/lib/index.d.ts +1 -0
  10. package/dist/lib/index.js +7 -1
  11. package/dist/lib/patterns/aws/buildkite.js +3 -2
  12. package/dist/lib/patterns/aws/cdn.d.ts +164 -0
  13. package/dist/lib/patterns/aws/cdn.js +264 -0
  14. package/dist/lib/patterns/aws/compute.d.ts +278 -59
  15. package/dist/lib/patterns/aws/compute.js +384 -188
  16. package/dist/lib/patterns/aws/connections.d.ts +46 -0
  17. package/dist/lib/patterns/aws/connections.js +159 -0
  18. package/dist/lib/patterns/aws/database.d.ts +124 -11
  19. package/dist/lib/patterns/aws/database.js +188 -66
  20. package/dist/lib/patterns/aws/hostedZone.js +1 -1
  21. package/dist/lib/patterns/aws/index.d.ts +3 -0
  22. package/dist/lib/patterns/aws/index.js +4 -1
  23. package/dist/lib/patterns/aws/interfaces/compute.d.ts +121 -0
  24. package/dist/lib/patterns/aws/interfaces/compute.js +48 -0
  25. package/dist/lib/patterns/aws/interfaces/connector.d.ts +183 -0
  26. package/dist/lib/patterns/aws/interfaces/connector.js +117 -0
  27. package/dist/lib/patterns/aws/interfaces/database.d.ts +136 -0
  28. package/dist/lib/patterns/aws/interfaces/database.js +65 -0
  29. package/dist/lib/patterns/aws/interfaces/index.d.ts +12 -0
  30. package/dist/lib/patterns/aws/interfaces/index.js +49 -0
  31. package/dist/lib/patterns/aws/interfaces/messaging.d.ts +146 -0
  32. package/dist/lib/patterns/aws/interfaces/messaging.js +56 -0
  33. package/dist/lib/patterns/aws/interfaces/pattern.d.ts +403 -0
  34. package/dist/lib/patterns/aws/interfaces/pattern.js +36 -0
  35. package/dist/lib/patterns/aws/interfaces/storage.d.ts +136 -0
  36. package/dist/lib/patterns/aws/interfaces/storage.js +48 -0
  37. package/dist/lib/patterns/aws/messaging.d.ts +183 -0
  38. package/dist/lib/patterns/aws/messaging.js +239 -0
  39. package/dist/lib/patterns/aws/network.js +4 -4
  40. package/dist/lib/patterns/aws/pattern.d.ts +67 -0
  41. package/dist/lib/patterns/aws/pattern.js +69 -0
  42. package/dist/lib/patterns/aws/payload.d.ts +87 -0
  43. package/dist/lib/patterns/aws/payload.js +526 -0
  44. package/dist/lib/patterns/aws/storage.d.ts +127 -15
  45. package/dist/lib/patterns/aws/storage.js +234 -38
  46. package/dist/lib/resources/aws/backup/backupPlan.js +1 -6
  47. package/dist/lib/resources/aws/backup/backupVault.js +1 -2
  48. package/dist/lib/resources/aws/base/awsStack.d.ts +0 -2
  49. package/dist/lib/resources/aws/base/awsStack.js +1 -7
  50. package/dist/lib/resources/aws/cdn/cloudFront.d.ts +71 -0
  51. package/dist/lib/resources/aws/cdn/cloudFront.js +176 -0
  52. package/dist/lib/resources/aws/cdn/index.d.ts +1 -0
  53. package/dist/lib/resources/aws/cdn/index.js +18 -0
  54. package/dist/lib/resources/aws/compute/ec2.d.ts +5 -0
  55. package/dist/lib/resources/aws/compute/ec2.js +33 -6
  56. package/dist/lib/resources/aws/compute/ecs.d.ts +32 -25
  57. package/dist/lib/resources/aws/compute/ecs.js +31 -115
  58. package/dist/lib/resources/aws/compute/lambda.d.ts +94 -5
  59. package/dist/lib/resources/aws/compute/lambda.js +209 -32
  60. package/dist/lib/resources/aws/database/database.js +1 -1
  61. package/dist/lib/resources/aws/database/dynamodb.d.ts +70 -0
  62. package/dist/lib/resources/aws/database/dynamodb.js +181 -0
  63. package/dist/lib/resources/aws/database/index.d.ts +1 -0
  64. package/dist/lib/resources/aws/database/index.js +2 -1
  65. package/dist/lib/resources/aws/database/migrationLambda.d.ts +80 -0
  66. package/dist/lib/resources/aws/database/migrationLambda.js +119 -0
  67. package/dist/lib/resources/aws/database/rdsAurora.d.ts +15 -0
  68. package/dist/lib/resources/aws/database/rdsAurora.js +41 -18
  69. package/dist/lib/resources/aws/database/rdsAuroraGlobal.js +12 -8
  70. package/dist/lib/resources/aws/database/rdsInstance.js +2 -2
  71. package/dist/lib/resources/aws/index.d.ts +2 -0
  72. package/dist/lib/resources/aws/index.js +3 -1
  73. package/dist/lib/resources/aws/messaging/eventbridge.d.ts +28 -0
  74. package/dist/lib/resources/aws/messaging/eventbridge.js +53 -0
  75. package/dist/lib/resources/aws/messaging/index.d.ts +3 -0
  76. package/dist/lib/resources/aws/messaging/index.js +20 -0
  77. package/dist/lib/resources/aws/messaging/sns.d.ts +35 -0
  78. package/dist/lib/resources/aws/messaging/sns.js +70 -0
  79. package/dist/lib/resources/aws/messaging/sqs.d.ts +105 -0
  80. package/dist/lib/resources/aws/messaging/sqs.js +231 -0
  81. package/dist/lib/resources/aws/messaging/utils.d.ts +3 -0
  82. package/dist/lib/resources/aws/messaging/utils.js +7 -0
  83. package/dist/lib/resources/aws/networking/ipam.js +1 -2
  84. package/dist/lib/resources/aws/networking/ipamPool.js +3 -2
  85. package/dist/lib/resources/aws/networking/vpc.js +1 -2
  86. package/dist/lib/resources/aws/storage/ecr.js +8 -5
  87. package/dist/lib/resources/aws/storage/s3.js +1 -2
  88. package/dist/lib/resources/aws/utilities/awsCustomResource.js +1 -1
  89. package/dist/lib/resources/aws/utilities/customResource.js +1 -1
  90. package/dist/lib/utils/getConfig.js +3 -2
  91. package/dist/lib/utils/index.d.ts +1 -0
  92. package/dist/lib/utils/index.js +2 -1
  93. package/dist/lib/utils/manifestWriter.d.ts +174 -0
  94. package/dist/lib/utils/manifestWriter.js +233 -0
  95. package/dist/lib/utils/standardTagsAspect.js +1 -8
  96. package/dist/lib/utils/validationLogger.d.ts +34 -0
  97. package/dist/lib/utils/validationLogger.js +83 -0
  98. package/package.json +3 -3
  99. package/dist/lib/__tests__/setup.d.ts +0 -48
  100. package/dist/lib/__tests__/setup.js +0 -1
  101. package/dist/lib/patterns/aws/cicdRole.d.ts +0 -67
  102. package/dist/lib/patterns/aws/cicdRole.js +0 -68
  103. package/dist/lib/resources/aws/cicd/cicdRole.d.ts +0 -65
  104. package/dist/lib/resources/aws/cicd/cicdRole.js +0 -191
  105. package/dist/lib/resources/aws/compute/ecsFreeTier.d.ts +0 -75
  106. package/dist/lib/resources/aws/compute/ecsFreeTier.js +0 -1
  107. package/dist/lib/resources/aws/compute/ecsSpot.d.ts +0 -75
  108. package/dist/lib/resources/aws/compute/ecsSpot.js +0 -1
  109. package/dist/lib/resources/aws/compute/utilities/capacityProviderDrainWaiter.d.ts +0 -20
  110. package/dist/lib/resources/aws/compute/utilities/capacityProviderDrainWaiter.js +0 -1
  111. package/dist/lib/resources/aws/utilities/cfnOutput.d.ts +0 -5
  112. package/dist/lib/resources/aws/utilities/cfnOutput.js +0 -1
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Shared connection processor for unified connector interface.
3
+ *
4
+ * This module provides the `processConnections` function that handles
5
+ * both security group rules (IConnectable) and IAM grants (IGrantable)
6
+ * in a unified way.
7
+ *
8
+ * @example
9
+ * // In ECS service setup
10
+ * processConnections(
11
+ * serviceProps.connections,
12
+ * serviceData.taskRole, // IGrantable for IAM
13
+ * service // IConnectable for security groups
14
+ * );
15
+ *
16
+ * @example
17
+ * // In Lambda setup
18
+ * processConnections(
19
+ * props.connections,
20
+ * this.lambdaFunction, // IGrantable (execution role)
21
+ * this.lambdaFunction // IConnectable (security group)
22
+ * );
23
+ */
24
+ import { type IConnectable } from "aws-cdk-lib/aws-ec2";
25
+ import { type IGrantable } from "aws-cdk-lib/aws-iam";
26
+ import { type ConnectionSpec, type ConnectionResult } from "./interfaces/connector.js";
27
+ /**
28
+ * Process connections from compute resources to data resources.
29
+ *
30
+ * Handles the unified connector interface, dispatching to:
31
+ * - Security group rules for IConnectable and ISecurityGroupConnector resources
32
+ * - IAM grants for IStorageConnector, IDynamoDBConnector, and IQueueConnector resources
33
+ *
34
+ * @param connections - Array of connection specifications
35
+ * @param grantee - The IAM grantee (task role, execution role, etc.)
36
+ * @param connectable - Optional IConnectable for security group rules
37
+ * @returns Array of connection results
38
+ *
39
+ * @example
40
+ * processConnections(
41
+ * [database, { resource: bucket, access: "read" }, queue],
42
+ * taskRole,
43
+ * service
44
+ * );
45
+ */
46
+ export declare function processConnections(connections: ConnectionSpec[], grantee: IGrantable, connectable?: IConnectable): ConnectionResult[];
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ /**
3
+ * Shared connection processor for unified connector interface.
4
+ *
5
+ * This module provides the `processConnections` function that handles
6
+ * both security group rules (IConnectable) and IAM grants (IGrantable)
7
+ * in a unified way.
8
+ *
9
+ * @example
10
+ * // In ECS service setup
11
+ * processConnections(
12
+ * serviceProps.connections,
13
+ * serviceData.taskRole, // IGrantable for IAM
14
+ * service // IConnectable for security groups
15
+ * );
16
+ *
17
+ * @example
18
+ * // In Lambda setup
19
+ * processConnections(
20
+ * props.connections,
21
+ * this.lambdaFunction, // IGrantable (execution role)
22
+ * this.lambdaFunction // IConnectable (security group)
23
+ * );
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.processConnections = processConnections;
27
+ const connector_js_1 = require("./interfaces/connector.js");
28
+ /** Default access levels for each connector type. */
29
+ const DEFAULT_ACCESS = {
30
+ storage: "readWrite",
31
+ dynamodb: "readWrite",
32
+ queue: "full"
33
+ };
34
+ /** Grant storage access based on access level. */
35
+ function processStorageConnection(connector, grantee, access) {
36
+ switch (access) {
37
+ case "read":
38
+ return connector.grantRead(grantee);
39
+ case "write":
40
+ return connector.grantWrite(grantee);
41
+ case "readWrite":
42
+ return connector.grantReadWrite(grantee);
43
+ }
44
+ }
45
+ /** Grant DynamoDB access based on access level. */
46
+ function processDynamoDBConnection(connector, grantee, access) {
47
+ switch (access) {
48
+ case "read":
49
+ return connector.grantReadData(grantee);
50
+ case "write":
51
+ return connector.grantWriteData(grantee);
52
+ case "readWrite":
53
+ return connector.grantReadWriteData(grantee);
54
+ }
55
+ }
56
+ /** Grant queue access based on access level. */
57
+ function processQueueConnection(connector, grantee, access) {
58
+ switch (access) {
59
+ case "send":
60
+ return connector.grantSendMessages(grantee);
61
+ case "consume":
62
+ return connector.grantConsumeMessages(grantee);
63
+ case "full":
64
+ return connector.grantFull(grantee);
65
+ }
66
+ }
67
+ /** Build an IAM connection result. */
68
+ function buildIamResult(connector, grant) {
69
+ return { resource: connector, grant, connectionType: connector_js_1.CONNECTION_TYPE.IAM };
70
+ }
71
+ /** Build a security group connection result. */
72
+ function buildSecurityGroupResult(resource) {
73
+ return { resource, connectionType: connector_js_1.CONNECTION_TYPE.SECURITY_GROUP };
74
+ }
75
+ /** Validate and narrow access type for storage/dynamodb connectors. */
76
+ function validateConnectionAccess(access, connectorType, defaultAccess) {
77
+ if (access === undefined)
78
+ return defaultAccess;
79
+ if ((0, connector_js_1.isConnectionAccess)(access))
80
+ return access;
81
+ throw new Error(`Invalid access "${access}" for ${connectorType} connector. ` +
82
+ `Valid values: read, write, readWrite`);
83
+ }
84
+ /** Validate and narrow access type for queue connectors. */
85
+ function validateMessagingAccess(access, defaultAccess) {
86
+ if (access === undefined)
87
+ return defaultAccess;
88
+ if ((0, connector_js_1.isMessagingAccess)(access))
89
+ return access;
90
+ throw new Error(`Invalid access "${access}" for queue connector. ` +
91
+ `Valid values: send, consume, full`);
92
+ }
93
+ /**
94
+ * Require IConnectable for security group operations.
95
+ * Throws a descriptive error if not provided.
96
+ */
97
+ function requireConnectable(connectable, context) {
98
+ if (!connectable) {
99
+ throw new Error(`${context} requires an IConnectable to be provided. ` +
100
+ "Ensure the compute resource (ECS, EC2, Lambda with VPC) implements IConnectable.");
101
+ }
102
+ }
103
+ /**
104
+ * Process connections from compute resources to data resources.
105
+ *
106
+ * Handles the unified connector interface, dispatching to:
107
+ * - Security group rules for IConnectable and ISecurityGroupConnector resources
108
+ * - IAM grants for IStorageConnector, IDynamoDBConnector, and IQueueConnector resources
109
+ *
110
+ * @param connections - Array of connection specifications
111
+ * @param grantee - The IAM grantee (task role, execution role, etc.)
112
+ * @param connectable - Optional IConnectable for security group rules
113
+ * @returns Array of connection results
114
+ *
115
+ * @example
116
+ * processConnections(
117
+ * [database, { resource: bucket, access: "read" }, queue],
118
+ * taskRole,
119
+ * service
120
+ * );
121
+ */
122
+ function processConnections(connections, grantee, connectable) {
123
+ return connections.map((spec) => {
124
+ const { resource, access } = (0, connector_js_1.isConnectionConfig)(spec)
125
+ ? { resource: spec.resource, access: spec.access }
126
+ : { resource: spec, access: undefined };
127
+ // Handle unified connector interface (isConnector now returns AnyConnector)
128
+ if ((0, connector_js_1.isConnector)(resource)) {
129
+ switch (resource.connectorType) {
130
+ case "storage": {
131
+ const validAccess = validateConnectionAccess(access, "storage", DEFAULT_ACCESS.storage);
132
+ return buildIamResult(resource, processStorageConnection(resource, grantee, validAccess));
133
+ }
134
+ case "dynamodb": {
135
+ const validAccess = validateConnectionAccess(access, "dynamodb", DEFAULT_ACCESS.dynamodb);
136
+ return buildIamResult(resource, processDynamoDBConnection(resource, grantee, validAccess));
137
+ }
138
+ case "queue": {
139
+ const validAccess = validateMessagingAccess(access, DEFAULT_ACCESS.queue);
140
+ return buildIamResult(resource, processQueueConnection(resource, grantee, validAccess));
141
+ }
142
+ case "securityGroup":
143
+ case "relational": {
144
+ requireConnectable(connectable, `${resource.connectorType} connector`);
145
+ connectable.connections.allowToDefaultPort(resource);
146
+ return buildSecurityGroupResult(resource);
147
+ }
148
+ }
149
+ }
150
+ // Legacy IConnectable path
151
+ if ((0, connector_js_1.isConnectable)(resource)) {
152
+ requireConnectable(connectable, "IConnectable resource");
153
+ connectable.connections.allowToDefaultPort(resource);
154
+ return buildSecurityGroupResult(resource);
155
+ }
156
+ throw new Error("Connection resource must be either an IConnector or IConnectable");
157
+ });
158
+ }
159
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29ubmVjdGlvbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWIvcGF0dGVybnMvYXdzL2Nvbm5lY3Rpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRzs7QUF5SkgsZ0RBdUVDO0FBNU5ELDREQWVtQztBQUVuQyxxREFBcUQ7QUFDckQsTUFBTSxjQUFjLEdBQUc7SUFDckIsT0FBTyxFQUFFLFdBQVc7SUFDcEIsUUFBUSxFQUFFLFdBQVc7SUFDckIsS0FBSyxFQUFFLE1BQU07Q0FDTCxDQUFDO0FBRVgsa0RBQWtEO0FBQ2xELFNBQVMsd0JBQXdCLENBQy9CLFNBQTRCLEVBQzVCLE9BQW1CLEVBQ25CLE1BQXdCO0lBRXhCLFFBQVEsTUFBTSxFQUFFLENBQUM7UUFDZixLQUFLLE1BQU07WUFDVCxPQUFPLFNBQVMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDdEMsS0FBSyxPQUFPO1lBQ1YsT0FBTyxTQUFTLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZDLEtBQUssV0FBVztZQUNkLE9BQU8sU0FBUyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM3QyxDQUFDO0FBQ0gsQ0FBQztBQUVELG1EQUFtRDtBQUNuRCxTQUFTLHlCQUF5QixDQUNoQyxTQUE2QixFQUM3QixPQUFtQixFQUNuQixNQUF3QjtJQUV4QixRQUFRLE1BQU0sRUFBRSxDQUFDO1FBQ2YsS0FBSyxNQUFNO1lBQ1QsT0FBTyxTQUFTLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzFDLEtBQUssT0FBTztZQUNWLE9BQU8sU0FBUyxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMzQyxLQUFLLFdBQVc7WUFDZCxPQUFPLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNqRCxDQUFDO0FBQ0gsQ0FBQztBQUVELGdE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QUMsQ0FBQztRQUM1QyxDQUFDO1FBRUQsTUFBTSxJQUFJLEtBQUssQ0FDYixrRUFBa0UsQ0FDbkUsQ0FBQztJQUNKLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogU2hhcmVkIGNvbm5lY3Rpb24gcHJvY2Vzc29yIGZvciB1bmlmaWVkIGNvbm5lY3RvciBpbnRlcmZhY2UuXG4gKlxuICogVGhpcyBtb2R1bGUgcHJvdmlkZXMgdGhlIGBwcm9jZXNzQ29ubmVjdGlvbnNgIGZ1bmN0aW9uIHRoYXQgaGFuZGxlc1xuICogYm90aCBzZWN1cml0eSBncm91cCBydWxlcyAoSUNvbm5lY3RhYmxlKSBhbmQgSUFNIGdyYW50cyAoSUdyYW50YWJsZSlcbiAqIGluIGEgdW5pZmllZCB3YXkuXG4gKlxuICogQGV4YW1wbGVcbiAqIC8vIEluIEVDUyBzZXJ2aWNlIHNldHVwXG4gKiBwcm9jZXNzQ29ubmVjdGlvbnMoXG4gKiAgIHNlcnZpY2VQcm9wcy5jb25uZWN0aW9ucyxcbiAqICAgc2VydmljZURhdGEudGFza1JvbGUsICAvLyBJR3JhbnRhYmxlIGZvciBJQU1cbiAqICAgc2VydmljZSAgICAgICAgICAgICAgIC8vIElDb25uZWN0YWJsZSBmb3Igc2VjdXJpdHkgZ3JvdXBzXG4gKiApO1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBJbiBMYW1iZGEgc2V0dXBcbiAqIHByb2Nlc3NDb25uZWN0aW9ucyhcbiAqICAgcHJvcHMuY29ubmVjdGlvbnMsXG4gKiAgIHRoaXMubGFtYmRhRnVuY3Rpb24sICAvLyBJR3JhbnRhYmxlIChleGVjdXRpb24gcm9sZSlcbiAqICAgdGhpcy5sYW1iZGFGdW5jdGlvbiAgIC8vIElDb25uZWN0YWJsZSAoc2VjdXJpdHkgZ3JvdXApXG4gKiApO1xuICovXG5cbmltcG9ydCB7IHR5cGUgSUNvbm5lY3RhYmxlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1lYzJcIjtcbmltcG9ydCB7IHR5cGUgSUdyYW50YWJsZSwgdHlwZSBHcmFudCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCI7XG5pbXBvcnQge1xuICB0eXBlIENvbm5lY3Rpb25TcGVjLFxuICB0eXBlIENvbm5lY3Rpb25SZXN1bHQsXG4gIHR5cGUgQ29ubmVjdGlvbkFjY2VzcyxcbiAgdHlwZSBNZXNzYWdpbmdBY2Nlc3MsXG4gIHR5cGUgQW55Q29ubmVjdG9yLFxuICB0eXBlIElTdG9yYWdlQ29ubmVjdG9yLFxuICB0eXBlIElEeW5hbW9EQkNvbm5lY3RvcixcbiAgdHlwZSBJUXVldWVDb25uZWN0b3IsXG4gIENPTk5FQ1RJT05fVFlQRSxcbiAgaXNDb25uZWN0aW9uQ29uZmlnLFxuICBpc0Nvbm5lY3RvcixcbiAgaXNDb25uZWN0YWJsZSxcbiAgaXNDb25uZWN0aW9uQWNjZXNzLFxuICBpc01lc3NhZ2luZ0FjY2Vzc1xufSBmcm9tIFwiLi9pbnRlcmZhY2VzL2Nvbm5lY3Rvci5qc1wiO1xuXG4vKiogRGVmYXVsdCBhY2Nlc3MgbGV2ZWxzIGZvciBlYWNoIGNvbm5lY3RvciB0eXBlLiAqL1xuY29uc3QgREVGQVVMVF9BQ0NFU1MgPSB7XG4gIHN0b3JhZ2U6IFwicmVhZFdyaXRlXCIsXG4gIGR5bmFtb2RiOiBcInJlYWRXcml0ZVwiLFxuICBxdWV1ZTogXCJmdWxsXCJcbn0gYXMgY29uc3Q7XG5cbi8qKiBHcmFudCBzdG9yYWdlIGFjY2VzcyBiYXNlZCBvbiBhY2Nlc3MgbGV2ZWwuICovXG5mdW5jdGlvbiBwcm9jZXNzU3RvcmFnZUNvbm5lY3Rpb24oXG4gIGNvbm5lY3RvcjogSVN0b3JhZ2VDb25uZWN0b3IsXG4gIGdyYW50ZWU6IElHcmFudGFibGUsXG4gIGFjY2VzczogQ29ubmVjdGlvbkFjY2Vzc1xuKTogR3JhbnQge1xuICBzd2l0Y2ggKGFjY2Vzcykge1xuICAgIGNhc2UgXCJyZWFkXCI6XG4gICAgICByZXR1cm4gY29ubmVjdG9yLmdyYW50UmVhZChncmFudGVlKTtcbiAgICBjYXNlIFwid3JpdGVcIjpcbiAgICAgIHJldHVybiBjb25uZWN0b3IuZ3JhbnRXcml0ZShncmFudGVlKTtcbiAgICBjYXNlIFwicmVhZFdyaXRlXCI6XG4gICAgICByZXR1cm4gY29ubmVjdG9yLmdyYW50UmVhZFdyaXRlKGdyYW50ZWUpO1xuICB9XG59XG5cbi8qKiBHcmFudCBEeW5hbW9EQiBhY2Nlc3MgYmFzZWQgb24gYWNjZXNzIGxldmVsLiAqL1xuZnVuY3Rpb24gcHJvY2Vzc0R5bmFtb0RCQ29ubmVjdGlvbihcbiAgY29ubmVjdG9yOiBJRHluYW1vREJDb25uZWN0b3IsXG4gIGdyYW50ZWU6IElHcmFudGFibGUsXG4gIGFjY2VzczogQ29ubmVjdGlvbkFjY2Vzc1xuKTogR3JhbnQge1xuICBzd2l0Y2ggKGFjY2Vzcykge1xuICAgIGNhc2UgXCJyZWFkXCI6XG4gICAgICByZXR1cm4gY29ubmVjdG9yLmdyYW50UmVhZERhdGEoZ3JhbnRlZSk7XG4gICAgY2FzZSBcIndyaXRlXCI6XG4gICAgICByZXR1cm4gY29ubmVjdG9yLmdyYW50V3JpdGVEYXRhKGdyYW50ZWUpO1xuICAgIGNhc2UgXCJyZWFkV3JpdGVcIjpcbiAgICAgIHJldHVybiBjb25uZWN0b3IuZ3JhbnRSZWFkV3JpdGVEYXRhKGdyYW50ZWUpO1xuICB9XG59XG5cbi8qKiBHcmFudCBxdWV1ZSBhY2Nlc3MgYmFzZWQgb24gYWNjZXNzIGxldmVsLiAqL1xuZnVuY3Rpb24gcHJvY2Vzc1F1ZXVlQ29ubmVjdGlvbihcbiAgY29ubmVjdG9yOiBJUXVldWVDb25uZWN0b3IsXG4gIGdyYW50ZWU6IElHcmFudGFibGUsXG4gIGFjY2VzczogTWVzc2FnaW5nQWNjZXNzXG4pOiBHcmFudCB7XG4gIHN3aXRjaCAoYWNjZXNzKSB7XG4gICAgY2FzZSBcInNlbmRcIjpcbiAgICAgIHJldHVybiBjb25uZWN0b3IuZ3JhbnRTZW5kTWVzc2FnZXMoZ3JhbnRlZSk7XG4gICAgY2FzZSBcImNvbnN1bWVcIjpcbiAgICAgIHJldHVybiBjb25uZWN0b3IuZ3JhbnRDb25zdW1lTWVzc2FnZXMoZ3JhbnRlZSk7XG4gICAgY2FzZSBcImZ1bGxcIjpcbiAgICAgIHJldHVybiBjb25uZWN0b3IuZ3JhbnRGdWxsKGdyYW50ZWUpO1xuICB9XG59XG5cbi8qKiBCdWlsZCBhbiBJQU0gY29ubmVjdGlvbiByZXN1bHQuICovXG5mdW5jdGlvbiBidWlsZElhbVJlc3VsdChcbiAgY29ubmVjdG9yOiBBbnlDb25uZWN0b3IsXG4gIGdyYW50OiBHcmFudFxuKTogQ29ubmVjdGlvblJlc3VsdCB7XG4gIHJldHVybiB7IHJlc291cmNlOiBjb25uZWN0b3IsIGdyYW50LCBjb25uZWN0aW9uVHlwZTogQ09OTkVDVElPTl9UWVBFLklBTSB9O1xufVxuXG4vKiogQnVpbGQgYSBzZWN1cml0eSBncm91cCBjb25uZWN0aW9uIHJlc3VsdC4gKi9cbmZ1bmN0aW9uIGJ1aWxkU2VjdXJpdHlHcm91cFJlc3VsdChcbiAgcmVzb3VyY2U6IEFueUNvbm5lY3RvciB8IElDb25uZWN0YWJsZVxuKTogQ29ubmVjdGlvblJlc3VsdCB7XG4gIHJldHVybiB7IHJlc291cmNlLCBjb25uZWN0aW9uVHlwZTogQ09OTkVDVElPTl9UWVBFLlNFQ1VSSVRZX0dST1VQIH07XG59XG5cbi8qKiBWYWxpZGF0ZSBhbmQgbmFycm93IGFjY2VzcyB0eXBlIGZvciBzdG9yYWdlL2R5bmFtb2RiIGNvbm5lY3RvcnMuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUNvbm5lY3Rpb25BY2Nlc3MoXG4gIGFjY2VzczogQ29ubmVjdGlvbkFjY2VzcyB8IE1lc3NhZ2luZ0FjY2VzcyB8IHVuZGVmaW5lZCxcbiAgY29ubmVjdG9yVHlwZTogc3RyaW5nLFxuICBkZWZhdWx0QWNjZXNzOiBDb25uZWN0aW9uQWNjZXNzXG4pOiBDb25uZWN0aW9uQWNjZXNzIHtcbiAgaWYgKGFjY2VzcyA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZGVmYXVsdEFjY2VzcztcbiAgaWYgKGlzQ29ubmVjdGlvbkFjY2VzcyhhY2Nlc3MpKSByZXR1cm4gYWNjZXNzO1xuICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgYEludmFsaWQgYWNjZXNzIFwiJHthY2Nlc3N9XCIgZm9yICR7Y29ubmVjdG9yVHlwZX0gY29ubmVjdG9yLiBgICtcbiAgICAgIGBWYWxpZCB2YWx1ZXM6IHJlYWQsIHdyaXRlLCByZWFkV3JpdGVgXG4gICk7XG59XG5cbi8qKiBWYWxpZGF0ZSBhbmQgbmFycm93IGFjY2VzcyB0eXBlIGZvciBxdWV1ZSBjb25uZWN0b3JzLiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVNZXNzYWdpbmdBY2Nlc3MoXG4gIGFjY2VzczogQ29ubmVjdGlvbkFjY2VzcyB8IE1lc3NhZ2luZ0FjY2VzcyB8IHVuZGVmaW5lZCxcbiAgZGVmYXVsdEFjY2VzczogTWVzc2FnaW5nQWNjZXNzXG4pOiBNZXNzYWdpbmdBY2Nlc3Mge1xuICBpZiAoYWNjZXNzID09PSB1bmRlZmluZWQpIHJldHVybiBkZWZhdWx0QWNjZXNzO1xuICBpZiAoaXNNZXNzYWdpbmdBY2Nlc3MoYWNjZXNzKSkgcmV0dXJuIGFjY2VzcztcbiAgdGhyb3cgbmV3IEVycm9yKFxuICAgIGBJbnZhbGlkIGFjY2VzcyBcIiR7YWNjZXNzfVwiIGZvciBxdWV1ZSBjb25uZWN0b3IuIGAgK1xuICAgICAgYFZhbGlkIHZhbHVlczogc2VuZCwgY29uc3VtZSwgZnVsbGBcbiAgKTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlIElDb25uZWN0YWJsZSBmb3Igc2VjdXJpdHkgZ3JvdXAgb3BlcmF0aW9ucy5cbiAqIFRocm93cyBhIGRlc2NyaXB0aXZlIGVycm9yIGlmIG5vdCBwcm92aWRlZC5cbiAqL1xuZnVuY3Rpb24gcmVxdWlyZUNvbm5lY3RhYmxlKFxuICBjb25uZWN0YWJsZTogSUNvbm5lY3RhYmxlIHwgdW5kZWZpbmVkLFxuICBjb250ZXh0OiBzdHJpbmdcbik6IGFzc2VydHMgY29ubmVjdGFibGUgaXMgSUNvbm5lY3RhYmxlIHtcbiAgaWYgKCFjb25uZWN0YWJsZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGAke2NvbnRleHR9IHJlcXVpcmVzIGFuIElDb25uZWN0YWJsZSB0byBiZSBwcm92aWRlZC4gYCArXG4gICAgICAgIFwiRW5zdXJlIHRoZSBjb21wdXRlIHJlc291cmNlIChFQ1MsIEVDMiwgTGFtYmRhIHdpdGggVlBDKSBpbXBsZW1lbnRzIElDb25uZWN0YWJsZS5cIlxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiBQcm9jZXNzIGNvbm5lY3Rpb25zIGZyb20gY29tcHV0ZSByZXNvdXJjZXMgdG8gZGF0YSByZXNvdXJjZXMuXG4gKlxuICogSGFuZGxlcyB0aGUgdW5pZmllZCBjb25uZWN0b3IgaW50ZXJmYWNlLCBkaXNwYXRjaGluZyB0bzpcbiAqIC0gU2VjdXJpdHkgZ3JvdXAgcnVsZXMgZm9yIElDb25uZWN0YWJsZSBhbmQgSVNlY3VyaXR5R3JvdXBDb25uZWN0b3IgcmVzb3VyY2VzXG4gKiAtIElBTSBncmFudHMgZm9yIElTdG9yYWdlQ29ubmVjdG9yLCBJRHluYW1vREJDb25uZWN0b3IsIGFuZCBJUXVldWVDb25uZWN0b3IgcmVzb3VyY2VzXG4gKlxuICogQHBhcmFtIGNvbm5lY3Rpb25zIC0gQXJyYXkgb2YgY29ubmVjdGlvbiBzcGVjaWZpY2F0aW9uc1xuICogQHBhcmFtIGdyYW50ZWUgLSBUaGUgSUFNIGdyYW50ZWUgKHRhc2sgcm9sZSwgZXhlY3V0aW9uIHJvbGUsIGV0Yy4pXG4gKiBAcGFyYW0gY29ubmVjdGFibGUgLSBPcHRpb25hbCBJQ29ubmVjdGFibGUgZm9yIHNlY3VyaXR5IGdyb3VwIHJ1bGVzXG4gKiBAcmV0dXJucyBBcnJheSBvZiBjb25uZWN0aW9uIHJlc3VsdHNcbiAqXG4gKiBAZXhhbXBsZVxuICogcHJvY2Vzc0Nvbm5lY3Rpb25zKFxuICogICBbZGF0YWJhc2UsIHsgcmVzb3VyY2U6IGJ1Y2tldCwgYWNjZXNzOiBcInJlYWRcIiB9LCBxdWV1ZV0sXG4gKiAgIHRhc2tSb2xlLFxuICogICBzZXJ2aWNlXG4gKiApO1xuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvY2Vzc0Nvbm5lY3Rpb25zKFxuICBjb25uZWN0aW9uczogQ29ubmVjdGlvblNwZWNbXSxcbiAgZ3JhbnRlZTogSUdyYW50YWJsZSxcbiAgY29ubmVjdGFibGU/OiBJQ29ubmVjdGFibGVcbik6IENvbm5lY3Rpb25SZXN1bHRbXSB7XG4gIHJldHVybiBjb25uZWN0aW9ucy5tYXAoKHNwZWMpID0+IHtcbiAgICBjb25zdCB7IHJlc291cmNlLCBhY2Nlc3MgfSA9IGlzQ29ubmVjdGlvbkNvbmZpZyhzcGVjKVxuICAgICAgPyB7IHJlc291cmNlOiBzcGVjLnJlc291cmNlLCBhY2Nlc3M6IHNwZWMuYWNjZXNzIH1cbiAgICAgIDogeyByZXNvdXJjZTogc3BlYywgYWNjZXNzOiB1bmRlZmluZWQgfTtcblxuICAgIC8vIEhhbmRsZSB1bmlmaWVkIGNvbm5lY3RvciBpbnRlcmZhY2UgKGlzQ29ubmVjdG9yIG5vdyByZXR1cm5zIEFueUNvbm5lY3RvcilcbiAgICBpZiAoaXNDb25uZWN0b3IocmVzb3VyY2UpKSB7XG4gICAgICBzd2l0Y2ggKHJlc291cmNlLmNvbm5lY3RvclR5cGUpIHtcbiAgICAgICAgY2FzZSBcInN0b3JhZ2VcIjoge1xuICAgICAgICAgIGNvbnN0IHZhbGlkQWNjZXNzID0gdmFsaWRhdGVDb25uZWN0aW9uQWNjZXNzKFxuICAgICAgICAgICAgYWNjZXNzLFxuICAgICAgICAgICAgXCJzdG9yYWdlXCIsXG4gICAgICAgICAgICBERUZBVUxUX0FDQ0VTUy5zdG9yYWdlXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXR1cm4gYnVpbGRJYW1SZXN1bHQoXG4gICAgICAgICAgICByZXNvdXJjZSxcbiAgICAgICAgICAgIHByb2Nlc3NTdG9yYWdlQ29ubmVjdGlvbihyZXNvdXJjZSwgZ3JhbnRlZSwgdmFsaWRBY2Nlc3MpXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgXCJkeW5hbW9kYlwiOiB7XG4gICAgICAgICAgY29uc3QgdmFsaWRBY2Nlc3MgPSB2YWxpZGF0ZUNvbm5lY3Rpb25BY2Nlc3MoXG4gICAgICAgICAgICBhY2Nlc3MsXG4gICAgICAgICAgICBcImR5bmFtb2RiXCIsXG4gICAgICAgICAgICBERUZBVUxUX0FDQ0VTUy5keW5hbW9kYlxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIGJ1aWxkSWFtUmVzdWx0KFxuICAgICAgICAgICAgcmVzb3VyY2UsXG4gICAgICAgICAgICBwcm9jZXNzRHluYW1vREJDb25uZWN0aW9uKHJlc291cmNlLCBncmFudGVlLCB2YWxpZEFjY2VzcylcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY2FzZSBcInF1ZXVlXCI6IHtcbiAgICAgICAgICBjb25zdCB2YWxpZEFjY2VzcyA9IHZhbGlkYXRlTWVzc2FnaW5nQWNjZXNzKFxuICAgICAgICAgICAgYWNjZXNzLFxuICAgICAgICAgICAgREVGQVVMVF9BQ0NFU1MucXVldWVcbiAgICAgICAgICApO1xuICAgICAgICAgIHJldHVybiBidWlsZElhbVJlc3VsdChcbiAgICAgICAgICAgIHJlc291cmNlLFxuICAgICAgICAgICAgcHJvY2Vzc1F1ZXVlQ29ubmVjdGlvbihyZXNvdXJjZSwgZ3JhbnRlZSwgdmFsaWRBY2Nlc3MpXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNhc2UgXCJzZWN1cml0eUdyb3VwXCI6XG4gICAgICAgIGNhc2UgXCJyZWxhdGlvbmFsXCI6IHtcbiAgICAgICAgICByZXF1aXJlQ29ubmVjdGFibGUoXG4gICAgICAgICAgICBjb25uZWN0YWJsZSxcbiAgICAgICAgICAgIGAke3Jlc291cmNlLmNvbm5lY3RvclR5cGV9IGNvbm5lY3RvcmBcbiAgICAgICAgICApO1xuICAgICAgICAgIGNvbm5lY3RhYmxlLmNvbm5lY3Rpb25zLmFsbG93VG9EZWZhdWx0UG9ydChyZXNvdXJjZSk7XG4gICAgICAgICAgcmV0dXJuIGJ1aWxkU2VjdXJpdHlHcm91cFJlc3VsdChyZXNvdXJjZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBMZWdhY3kgSUNvbm5lY3RhYmxlIHBhdGhcbiAgICBpZiAoaXNDb25uZWN0YWJsZShyZXNvdXJjZSkpIHtcbiAgICAgIHJlcXVpcmVDb25uZWN0YWJsZShjb25uZWN0YWJsZSwgXCJJQ29ubmVjdGFibGUgcmVzb3VyY2VcIik7XG4gICAgICBjb25uZWN0YWJsZS5jb25uZWN0aW9ucy5hbGxvd1RvRGVmYXVsdFBvcnQocmVzb3VyY2UpO1xuICAgICAgcmV0dXJuIGJ1aWxkU2VjdXJpdHlHcm91cFJlc3VsdChyZXNvdXJjZSk7XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJDb25uZWN0aW9uIHJlc291cmNlIG11c3QgYmUgZWl0aGVyIGFuIElDb25uZWN0b3Igb3IgSUNvbm5lY3RhYmxlXCJcbiAgICApO1xuICB9KTtcbn1cbiJdfQ==
@@ -1,7 +1,12 @@
1
1
  import { Construct } from "constructs";
2
2
  import type App from "../../app";
3
- import { type Secret } from "../../resources/aws/secrets";
3
+ import { type DynamoDBKeySchema, type DynamoDBGlobalSecondaryIndex } from "../../resources/aws/database/dynamodb";
4
4
  import { type Connections, type IConnectable, type IVpc, type SubnetSelection } from "aws-cdk-lib/aws-ec2";
5
+ import { type ITable } from "aws-cdk-lib/aws-dynamodb";
6
+ import { type Secret } from "../../resources/aws/secrets";
7
+ import { type IGrantable, type Grant } from "aws-cdk-lib/aws-iam";
8
+ import { type IRelationalDatabase, type IDynamoDBDatabase, type RelationalDatabaseType } from "./interfaces/database.js";
9
+ import { type IDynamoDBConnector, type ISecurityGroupConnector } from "./interfaces/connector.js";
5
10
  import { type IInstanceEngine, type IClusterEngine } from "aws-cdk-lib/aws-rds";
6
11
  import { Duration } from "aws-cdk-lib";
7
12
  import { type IKey } from "aws-cdk-lib/aws-kms";
@@ -132,6 +137,21 @@ export interface AuroraDatabaseProps extends BaseDatabaseProps {
132
137
  snapshotIdentifier?: string;
133
138
  /** Username from the snapshot (required when restoring from snapshot to reset password) */
134
139
  snapshotUsername?: string;
140
+ /** Allow access from VPC CIDR (avoids cross-stack cyclic dependencies with Lambda) */
141
+ allowVpcAccess?: boolean;
142
+ /**
143
+ * Make database publicly accessible from the internet.
144
+ * WARNING: This is a security risk and should only be used for development
145
+ * or when building Payload apps locally that need database access.
146
+ * When enabled, the database is placed in public subnets.
147
+ */
148
+ publiclyAccessible?: boolean;
149
+ /**
150
+ * IP address to allow access from when publiclyAccessible is true.
151
+ * If not specified, access is restricted to VPC only even when public.
152
+ * Format: CIDR notation (e.g., "203.0.113.0/32" for single IP)
153
+ */
154
+ allowedIpCidr?: string;
135
155
  }
136
156
  export interface GlobalAuroraDatabaseProps extends BaseDatabaseProps {
137
157
  type: "GlobalAurora";
@@ -178,19 +198,106 @@ export interface InstanceDatabaseProps extends BaseDatabaseProps {
178
198
  /** Username from the snapshot (required when restoring from snapshot to reset password) */
179
199
  snapshotUsername?: string;
180
200
  }
181
- export type IDatabaseProps = AuroraDatabaseProps | InstanceDatabaseProps | GlobalAuroraDatabaseProps;
201
+ /**
202
+ * DynamoDB table configuration properties.
203
+ */
204
+ export interface DynamoDBDatabaseProps {
205
+ type: "DynamoDB";
206
+ partitionKey: DynamoDBKeySchema;
207
+ sortKey?: DynamoDBKeySchema;
208
+ billingMode?: "PAY_PER_REQUEST" | "PROVISIONED";
209
+ readCapacity?: number;
210
+ writeCapacity?: number;
211
+ globalSecondaryIndexes?: DynamoDBGlobalSecondaryIndex[];
212
+ timeToLiveAttribute?: string;
213
+ stream?: "NEW_IMAGE" | "OLD_IMAGE" | "NEW_AND_OLD_IMAGES" | "KEYS_ONLY";
214
+ pointInTimeRecovery?: boolean;
215
+ encryption?: "AWS_OWNED" | "AWS_MANAGED" | "CUSTOMER_MANAGED";
216
+ removalPolicy?: "DESTROY" | "RETAIN" | "SNAPSHOT";
217
+ }
218
+ /**
219
+ * Relational database props union (Aurora, Instance, GlobalAurora).
220
+ */
221
+ export type IRelationalDatabaseProps = AuroraDatabaseProps | InstanceDatabaseProps | GlobalAuroraDatabaseProps;
222
+ /**
223
+ * All database props union.
224
+ */
225
+ export type IDatabaseProps = AuroraDatabaseProps | InstanceDatabaseProps | GlobalAuroraDatabaseProps | DynamoDBDatabaseProps;
226
+ /**
227
+ * Factory for creating type-safe database resources.
228
+ *
229
+ * @example
230
+ * // Aurora database - returns RelationalDatabase
231
+ * const aurora = app.addDatabase(DatabaseFactory.build("Main", {
232
+ * type: "Aurora",
233
+ * databaseName: "myapp"
234
+ * }));
235
+ * aurora.getHostEndpoint(); // Available
236
+ *
237
+ * @example
238
+ * // DynamoDB table - returns DynamoDBDatabase
239
+ * const cache = app.addDatabase(DatabaseFactory.build("Cache", {
240
+ * type: "DynamoDB",
241
+ * partitionKey: { name: "id", type: "S" }
242
+ * }));
243
+ * cache.getTableName(); // Available
244
+ * cache.grantReadWriteData(lambda); // Available
245
+ */
182
246
  export declare class DatabaseFactory {
183
- static build<T extends IDatabaseProps>(id: string, props: T): (app: App, scope: Construct) => Database;
247
+ static build(id: string, props: AuroraDatabaseProps): (app: App, scope: Construct) => RelationalDatabase;
248
+ static build(id: string, props: InstanceDatabaseProps): (app: App, scope: Construct) => RelationalDatabase;
249
+ static build(id: string, props: GlobalAuroraDatabaseProps): (app: App, scope: Construct) => RelationalDatabase;
250
+ static build(id: string, props: DynamoDBDatabaseProps): (app: App, scope: Construct) => DynamoDBDatabase;
251
+ }
252
+ /**
253
+ * DynamoDB database wrapper implementing IDynamoDBDatabase interface.
254
+ * Provides type-safe access to DynamoDB table operations.
255
+ *
256
+ * @example
257
+ * const cache = app.addDatabase(DatabaseFactory.build("Cache", {
258
+ * type: "DynamoDB",
259
+ * partitionKey: { name: "id", type: "S" }
260
+ * }));
261
+ * cache.grantReadWriteData(lambda);
262
+ */
263
+ export declare class DynamoDBDatabase extends Construct implements IDynamoDBDatabase, IDynamoDBConnector {
264
+ readonly databaseType: "DynamoDB";
265
+ readonly connectorType: "dynamodb";
266
+ readonly id: string;
267
+ private readonly table;
268
+ constructor(scope: Construct, id: string, props: DynamoDBDatabaseProps);
269
+ getTableName(): string;
270
+ getTableArn(): string;
271
+ getTable(): ITable;
272
+ getStreamArn(): string | undefined;
273
+ grantReadData(grantee: IGrantable): Grant;
274
+ grantWriteData(grantee: IGrantable): Grant;
275
+ grantReadWriteData(grantee: IGrantable): Grant;
276
+ grantFullAccess(grantee: IGrantable): Grant;
277
+ grantStreamRead(grantee: IGrantable): Grant;
184
278
  }
185
- export declare class Database extends Construct implements IConnectable {
186
- id: string;
187
- scope: Construct;
188
- vpc: IVpc;
279
+ /**
280
+ * Relational database wrapper implementing IRelationalDatabase interface.
281
+ * Supports Aurora, RDS Instance, and GlobalAurora database types.
282
+ *
283
+ * @example
284
+ * const db = app.addDatabase(DatabaseFactory.build("Main", {
285
+ * type: "Aurora",
286
+ * databaseName: "myapp"
287
+ * }));
288
+ * db.grantConnect(lambda);
289
+ */
290
+ export declare class RelationalDatabase extends Construct implements IRelationalDatabase, ISecurityGroupConnector {
291
+ readonly id: string;
292
+ readonly scope: Construct;
293
+ readonly vpc: IVpc;
294
+ readonly databaseType: RelationalDatabaseType;
295
+ readonly connectorType: "relational";
189
296
  connections: Connections;
190
- private databaseName;
297
+ private readonly _databaseName;
191
298
  private database;
192
- constructor(scope: Construct, id: string, props: IDatabaseProps);
193
- addDatabase(props: IDatabaseProps): void;
299
+ constructor(scope: Construct, id: string, props: IRelationalDatabaseProps);
300
+ addDatabase(props: IRelationalDatabaseProps): void;
194
301
  private addAurora;
195
302
  private addAuroraGlobal;
196
303
  private addRdsInstance;
@@ -199,5 +306,11 @@ export declare class Database extends Construct implements IConnectable {
199
306
  getHostEndpoint(): string;
200
307
  getHostPort(): string;
201
308
  getDatabaseName(): string;
309
+ /**
310
+ * Grant connect permissions to a grantee by adding it to the database security group.
311
+ * @param grantee The connectable principal to grant connect permissions to
312
+ */
313
+ grantConnect(grantee: IConnectable): void;
202
314
  }
203
- export {};
315
+ export type { DynamoDBKeySchema, DynamoDBGlobalSecondaryIndex, DynamoDBTableProps } from "../../resources/aws/database/dynamodb";
316
+ export { type IRelationalDatabase, type IDynamoDBDatabase, type AnyDatabase, type DatabaseType, type RelationalDatabaseType, isRelationalDatabase, isDynamoDBDatabase, isAuroraDatabase, isInstanceDatabase, isGlobalAuroraDatabase } from "./interfaces/database.js";