cdk-rds-sql 6.1.1 → 6.1.2

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,26 +1,13 @@
1
1
  import { SecretsManagerClient } from "@aws-sdk/client-secrets-manager"
2
2
  import { createConnection } from "mysql2/promise"
3
3
  import { GenericContainer, StartedTestContainer } from "testcontainers"
4
- import { createRequest, updateRequest, deleteRequest } from "./util"
5
4
  import { handler } from "./handler"
5
+ import { createRequest, updateRequest, deleteRequest } from "./util"
6
6
 
7
7
  jest.mock("@aws-sdk/client-secrets-manager")
8
8
  const SecretsManagerClientMock = SecretsManagerClient as jest.MockedClass<
9
9
  typeof SecretsManagerClient
10
10
  >
11
- SecretsManagerClientMock.prototype.send.mockImplementation(() => {
12
- return {
13
- SecretString: JSON.stringify({
14
- host: mysqlHost,
15
- port: mysqlPort,
16
- username: DB_MASTER_USERNAME,
17
- password: DB_MASTER_PASSWORD,
18
- dbname: DB_DEFAULT_DB,
19
- engine: "mysql",
20
- dbClusterIdentifier: "dummy",
21
- }),
22
- }
23
- })
24
11
 
25
12
  const DB_PORT = 3306
26
13
  const DB_MASTER_USERNAME = "root"
@@ -45,6 +32,21 @@ beforeEach(async () => {
45
32
  .start()
46
33
  mysqlHost = mysqlContainer.getHost()
47
34
  mysqlPort = mysqlContainer.getMappedPort(DB_PORT)
35
+
36
+ // Set up the mock after we have the host and port values
37
+ SecretsManagerClientMock.prototype.send.mockImplementation(() => {
38
+ return {
39
+ SecretString: JSON.stringify({
40
+ host: mysqlHost,
41
+ port: mysqlPort,
42
+ username: DB_MASTER_USERNAME,
43
+ password: DB_MASTER_PASSWORD,
44
+ dbname: DB_DEFAULT_DB,
45
+ engine: "mysql",
46
+ dbClusterIdentifier: "dummy",
47
+ }),
48
+ }
49
+ })
48
50
  }, 30000)
49
51
 
50
52
  afterEach(async () => {
@@ -57,14 +59,14 @@ afterEach(async () => {
57
59
  // Helper functions for MySQL tests
58
60
  async function databaseExists(connection: any, dbName: string): Promise<boolean> {
59
61
  const [rows] = await connection.query(
60
- `SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?`,
62
+ "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?",
61
63
  [dbName]
62
64
  )
63
65
  return rows.length > 0
64
66
  }
65
67
 
66
68
  async function userExists(connection: any, username: string): Promise<boolean> {
67
- const [rows] = await connection.query(`SELECT User FROM mysql.user WHERE User = ?`, [
69
+ const [rows] = await connection.query("SELECT User FROM mysql.user WHERE User = ?", [
68
70
  username,
69
71
  ])
70
72
  return rows.length > 0
@@ -76,7 +78,7 @@ async function tableExists(
76
78
  tableName: string
77
79
  ): Promise<boolean> {
78
80
  const [rows] = await connection.query(
79
- `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?`,
81
+ "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?",
80
82
  [dbName, tableName]
81
83
  )
82
84
  return rows.length > 0
@@ -103,7 +105,7 @@ test("database", async () => {
103
105
  const newDatabaseName = "mydb2"
104
106
  const create = createRequest("database", oldDatabaseName)
105
107
  await handler(create)
106
- expect(SecretsManagerClientMock).toHaveBeenCalledTimes(1)
108
+ expect(SecretsManagerClientMock.prototype.send).toHaveBeenCalledTimes(1)
107
109
  const connection = await newConnection()
108
110
  try {
109
111
  expect(await databaseExists(connection, oldDatabaseName)).toEqual(true)
@@ -188,7 +190,7 @@ describe("User creation", () => {
188
190
  DatabaseName: DB_DEFAULT_DB,
189
191
  })
190
192
  await handler(create)
191
- expect(SecretsManagerClientMock).toHaveBeenCalledTimes(2)
193
+ expect(SecretsManagerClientMock.prototype.send).toHaveBeenCalledTimes(2)
192
194
 
193
195
  const connection = await newConnection()
194
196
  try {
@@ -227,7 +229,7 @@ describe("User creation", () => {
227
229
  DatabaseName: DB_DEFAULT_DB,
228
230
  })
229
231
  await handler(create)
230
- expect(SecretsManagerClientMock).toHaveBeenCalledTimes(2)
232
+ expect(SecretsManagerClientMock.prototype.send).toHaveBeenCalledTimes(2)
231
233
 
232
234
  const connection = await newConnection()
233
235
  try {
@@ -1,6 +1,7 @@
1
1
  import { SecretsManagerClient } from "@aws-sdk/client-secrets-manager"
2
2
  import { Client, ClientConfig } from "pg"
3
3
  import { GenericContainer, StartedTestContainer } from "testcontainers"
4
+ import { handler } from "./handler"
4
5
  import {
5
6
  createRequest,
6
7
  updateRequest,
@@ -12,7 +13,6 @@ import {
12
13
  rowCount,
13
14
  roleGrantedForSchema,
14
15
  } from "./util"
15
- import { handler } from "./handler"
16
16
 
17
17
  jest.mock("@aws-sdk/client-secrets-manager")
18
18
  const SecretsManagerClientMock = SecretsManagerClient as jest.MockedClass<
@@ -71,7 +71,7 @@ test("schema", async () => {
71
71
  const newSchemaName = "test2"
72
72
  const create = createRequest("schema", oldSchemaName)
73
73
  await handler(create)
74
- expect(SecretsManagerClientMock).toHaveBeenCalledTimes(1)
74
+ expect(SecretsManagerClientMock.prototype.send).toHaveBeenCalledTimes(1)
75
75
 
76
76
  const client = await newClient()
77
77
  try {
@@ -128,7 +128,7 @@ test("role with existing database", async () => {
128
128
  DatabaseName: "postgres",
129
129
  })
130
130
  await handler(create)
131
- expect(SecretsManagerClientMock).toHaveBeenCalledTimes(2)
131
+ expect(SecretsManagerClientMock.prototype.send).toHaveBeenCalledTimes(2)
132
132
  const client = await newClient()
133
133
  try {
134
134
  expect(await roleExists(client, oldRoleName)).toEqual(true)
@@ -165,7 +165,7 @@ test("role without database", async () => {
165
165
  PasswordArn: "arn:aws:secretsmanager:us-east-1:123456789:secret:dummy",
166
166
  })
167
167
  await handler(create)
168
- expect(SecretsManagerClientMock).toHaveBeenCalledTimes(2)
168
+ expect(SecretsManagerClientMock.prototype.send).toHaveBeenCalledTimes(2)
169
169
  const client = await newClient()
170
170
  try {
171
171
  expect(await roleExists(client, roleName)).toEqual(true)
@@ -180,7 +180,7 @@ test("change role password", async () => {
180
180
  PasswordArn: "arn:aws:secretsmanager:us-east-1:123456789:secret:dummy",
181
181
  })
182
182
  await handler(create)
183
- expect(SecretsManagerClientMock).toHaveBeenCalledTimes(2)
183
+ expect(SecretsManagerClientMock.prototype.send).toHaveBeenCalledTimes(2)
184
184
  const client = await newClient()
185
185
  try {
186
186
  expect(await roleExists(client, roleName)).toEqual(true)
@@ -198,7 +198,7 @@ test("database", async () => {
198
198
  const newDatabaseName = "mydb2"
199
199
  const create = createRequest("database", oldDatabaseName)
200
200
  await handler(create)
201
- expect(SecretsManagerClientMock).toHaveBeenCalledTimes(1)
201
+ expect(SecretsManagerClientMock.prototype.send).toHaveBeenCalledTimes(1)
202
202
  const client = await newClient()
203
203
  try {
204
204
  expect(await databaseExists(client, oldDatabaseName)).toEqual(true)
@@ -0,0 +1,164 @@
1
+ import { SecretsManagerClient } from "@aws-sdk/client-secrets-manager"
2
+ import { MysqlEngine } from "./engine.mysql"
3
+ import { PostgresqlEngine } from "./engine.postgresql"
4
+ import { handler } from "./handler"
5
+ import { createRequest } from "./util"
6
+
7
+ // Mock the secrets manager client
8
+ jest.mock("@aws-sdk/client-secrets-manager")
9
+ const SecretsManagerClientMock = SecretsManagerClient as jest.MockedClass<
10
+ typeof SecretsManagerClient
11
+ >
12
+
13
+ // Mock the database engines
14
+ jest.mock("./engine.mysql")
15
+ jest.mock("./engine.postgresql")
16
+
17
+ const MockedMysqlEngine = MysqlEngine as jest.MockedClass<typeof MysqlEngine>
18
+ const MockedPostgresqlEngine = PostgresqlEngine as jest.MockedClass<
19
+ typeof PostgresqlEngine
20
+ >
21
+
22
+ describe("Handler CloudFormation Property Conversion", () => {
23
+ let mockMysqlEngine: jest.Mocked<MysqlEngine>
24
+ let mockPostgresqlEngine: jest.Mocked<PostgresqlEngine>
25
+
26
+ beforeEach(() => {
27
+ jest.clearAllMocks()
28
+
29
+ // Mock the engine instances
30
+ mockMysqlEngine = {
31
+ createRole: jest.fn(),
32
+ executeSQL: jest.fn(),
33
+ } as any
34
+
35
+ mockPostgresqlEngine = {
36
+ createRole: jest.fn(),
37
+ executeSQL: jest.fn(),
38
+ } as any
39
+
40
+ MockedMysqlEngine.mockImplementation(() => mockMysqlEngine)
41
+ MockedPostgresqlEngine.mockImplementation(() => mockPostgresqlEngine)
42
+
43
+ // Mock secrets manager to return MySQL engine
44
+ SecretsManagerClientMock.prototype.send.mockImplementation(() => {
45
+ return Promise.resolve({
46
+ SecretString: JSON.stringify({
47
+ host: "localhost",
48
+ port: 3306,
49
+ username: "root",
50
+ password: "password",
51
+ dbname: "test",
52
+ engine: "mysql",
53
+ }),
54
+ })
55
+ })
56
+ })
57
+
58
+ describe("EnableIamAuth property conversion", () => {
59
+ it("should convert string 'false' to boolean false", async () => {
60
+ mockMysqlEngine.createRole.mockResolvedValue(["CREATE USER test"])
61
+ mockMysqlEngine.executeSQL.mockResolvedValue({})
62
+
63
+ // Create a request with EnableIamAuth as string 'false' (simulating CloudFormation)
64
+ const request = createRequest("role", "testuser", {
65
+ EnableIamAuth: "false",
66
+ PasswordArn: "arn:aws:secretsmanager:us-east-1:123456789:secret:dummy",
67
+ })
68
+
69
+ await handler(request)
70
+
71
+ // Verify that createRole was called with boolean false, not string 'false'
72
+ expect(mockMysqlEngine.createRole).toHaveBeenCalledWith(
73
+ "testuser",
74
+ expect.objectContaining({
75
+ EnableIamAuth: false, // Should be converted to boolean false
76
+ PasswordArn: "arn:aws:secretsmanager:us-east-1:123456789:secret:dummy",
77
+ })
78
+ )
79
+ })
80
+
81
+ it("should convert string 'true' to boolean true", async () => {
82
+ mockMysqlEngine.createRole.mockResolvedValue(["CREATE USER test"])
83
+ mockMysqlEngine.executeSQL.mockResolvedValue({})
84
+
85
+ // Create a request with EnableIamAuth as string 'true' (simulating CloudFormation)
86
+ const request = createRequest("role", "testuser", {
87
+ EnableIamAuth: "true", // CloudFormation passes boolean as string
88
+ })
89
+
90
+ await handler(request)
91
+
92
+ // Verify that createRole was called with boolean true, not string 'true'
93
+ expect(mockMysqlEngine.createRole).toHaveBeenCalledWith(
94
+ "testuser",
95
+ expect.objectContaining({
96
+ EnableIamAuth: true, // Should be converted to boolean true
97
+ })
98
+ )
99
+ })
100
+
101
+ it("should handle number 0 correctly", async () => {
102
+ mockMysqlEngine.createRole.mockResolvedValue(["CREATE USER test"])
103
+ mockMysqlEngine.executeSQL.mockResolvedValue({})
104
+
105
+ // Create a request with EnableIamAuth as actual boolean false
106
+ const request = createRequest("role", "testuser", {
107
+ EnableIamAuth: "0",
108
+ PasswordArn: "arn:aws:secretsmanager:us-east-1:123456789:secret:dummy",
109
+ })
110
+
111
+ await handler(request)
112
+
113
+ // Verify that createRole was called with boolean false
114
+ expect(mockMysqlEngine.createRole).toHaveBeenCalledWith(
115
+ "testuser",
116
+ expect.objectContaining({
117
+ EnableIamAuth: false,
118
+ PasswordArn: "arn:aws:secretsmanager:us-east-1:123456789:secret:dummy",
119
+ })
120
+ )
121
+ })
122
+
123
+ it("should handle number 1 correctly", async () => {
124
+ mockMysqlEngine.createRole.mockResolvedValue(["CREATE USER test"])
125
+ mockMysqlEngine.executeSQL.mockResolvedValue({})
126
+
127
+ // Create a request with EnableIamAuth as actual boolean true
128
+ const request = createRequest("role", "testuser", {
129
+ EnableIamAuth: "1",
130
+ })
131
+
132
+ await handler(request)
133
+
134
+ // Verify that createRole was called with boolean true
135
+ expect(mockMysqlEngine.createRole).toHaveBeenCalledWith(
136
+ "testuser",
137
+ expect.objectContaining({
138
+ EnableIamAuth: true,
139
+ })
140
+ )
141
+ })
142
+
143
+ it("should handle undefined EnableIamAuth correctly", async () => {
144
+ mockMysqlEngine.createRole.mockResolvedValue(["CREATE USER test"])
145
+ mockMysqlEngine.executeSQL.mockResolvedValue({})
146
+
147
+ // Create a request without EnableIamAuth property
148
+ const request = createRequest("role", "testuser", {
149
+ PasswordArn: "arn:aws:secretsmanager:us-east-1:123456789:secret:dummy",
150
+ })
151
+
152
+ await handler(request)
153
+
154
+ // Verify that createRole was called without EnableIamAuth
155
+ expect(mockMysqlEngine.createRole).toHaveBeenCalledWith(
156
+ "testuser",
157
+ expect.objectContaining({
158
+ PasswordArn: "arn:aws:secretsmanager:us-east-1:123456789:secret:dummy",
159
+ EnableIamAuth: false,
160
+ })
161
+ )
162
+ })
163
+ })
164
+ })
package/lambda/handler.ts CHANGED
@@ -15,10 +15,17 @@ import {
15
15
  CloudFormationCustomResourceDeleteEvent,
16
16
  } from "aws-lambda"
17
17
  import { backOff } from "exponential-backoff"
18
- import { EngineFactory } from "./engine.factory"
19
18
  import { EngineConnectionConfig } from "./engine.abstract"
19
+ import { EngineFactory } from "./engine.factory"
20
+ import {
21
+ ResourceProperties,
22
+ CustomResourceResponse,
23
+ EngineDatabaseProperties,
24
+ EngineRoleProperties,
25
+ EngineSchemaProperties,
26
+ EngineSqlProperties,
27
+ } from "./types"
20
28
  import { RdsSqlResource } from "../src/enum"
21
- import { ResourceProperties, CustomResourceResponse } from "./types"
22
29
 
23
30
  const maxAttempts = 20
24
31
 
@@ -29,6 +36,40 @@ const log =
29
36
 
30
37
  const secrets_client = new SecretsManagerClient({})
31
38
 
39
+ // Helper functions to extract engine properties from CloudFormation properties
40
+ // These functions throw if the resource type doesn't match the expected type
41
+ function toDatabaseEngineProps(props: ResourceProperties): EngineDatabaseProperties {
42
+ if (props.Resource !== RdsSqlResource.DATABASE) {
43
+ throw new Error(`Expected DATABASE resource, got ${props.Resource}`)
44
+ }
45
+ return props
46
+ }
47
+
48
+ function toRoleEngineProps(props: ResourceProperties): EngineRoleProperties {
49
+ if (props.Resource !== RdsSqlResource.ROLE) {
50
+ throw new Error(`Expected ROLE resource, got ${props.Resource}`)
51
+ }
52
+ // Convert string 'true'/'false' to boolean for EnableIamAuth
53
+ return {
54
+ ...props,
55
+ EnableIamAuth: props.EnableIamAuth === "true" || props.EnableIamAuth === "1",
56
+ }
57
+ }
58
+
59
+ function toSchemaEngineProps(props: ResourceProperties): EngineSchemaProperties {
60
+ if (props.Resource !== RdsSqlResource.SCHEMA) {
61
+ throw new Error(`Expected SCHEMA resource, got ${props.Resource}`)
62
+ }
63
+ return props
64
+ }
65
+
66
+ function toSqlEngineProps(props: ResourceProperties): EngineSqlProperties {
67
+ if (props.Resource !== RdsSqlResource.SQL) {
68
+ throw new Error(`Expected SQL resource, got ${props.Resource}`)
69
+ }
70
+ return props
71
+ }
72
+
32
73
  export const handler = async (
33
74
  event:
34
75
  | CloudFormationCustomResourceCreateEvent<ResourceProperties>
@@ -82,16 +123,25 @@ export const handler = async (
82
123
  case "Create": {
83
124
  switch (resource) {
84
125
  case RdsSqlResource.DATABASE:
85
- sql = dbEngine.createDatabase(resourceId, event.ResourceProperties)
126
+ sql = dbEngine.createDatabase(
127
+ resourceId,
128
+ toDatabaseEngineProps(event.ResourceProperties)
129
+ )
86
130
  break
87
131
  case RdsSqlResource.ROLE:
88
- sql = await dbEngine.createRole(resourceId, event.ResourceProperties)
132
+ sql = await dbEngine.createRole(
133
+ resourceId,
134
+ toRoleEngineProps(event.ResourceProperties)
135
+ )
89
136
  break
90
137
  case RdsSqlResource.SCHEMA:
91
- sql = dbEngine.createSchema(resourceId, event.ResourceProperties)
138
+ sql = dbEngine.createSchema(
139
+ resourceId,
140
+ toSchemaEngineProps(event.ResourceProperties)
141
+ )
92
142
  break
93
143
  case RdsSqlResource.SQL:
94
- sql = dbEngine.createSql(resourceId, event.ResourceProperties)
144
+ sql = dbEngine.createSql(resourceId, toSqlEngineProps(event.ResourceProperties))
95
145
  break
96
146
  case RdsSqlResource.PARAMETER_PASSWORD:
97
147
  await handleParameterPassword(event.ResourceProperties)
@@ -104,24 +154,35 @@ export const handler = async (
104
154
  .PhysicalResourceId
105
155
  switch (resource) {
106
156
  case RdsSqlResource.DATABASE:
157
+ const dbProps = toDatabaseEngineProps(event.ResourceProperties)
107
158
  sql = dbEngine.updateDatabase(resourceId, oldResourceId, {
108
- ...event.ResourceProperties,
159
+ ...dbProps,
109
160
  MasterOwner: secretValues.username,
110
161
  })
111
162
  break
112
163
  case RdsSqlResource.ROLE:
164
+ const updateEvent =
165
+ event as CloudFormationCustomResourceUpdateEvent<ResourceProperties>
113
166
  sql = await dbEngine.updateRole(
114
167
  resourceId,
115
168
  oldResourceId,
116
- event.ResourceProperties,
117
- (event as CloudFormationCustomResourceUpdateEvent).OldResourceProperties
169
+ toRoleEngineProps(event.ResourceProperties),
170
+ toRoleEngineProps(updateEvent.OldResourceProperties)
118
171
  )
119
172
  break
120
173
  case RdsSqlResource.SCHEMA:
121
- sql = dbEngine.updateSchema(resourceId, oldResourceId, event.ResourceProperties)
174
+ sql = dbEngine.updateSchema(
175
+ resourceId,
176
+ oldResourceId,
177
+ toSchemaEngineProps(event.ResourceProperties)
178
+ )
122
179
  break
123
180
  case RdsSqlResource.SQL:
124
- sql = dbEngine.updateSql(resourceId, oldResourceId, event.ResourceProperties)
181
+ sql = dbEngine.updateSql(
182
+ resourceId,
183
+ oldResourceId,
184
+ toSqlEngineProps(event.ResourceProperties)
185
+ )
125
186
  break
126
187
  case RdsSqlResource.PARAMETER_PASSWORD:
127
188
  await handleParameterPassword(event.ResourceProperties)
@@ -136,13 +197,19 @@ export const handler = async (
136
197
  sql = dbEngine.deleteDatabase(resourceId, secretValues.username)
137
198
  break
138
199
  case RdsSqlResource.ROLE:
139
- sql = dbEngine.deleteRole(resourceId, event.ResourceProperties)
200
+ sql = dbEngine.deleteRole(
201
+ resourceId,
202
+ toRoleEngineProps(event.ResourceProperties)
203
+ )
140
204
  break
141
205
  case RdsSqlResource.SCHEMA:
142
- sql = dbEngine.deleteSchema(resourceId, event.ResourceProperties)
206
+ sql = dbEngine.deleteSchema(
207
+ resourceId,
208
+ toSchemaEngineProps(event.ResourceProperties)
209
+ )
143
210
  break
144
211
  case RdsSqlResource.SQL:
145
- sql = dbEngine.deleteSql(resourceId, event.ResourceProperties)
212
+ sql = dbEngine.deleteSql(resourceId, toSqlEngineProps(event.ResourceProperties))
146
213
  break
147
214
  case RdsSqlResource.PARAMETER_PASSWORD:
148
215
  await deleteParameterPassword(event.ResourceProperties)
package/lambda/types.ts CHANGED
@@ -1,7 +1,30 @@
1
1
  import { CloudFormationCustomResourceResourcePropertiesCommon } from "aws-lambda"
2
2
  import { RdsSqlResource } from "../src/enum"
3
3
 
4
- // Common properties shared by all resources
4
+ // Engine-specific interfaces (business logic properties only)
5
+ export interface EngineDatabaseProperties {
6
+ readonly Owner?: string
7
+ readonly MasterOwner?: string
8
+ }
9
+
10
+ export interface EngineRoleProperties {
11
+ readonly PasswordArn?: string
12
+ readonly DatabaseName?: string
13
+ readonly EnableIamAuth?: boolean
14
+ }
15
+
16
+ export interface EngineSchemaProperties {
17
+ readonly DatabaseName?: string
18
+ readonly RoleName?: string
19
+ }
20
+
21
+ export interface EngineSqlProperties {
22
+ readonly DatabaseName?: string
23
+ readonly Statement?: string
24
+ readonly Rollback?: string
25
+ }
26
+
27
+ // Common CloudFormation properties shared by all resources
5
28
  export interface CommonProperties
6
29
  extends CloudFormationCustomResourceResourcePropertiesCommon {
7
30
  readonly Resource: RdsSqlResource
@@ -9,32 +32,24 @@ export interface CommonProperties
9
32
  readonly SecretArn: string
10
33
  }
11
34
 
12
- // Database specific properties
13
- export interface DatabaseProperties extends CommonProperties {
35
+ // CloudFormation-specific properties (engine properties + CloudFormation metadata)
36
+ export interface DatabaseProperties extends CommonProperties, EngineDatabaseProperties {
14
37
  readonly Resource: RdsSqlResource.DATABASE
15
- readonly Owner?: string
16
38
  }
17
39
 
18
- // Role specific properties
19
40
  export interface RoleProperties extends CommonProperties {
20
41
  readonly Resource: RdsSqlResource.ROLE
21
42
  readonly PasswordArn?: string
22
43
  readonly DatabaseName?: string
44
+ readonly EnableIamAuth?: string // CloudFormation passes boolean as string
23
45
  }
24
46
 
25
- // Schema specific properties
26
- export interface SchemaProperties extends CommonProperties {
47
+ export interface SchemaProperties extends CommonProperties, EngineSchemaProperties {
27
48
  readonly Resource: RdsSqlResource.SCHEMA
28
- readonly DatabaseName?: string
29
- readonly RoleName?: string
30
49
  }
31
50
 
32
- // SQL specific properties
33
- export interface SqlProperties extends CommonProperties {
51
+ export interface SqlProperties extends CommonProperties, EngineSqlProperties {
34
52
  readonly Resource: RdsSqlResource.SQL
35
- readonly DatabaseName?: string
36
- readonly Statement?: string
37
- readonly Rollback?: string
38
53
  }
39
54
 
40
55
  // Parameter password specific properties
package/lambda/util.ts CHANGED
@@ -25,7 +25,7 @@ export interface ResourcePropertiesInput {
25
25
  export const createRequest = (
26
26
  resource: string,
27
27
  resourceId: string,
28
- props?: ResourcePropertiesInput
28
+ props?: Partial<ResourceProperties>
29
29
  ): CloudFormationCustomResourceCreateEvent<ResourceProperties> => {
30
30
  return {
31
31
  ServiceToken: "",
@@ -41,7 +41,7 @@ export const createRequest = (
41
41
  SecretArn:
42
42
  props?.SecretArn || "arn:aws:secretsmanager:us-east-1:123456789:secret:dummy",
43
43
  ...props,
44
- } as unknown as ResourceProperties,
44
+ },
45
45
  RequestType: "Create",
46
46
  }
47
47
  }
package/lib/database.js CHANGED
@@ -40,5 +40,5 @@ class Database extends aws_cdk_lib_1.CustomResource {
40
40
  }
41
41
  exports.Database = Database;
42
42
  _a = JSII_RTTI_SYMBOL_1;
43
- Database[_a] = { fqn: "cdk-rds-sql.Database", version: "6.1.1" };
43
+ Database[_a] = { fqn: "cdk-rds-sql.Database", version: "6.1.2" };
44
44
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWJhc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZGF0YWJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2Q0FBNEM7QUFDNUMsMkNBQXNDO0FBQ3RDLGlDQUF1QztBQTJCdkMsTUFBTSxnQkFBaUIsU0FBUSxzQkFBUztJQUd0QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXlCO1FBQ2pFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFDaEIsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUMsWUFBWSxDQUFBO0lBQ3hDLENBQUM7Q0FDRjtBQUVELE1BQWEsUUFBUyxTQUFRLDRCQUFjO0lBQzFDOztPQUVHO0lBQ0gsTUFBTSxDQUFDLGdCQUFnQixDQUFDLEtBQWdCLEVBQUUsRUFBVSxFQUFFLFlBQW9CO1FBQ3hFLE9BQU8sSUFBSSxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ3JDLFlBQVksRUFBRSxZQUFZO1NBQzNCLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFJRCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQW9CO1FBQzVELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ2YsWUFBWSxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsWUFBWTtZQUN6QyxVQUFVLEVBQUU7Z0JBQ1YsUUFBUSxFQUFFLHFCQUFjLENBQUMsUUFBUTtnQkFDakMsVUFBVSxFQUFFLEtBQUssQ0FBQyxZQUFZO2dCQUM5QixTQUFTLEVBQUUsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsU0FBUztnQkFDMUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsUUFBUTthQUM3QjtTQUNGLENBQUMsQ0FBQTtRQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUN2QyxJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxZQUFZLENBQUE7UUFDdEMsSUFBSSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDaEIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3RDLENBQUM7SUFDSCxDQUFDOztBQTNCSCw0QkE0QkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDdXN0b21SZXNvdXJjZSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiXG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiXG5pbXBvcnQgeyBSZHNTcWxSZXNvdXJjZSB9IGZyb20gXCIuL2VudW1cIlxuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tIFwiLi9wcm92aWRlclwiXG5pbXBvcnQgeyBSb2xlIH0gZnJvbSBcIi4vcm9sZVwiXG5cbmludGVyZmFjZSBEYXRhYmFzZUF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogTmFtZSBvZiBkYXRhYmFzZSB0byBjcmVhdGUuXG4gICAqL1xuICByZWFkb25seSBkYXRhYmFzZU5hbWU6IHN0cmluZ1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBkYXRhYmFzZSBvd25lci5cbiAgICovXG4gIHJlYWRvbmx5IG93bmVyPzogUm9sZVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIERhdGFiYXNlUHJvcHMgZXh0ZW5kcyBEYXRhYmFzZUF0dHJpYnV0ZXMge1xuICAvKipcbiAgICogUHJvdmlkZXIuXG4gICAqL1xuICByZWFkb25seSBwcm92aWRlcjogUHJvdmlkZXJcbn1cblxuZXhwb3J0IGludGVyZmFjZSBJRGF0YWJhc2Uge1xuICByZWFkb25seSBkYXRhYmFzZU5hbWU6IHN0cmluZ1xufVxuXG5jbGFzcyBJbXBvcnRlZERhdGFiYXNlIGV4dGVuZHMgQ29uc3RydWN0IGltcGxlbWVudHMgSURhdGFiYXNlIHtcbiAgcHVibGljIHJlYWRvbmx5IGRhdGFiYXNlTmFtZTogc3RyaW5nXG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IERhdGFiYXNlQXR0cmlidXRlcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcbiAgICB0aGlzLmRhdGFiYXNlTmFtZSA9IHByb3BzLmRhdGFiYXNlTmFtZVxuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBEYXRhYmFzZSBleHRlbmRzIEN1c3RvbVJlc291cmNlIGltcGxlbWVudHMgSURhdGFiYXNlIHtcbiAgLyoqXG4gICAqIFJldHVybiBhIERhdGFiYXNlIGJhc2VkIHVwb24gbmFtZSBvbmx5LiBVc2UgZm9yIGltcG9ydGluZyBleGlzdGluZyBkYXRhYmFzZXMuXG4gICAqL1xuICBzdGF0aWMgZnJvbURhdGFiYXNlTmFtZShzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBkYXRhYmFzZU5hbWU6IHN0cmluZyk6IElEYXRhYmFzZSB7XG4gICAgcmV0dXJuIG5ldyBJbXBvcnRlZERhdGFiYXNlKHNjb3BlLCBpZCwge1xuICAgICAgZGF0YWJhc2VOYW1lOiBkYXRhYmFzZU5hbWUsXG4gICAgfSlcbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSBkYXRhYmFzZU5hbWU6IHN0cmluZ1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBEYXRhYmFzZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBzZXJ2aWNlVG9rZW46IHByb3BzLnByb3ZpZGVyLnNlcnZpY2VUb2tlbixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgUmVzb3VyY2U6IFJkc1NxbFJlc291cmNlLkRBVEFCQVNFLFxuICAgICAgICBSZXNvdXJjZUlkOiBwcm9wcy5kYXRhYmFzZU5hbWUsXG4gICAgICAgIFNlY3JldEFybjogcHJvcHMucHJvdmlkZXIuc2VjcmV0LnNlY3JldEFybixcbiAgICAgICAgT3duZXI6IHByb3BzLm93bmVyPy5yb2xlTmFtZSxcbiAgICAgIH0sXG4gICAgfSlcbiAgICB0aGlzLm5vZGUuYWRkRGVwZW5kZW5jeShwcm9wcy5wcm92aWRlcilcbiAgICB0aGlzLmRhdGFiYXNlTmFtZSA9IHByb3BzLmRhdGFiYXNlTmFtZVxuICAgIGlmIChwcm9wcy5vd25lcikge1xuICAgICAgdGhpcy5ub2RlLmFkZERlcGVuZGVuY3kocHJvcHMub3duZXIpXG4gICAgfVxuICB9XG59XG4iXX0=