@prismatic-io/components-aws-redshift 0.0.0-stage → 0.1.0
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/README.md +64 -2
- package/dist/icon.png +0 -0
- package/dist/index.js +599 -0
- package/npm-dist/icon.png +0 -0
- package/npm-dist/index.cjs +1139 -0
- package/npm-dist/index.d.cts +422 -0
- package/package.json +56 -4
|
@@ -0,0 +1,1139 @@
|
|
|
1
|
+
let _prismatic_io_spectral = require("@prismatic-io/spectral");
|
|
2
|
+
let _aws_sdk_client_sts = require("@aws-sdk/client-sts");
|
|
3
|
+
let _aws_sdk_client_redshift_data = require("@aws-sdk/client-redshift-data");
|
|
4
|
+
let _prismatic_io_spectral_http = require("@prismatic-io/spectral/http");
|
|
5
|
+
let aws4 = require("aws4");
|
|
6
|
+
//#region ../../packages/aws-utils/dist/connection/assumeRole.js
|
|
7
|
+
var __awaiter$3 = function(thisArg, _arguments, P, generator) {
|
|
8
|
+
function adopt(value) {
|
|
9
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
10
|
+
resolve(value);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
14
|
+
function fulfilled(value) {
|
|
15
|
+
try {
|
|
16
|
+
step(generator.next(value));
|
|
17
|
+
} catch (e) {
|
|
18
|
+
reject(e);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function rejected(value) {
|
|
22
|
+
try {
|
|
23
|
+
step(generator["throw"](value));
|
|
24
|
+
} catch (e) {
|
|
25
|
+
reject(e);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function step(result) {
|
|
29
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
30
|
+
}
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
const assumeRole = (region, accessKeyId, secretAccessKey, roleArn, externalId) => __awaiter$3(void 0, void 0, void 0, function* () {
|
|
35
|
+
const { Credentials: { AccessKeyId, SecretAccessKey, SessionToken } } = yield new _aws_sdk_client_sts.STSClient(Object.assign(Object.assign({}, region.length > 0 && { region }), { credentials: {
|
|
36
|
+
accessKeyId,
|
|
37
|
+
secretAccessKey
|
|
38
|
+
} })).send(new _aws_sdk_client_sts.AssumeRoleCommand({
|
|
39
|
+
RoleArn: _prismatic_io_spectral.util.types.toString(roleArn),
|
|
40
|
+
RoleSessionName: "integration-session",
|
|
41
|
+
ExternalId: externalId
|
|
42
|
+
}));
|
|
43
|
+
return {
|
|
44
|
+
accessKeyId: AccessKeyId,
|
|
45
|
+
secretAccessKey: SecretAccessKey,
|
|
46
|
+
sessionToken: SessionToken
|
|
47
|
+
};
|
|
48
|
+
});
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region ../../packages/aws-utils/dist/connection/assumeRoleConnection.js
|
|
51
|
+
const assumeRoleConnection = {
|
|
52
|
+
key: "awsAssumeRole",
|
|
53
|
+
display: {
|
|
54
|
+
label: "AWS Role ARN",
|
|
55
|
+
description: "Connect to AWS using an assumed role"
|
|
56
|
+
},
|
|
57
|
+
inputs: {
|
|
58
|
+
roleARN: {
|
|
59
|
+
label: "Role ARN",
|
|
60
|
+
placeholder: "arn:aws:iam::OtherAccount-ID:role/assumed-role-name",
|
|
61
|
+
type: "string",
|
|
62
|
+
required: true,
|
|
63
|
+
shown: true,
|
|
64
|
+
comments: "An AWS IAM Role ARN",
|
|
65
|
+
example: "arn:aws:iam::OtherAccount-ID:role/assumed-role-name"
|
|
66
|
+
},
|
|
67
|
+
accessKeyId: {
|
|
68
|
+
label: "Access Key ID",
|
|
69
|
+
placeholder: "Access Key ID",
|
|
70
|
+
type: "string",
|
|
71
|
+
required: true,
|
|
72
|
+
shown: true,
|
|
73
|
+
comments: "An AWS IAM Access Key ID",
|
|
74
|
+
example: "AKIAIOSFODNN7EXAMPLE"
|
|
75
|
+
},
|
|
76
|
+
secretAccessKey: {
|
|
77
|
+
label: "Secret Access Key",
|
|
78
|
+
placeholder: "Secret Access Key",
|
|
79
|
+
type: "password",
|
|
80
|
+
required: true,
|
|
81
|
+
shown: true,
|
|
82
|
+
comments: "An AWS IAM Secret Access Key",
|
|
83
|
+
example: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
|
84
|
+
},
|
|
85
|
+
externalId: {
|
|
86
|
+
label: "External ID",
|
|
87
|
+
placeholder: "shared-common-secret",
|
|
88
|
+
type: "string",
|
|
89
|
+
required: false,
|
|
90
|
+
shown: true,
|
|
91
|
+
comments: "Provides enhanced security measures to the connection. Optional, but recommended. Please check [AWS docs](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html#id_roles_third-party_external-id) for more information.",
|
|
92
|
+
example: "shared-common-secret"
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region ../../packages/aws-utils/dist/helpers/misc.js
|
|
98
|
+
const toTrimmedString = (value) => _prismatic_io_spectral.util.types.toString(value).trim();
|
|
99
|
+
const toOptionalString$1 = (value) => value ? _prismatic_io_spectral.util.types.toString(value) : void 0;
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region ../../packages/aws-utils/dist/helpers/getCredentials.js
|
|
102
|
+
const getCredentials = (connection) => {
|
|
103
|
+
return {
|
|
104
|
+
accessKeyId: toTrimmedString(connection.fields.accessKeyId),
|
|
105
|
+
secretAccessKey: toTrimmedString(connection.fields.secretAccessKey)
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region ../../packages/aws-utils/dist/helpers/validateConnection.js
|
|
110
|
+
const validateConnection$1 = (connection, validConnectionKeys) => {
|
|
111
|
+
if (![assumeRoleConnection.key, ...validConnectionKeys].includes(connection.key)) throw new _prismatic_io_spectral.ConnectionError(connection, `Unsupported connection method ${connection.key}.`);
|
|
112
|
+
};
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region ../../packages/aws-utils/dist/client/getClientParams.js
|
|
115
|
+
var __awaiter$2 = function(thisArg, _arguments, P, generator) {
|
|
116
|
+
function adopt(value) {
|
|
117
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
118
|
+
resolve(value);
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
122
|
+
function fulfilled(value) {
|
|
123
|
+
try {
|
|
124
|
+
step(generator.next(value));
|
|
125
|
+
} catch (e) {
|
|
126
|
+
reject(e);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function rejected(value) {
|
|
130
|
+
try {
|
|
131
|
+
step(generator["throw"](value));
|
|
132
|
+
} catch (e) {
|
|
133
|
+
reject(e);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function step(result) {
|
|
137
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
138
|
+
}
|
|
139
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
const getClientParams = (_a) => __awaiter$2(void 0, [_a], void 0, function* ({ awsRegion, awsConnection, validConnectionKeys, dynamicAccessKeyId, dynamicSecretAccessKey, dynamicSessionToken }) {
|
|
143
|
+
var _b;
|
|
144
|
+
let shouldAssumeRole = false;
|
|
145
|
+
if (awsConnection) {
|
|
146
|
+
validateConnection$1(awsConnection, validConnectionKeys);
|
|
147
|
+
if (dynamicAccessKeyId || dynamicSecretAccessKey) throw new Error("Please specify either a connection or dynamic access key and secret inputs.");
|
|
148
|
+
shouldAssumeRole = awsConnection.key === assumeRoleConnection.key;
|
|
149
|
+
}
|
|
150
|
+
if (!awsConnection && (!dynamicAccessKeyId || !dynamicSecretAccessKey)) throw new Error("You must specify either a connection input or dynamic access key and secret inputs.");
|
|
151
|
+
const { accessKeyId, secretAccessKey } = awsConnection ? getCredentials(awsConnection) : {
|
|
152
|
+
accessKeyId: dynamicAccessKeyId,
|
|
153
|
+
secretAccessKey: dynamicSecretAccessKey
|
|
154
|
+
};
|
|
155
|
+
const credentials = shouldAssumeRole ? yield assumeRole(awsRegion, accessKeyId, secretAccessKey, toTrimmedString(awsConnection.fields.roleARN), toOptionalString$1((_b = awsConnection.fields) === null || _b === void 0 ? void 0 : _b.externalId)) : {
|
|
156
|
+
accessKeyId,
|
|
157
|
+
secretAccessKey,
|
|
158
|
+
sessionToken: dynamicSessionToken
|
|
159
|
+
};
|
|
160
|
+
return {
|
|
161
|
+
region: awsRegion.length > 0 ? awsRegion : void 0,
|
|
162
|
+
credentials
|
|
163
|
+
};
|
|
164
|
+
});
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region ../../packages/aws-utils/dist/data/awsRegions.js
|
|
167
|
+
const awsRegions = [
|
|
168
|
+
"af-south-1",
|
|
169
|
+
"ap-east-1",
|
|
170
|
+
"ap-east-2",
|
|
171
|
+
"ap-northeast-1",
|
|
172
|
+
"ap-northeast-2",
|
|
173
|
+
"ap-northeast-3",
|
|
174
|
+
"ap-south-1",
|
|
175
|
+
"ap-south-2",
|
|
176
|
+
"ap-southeast-1",
|
|
177
|
+
"ap-southeast-2",
|
|
178
|
+
"ap-southeast-3",
|
|
179
|
+
"ap-southeast-4",
|
|
180
|
+
"ap-southeast-5",
|
|
181
|
+
"ap-southeast-6",
|
|
182
|
+
"ap-southeast-7",
|
|
183
|
+
"ca-central-1",
|
|
184
|
+
"ca-west-1",
|
|
185
|
+
"eu-central-1",
|
|
186
|
+
"eu-central-2",
|
|
187
|
+
"eu-north-1",
|
|
188
|
+
"eu-south-1",
|
|
189
|
+
"eu-south-2",
|
|
190
|
+
"eu-west-1",
|
|
191
|
+
"eu-west-2",
|
|
192
|
+
"eu-west-3",
|
|
193
|
+
"il-central-1",
|
|
194
|
+
"me-central-1",
|
|
195
|
+
"me-south-1",
|
|
196
|
+
"mx-central-1",
|
|
197
|
+
"sa-east-1",
|
|
198
|
+
"us-east-1",
|
|
199
|
+
"us-east-2",
|
|
200
|
+
"us-gov-east-1",
|
|
201
|
+
"us-gov-west-1",
|
|
202
|
+
"us-west-1",
|
|
203
|
+
"us-west-2"
|
|
204
|
+
];
|
|
205
|
+
//#endregion
|
|
206
|
+
//#region ../../packages/aws-utils/dist/dataSources/selectRegion.js
|
|
207
|
+
var __awaiter$1 = function(thisArg, _arguments, P, generator) {
|
|
208
|
+
function adopt(value) {
|
|
209
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
210
|
+
resolve(value);
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
214
|
+
function fulfilled(value) {
|
|
215
|
+
try {
|
|
216
|
+
step(generator.next(value));
|
|
217
|
+
} catch (e) {
|
|
218
|
+
reject(e);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function rejected(value) {
|
|
222
|
+
try {
|
|
223
|
+
step(generator["throw"](value));
|
|
224
|
+
} catch (e) {
|
|
225
|
+
reject(e);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function step(result) {
|
|
229
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
230
|
+
}
|
|
231
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
232
|
+
});
|
|
233
|
+
};
|
|
234
|
+
const selectRegion = (0, _prismatic_io_spectral.dataSource)({
|
|
235
|
+
display: {
|
|
236
|
+
label: "Select AWS Region",
|
|
237
|
+
description: "Select an AWS region"
|
|
238
|
+
},
|
|
239
|
+
dataSourceType: "picklist",
|
|
240
|
+
perform: () => __awaiter$1(void 0, void 0, void 0, function* () {
|
|
241
|
+
return Promise.resolve({ result: awsRegions.map((region) => ({
|
|
242
|
+
label: region,
|
|
243
|
+
key: region
|
|
244
|
+
})) });
|
|
245
|
+
}),
|
|
246
|
+
inputs: {}
|
|
247
|
+
});
|
|
248
|
+
//#endregion
|
|
249
|
+
//#region ../../packages/aws-utils/dist/helpers/pagination.js
|
|
250
|
+
var __awaiter = function(thisArg, _arguments, P, generator) {
|
|
251
|
+
function adopt(value) {
|
|
252
|
+
return value instanceof P ? value : new P(function(resolve) {
|
|
253
|
+
resolve(value);
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
return new (P || (P = Promise))(function(resolve, reject) {
|
|
257
|
+
function fulfilled(value) {
|
|
258
|
+
try {
|
|
259
|
+
step(generator.next(value));
|
|
260
|
+
} catch (e) {
|
|
261
|
+
reject(e);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function rejected(value) {
|
|
265
|
+
try {
|
|
266
|
+
step(generator["throw"](value));
|
|
267
|
+
} catch (e) {
|
|
268
|
+
reject(e);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
function step(result) {
|
|
272
|
+
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
|
|
273
|
+
}
|
|
274
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
275
|
+
});
|
|
276
|
+
};
|
|
277
|
+
const paginateAwsResults = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
278
|
+
const { createCommand, client, itemsKey } = options;
|
|
279
|
+
const allItems = [];
|
|
280
|
+
let nextToken;
|
|
281
|
+
let lastResponse;
|
|
282
|
+
do {
|
|
283
|
+
const command = createCommand(nextToken);
|
|
284
|
+
const response = yield client.send(command);
|
|
285
|
+
lastResponse = response;
|
|
286
|
+
const record = response;
|
|
287
|
+
const items = record[itemsKey];
|
|
288
|
+
allItems.push(...Array.isArray(items) ? items : []);
|
|
289
|
+
nextToken = record.NextToken;
|
|
290
|
+
} while (nextToken);
|
|
291
|
+
return {
|
|
292
|
+
allItems,
|
|
293
|
+
lastResponse
|
|
294
|
+
};
|
|
295
|
+
});
|
|
296
|
+
//#endregion
|
|
297
|
+
//#region ../../packages/aws-utils/dist/inputs/awsRegion.js
|
|
298
|
+
const awsRegion$1 = (0, _prismatic_io_spectral.input)({
|
|
299
|
+
label: "AWS Region",
|
|
300
|
+
placeholder: "AWS Region",
|
|
301
|
+
type: "string",
|
|
302
|
+
required: false,
|
|
303
|
+
comments: "AWS provides services in multiple regions, like us-west-2 or eu-west-1.",
|
|
304
|
+
example: "us-east-1",
|
|
305
|
+
dataSource: "selectRegion",
|
|
306
|
+
clean: _prismatic_io_spectral.util.types.toString
|
|
307
|
+
});
|
|
308
|
+
(0, _prismatic_io_spectral.input)({
|
|
309
|
+
label: "Connection",
|
|
310
|
+
type: "connection",
|
|
311
|
+
required: false
|
|
312
|
+
});
|
|
313
|
+
(0, _prismatic_io_spectral.input)({
|
|
314
|
+
label: "Dynamic Access Key ID",
|
|
315
|
+
type: "string",
|
|
316
|
+
required: false,
|
|
317
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
318
|
+
comments: "Use this input to authenticate with AWS if you are using a dynamically-generated access key. Otherwise, use the connection to enter a static access key ID."
|
|
319
|
+
});
|
|
320
|
+
(0, _prismatic_io_spectral.input)({
|
|
321
|
+
label: "Dynamic Secret Access Key",
|
|
322
|
+
type: "password",
|
|
323
|
+
required: false,
|
|
324
|
+
clean: _prismatic_io_spectral.util.types.toString,
|
|
325
|
+
comments: "Use this input to authenticate with AWS if you are using a dynamically-generated secret access key. Otherwise, use the connection to enter a static secret access key."
|
|
326
|
+
});
|
|
327
|
+
(0, _prismatic_io_spectral.input)({
|
|
328
|
+
label: "Dynamic Session Token",
|
|
329
|
+
type: "password",
|
|
330
|
+
required: false,
|
|
331
|
+
clean: (value) => _prismatic_io_spectral.util.types.toString(value) || void 0,
|
|
332
|
+
comments: "Use this input to authenticate with AWS if you are using a OPTIONAL dynamically-generated session token."
|
|
333
|
+
});
|
|
334
|
+
//#endregion
|
|
335
|
+
//#region src/connections/index.ts
|
|
336
|
+
const accessKeySecretPair = (0, _prismatic_io_spectral.connection)({
|
|
337
|
+
key: "awsAccessKeySecret",
|
|
338
|
+
display: {
|
|
339
|
+
label: "Access Key and Secret",
|
|
340
|
+
description: "Authenticate requests to AWS using an Access Key and Secret Key."
|
|
341
|
+
},
|
|
342
|
+
inputs: {
|
|
343
|
+
accessKeyId: {
|
|
344
|
+
label: "Access Key ID",
|
|
345
|
+
type: "string",
|
|
346
|
+
required: true,
|
|
347
|
+
comments: "The AWS Access Key ID used to authenticate requests to the Redshift Data API.",
|
|
348
|
+
example: "AKIAIOSFODNN7EXAMPLE",
|
|
349
|
+
placeholder: "Enter the AWS Access Key ID"
|
|
350
|
+
},
|
|
351
|
+
secretAccessKey: {
|
|
352
|
+
label: "Secret Access Key",
|
|
353
|
+
type: "password",
|
|
354
|
+
required: true,
|
|
355
|
+
comments: "The AWS Secret Access Key paired with the Access Key ID for request signing.",
|
|
356
|
+
example: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
var connections_default = [accessKeySecretPair, assumeRoleConnection];
|
|
361
|
+
//#endregion
|
|
362
|
+
//#region src/util/index.ts
|
|
363
|
+
const toOptionalString = (value) => value ? _prismatic_io_spectral.util.types.toString(value) : void 0;
|
|
364
|
+
const toOptionalResultFormatString = (value) => value ? _prismatic_io_spectral.util.types.toString(value) : void 0;
|
|
365
|
+
const cleanSqlParameters = (sqlParameters) => Array.isArray(sqlParameters) && sqlParameters.length > 0 ? sqlParameters.map(({ name, value }) => ({
|
|
366
|
+
name,
|
|
367
|
+
value
|
|
368
|
+
})) : void 0;
|
|
369
|
+
const toOptionalNumber = (value) => value ? _prismatic_io_spectral.util.types.toNumber(value) : void 0;
|
|
370
|
+
const connectionKeys = [accessKeySecretPair.key, assumeRoleConnection.key];
|
|
371
|
+
const validateConnection = (connection) => {
|
|
372
|
+
if (!connectionKeys.includes(connection.key)) throw new _prismatic_io_spectral.ConnectionError(connection, `Unsupported connection method ${connection.key}. Supported methods: ${connectionKeys.join(", ")}`);
|
|
373
|
+
};
|
|
374
|
+
const getAllStatements = async ({ client, databaseName, workgroupName, clusterIdentifier, status, statementName }) => {
|
|
375
|
+
const { allItems, lastResponse } = await paginateAwsResults({
|
|
376
|
+
client,
|
|
377
|
+
createCommand: (token) => new _aws_sdk_client_redshift_data.ListStatementsCommand({
|
|
378
|
+
Database: databaseName,
|
|
379
|
+
WorkgroupName: workgroupName,
|
|
380
|
+
ClusterIdentifier: clusterIdentifier,
|
|
381
|
+
Status: status,
|
|
382
|
+
StatementName: statementName,
|
|
383
|
+
MaxResults: 100,
|
|
384
|
+
NextToken: token
|
|
385
|
+
}),
|
|
386
|
+
itemsKey: "Statements"
|
|
387
|
+
});
|
|
388
|
+
return {
|
|
389
|
+
allStatements: allItems,
|
|
390
|
+
lastResponse
|
|
391
|
+
};
|
|
392
|
+
};
|
|
393
|
+
//#endregion
|
|
394
|
+
//#region src/client.ts
|
|
395
|
+
const createRedshiftClient = async (connection, region, debug) => {
|
|
396
|
+
validateConnection(connection);
|
|
397
|
+
try {
|
|
398
|
+
const { region: awsRegion, credentials } = await getClientParams({
|
|
399
|
+
awsConnection: connection,
|
|
400
|
+
awsRegion: region,
|
|
401
|
+
validConnectionKeys: connectionKeys,
|
|
402
|
+
dynamicAccessKeyId: "",
|
|
403
|
+
dynamicSecretAccessKey: "",
|
|
404
|
+
dynamicSessionToken: void 0
|
|
405
|
+
});
|
|
406
|
+
const client = new _aws_sdk_client_redshift_data.RedshiftDataClient({
|
|
407
|
+
region: awsRegion,
|
|
408
|
+
credentials
|
|
409
|
+
});
|
|
410
|
+
if (debug) client.middlewareStack.add((next, context) => async (args) => {
|
|
411
|
+
console.log("Request:", {
|
|
412
|
+
input: args.input,
|
|
413
|
+
commandName: context.commandName
|
|
414
|
+
});
|
|
415
|
+
try {
|
|
416
|
+
const result = await next(args);
|
|
417
|
+
console.log("Response:", result.output);
|
|
418
|
+
return result;
|
|
419
|
+
} catch (error) {
|
|
420
|
+
console.error("Error:", error);
|
|
421
|
+
throw error;
|
|
422
|
+
}
|
|
423
|
+
}, {
|
|
424
|
+
step: "initialize",
|
|
425
|
+
name: "logRequestResponseMiddleware"
|
|
426
|
+
});
|
|
427
|
+
return client;
|
|
428
|
+
} catch (error) {
|
|
429
|
+
throw new _prismatic_io_spectral.ConnectionError(connection, `Failed to create AWS Redshift Data API client: ${error.message}`);
|
|
430
|
+
}
|
|
431
|
+
};
|
|
432
|
+
const getRedshiftDataApiClient = async (connection, region, debug) => {
|
|
433
|
+
validateConnection(connection);
|
|
434
|
+
const { region: awsRegion, credentials } = await getClientParams({
|
|
435
|
+
awsConnection: connection,
|
|
436
|
+
awsRegion: region,
|
|
437
|
+
validConnectionKeys: connectionKeys,
|
|
438
|
+
dynamicAccessKeyId: "",
|
|
439
|
+
dynamicSecretAccessKey: "",
|
|
440
|
+
dynamicSessionToken: void 0
|
|
441
|
+
});
|
|
442
|
+
const host = `redshift-data.${awsRegion}.amazonaws.com`;
|
|
443
|
+
return {
|
|
444
|
+
client: (0, _prismatic_io_spectral_http.createClient)({
|
|
445
|
+
baseUrl: `https://${host}`,
|
|
446
|
+
debug
|
|
447
|
+
}),
|
|
448
|
+
credentials,
|
|
449
|
+
host
|
|
450
|
+
};
|
|
451
|
+
};
|
|
452
|
+
//#endregion
|
|
453
|
+
//#region src/inputs/common.ts
|
|
454
|
+
const awsRegion = (0, _prismatic_io_spectral.input)({
|
|
455
|
+
...awsRegion$1,
|
|
456
|
+
required: true
|
|
457
|
+
});
|
|
458
|
+
const awsConnection = (0, _prismatic_io_spectral.input)({
|
|
459
|
+
label: "AWS Connection",
|
|
460
|
+
type: "connection",
|
|
461
|
+
required: true,
|
|
462
|
+
comments: "Select the AWS connection to use for Redshift Data API access."
|
|
463
|
+
});
|
|
464
|
+
const databaseName = (0, _prismatic_io_spectral.input)({
|
|
465
|
+
label: "Database Name",
|
|
466
|
+
type: "string",
|
|
467
|
+
required: true,
|
|
468
|
+
comments: "The name of the database to connect to. This parameter is required when authenticating using either Secrets Manager or temporary credentials.",
|
|
469
|
+
example: "analytics",
|
|
470
|
+
placeholder: "Enter the database name",
|
|
471
|
+
clean: _prismatic_io_spectral.util.types.toString
|
|
472
|
+
});
|
|
473
|
+
const clusterIdentifier = (0, _prismatic_io_spectral.input)({
|
|
474
|
+
label: "Cluster Identifier",
|
|
475
|
+
type: "string",
|
|
476
|
+
required: false,
|
|
477
|
+
comments: "The identifier of the Redshift cluster. Required for cluster connections using either Secrets Manager or temporary credentials.",
|
|
478
|
+
example: "my-redshift-cluster",
|
|
479
|
+
placeholder: "Enter the cluster identifier",
|
|
480
|
+
clean: toOptionalString
|
|
481
|
+
});
|
|
482
|
+
const workgroupName = (0, _prismatic_io_spectral.input)({
|
|
483
|
+
label: "Workgroup Name",
|
|
484
|
+
type: "string",
|
|
485
|
+
required: false,
|
|
486
|
+
comments: "The name of the Redshift serverless workgroup. This parameter is required when connecting to a serverless workgroup and authenticating using either Secrets Manager or temporary credentials.",
|
|
487
|
+
example: "my-workgroup",
|
|
488
|
+
placeholder: "Enter the workgroup name",
|
|
489
|
+
clean: toOptionalString
|
|
490
|
+
});
|
|
491
|
+
const statementId = (0, _prismatic_io_spectral.input)({
|
|
492
|
+
label: "Statement ID",
|
|
493
|
+
type: "string",
|
|
494
|
+
required: true,
|
|
495
|
+
comments: "The unique identifier of the executed SQL statement returned by the Redshift Data API.",
|
|
496
|
+
example: "12345678-1234-1234-1234-123456789012",
|
|
497
|
+
placeholder: "Enter the statement ID",
|
|
498
|
+
clean: _prismatic_io_spectral.util.types.toString
|
|
499
|
+
});
|
|
500
|
+
const fetchAll = (0, _prismatic_io_spectral.input)({
|
|
501
|
+
label: "Fetch All",
|
|
502
|
+
type: "boolean",
|
|
503
|
+
comments: "When enabled, automatically fetches all pages of results. Next Token and Max Results inputs are ignored when this is enabled.",
|
|
504
|
+
required: false,
|
|
505
|
+
default: "false",
|
|
506
|
+
clean: _prismatic_io_spectral.util.types.toBool
|
|
507
|
+
});
|
|
508
|
+
const statementName = (0, _prismatic_io_spectral.input)({
|
|
509
|
+
label: "Statement Name",
|
|
510
|
+
type: "string",
|
|
511
|
+
required: false,
|
|
512
|
+
comments: "A descriptive label assigned to the SQL statement to help identify it when listing or filtering statements later.",
|
|
513
|
+
example: "GetActiveUsers",
|
|
514
|
+
placeholder: "Enter the statement name",
|
|
515
|
+
clean: toOptionalString
|
|
516
|
+
});
|
|
517
|
+
//#endregion
|
|
518
|
+
//#region src/constants.ts
|
|
519
|
+
const RESULT_FORMAT_OPTIONS = [{
|
|
520
|
+
label: "JSON",
|
|
521
|
+
value: "JSON"
|
|
522
|
+
}, {
|
|
523
|
+
label: "CSV",
|
|
524
|
+
value: "CSV"
|
|
525
|
+
}];
|
|
526
|
+
const STATUS_OPTIONS = [
|
|
527
|
+
{
|
|
528
|
+
label: "ALL",
|
|
529
|
+
value: "ALL"
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
label: "ABORTED",
|
|
533
|
+
value: "ABORTED"
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
label: "FAILED",
|
|
537
|
+
value: "FAILED"
|
|
538
|
+
},
|
|
539
|
+
{
|
|
540
|
+
label: "FINISHED",
|
|
541
|
+
value: "FINISHED"
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
label: "PICKED",
|
|
545
|
+
value: "PICKED"
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
label: "STARTED",
|
|
549
|
+
value: "STARTED"
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
label: "SUBMITTED",
|
|
553
|
+
value: "SUBMITTED"
|
|
554
|
+
}
|
|
555
|
+
];
|
|
556
|
+
const RAW_REQUEST_ACTION_OPTIONS = [
|
|
557
|
+
{
|
|
558
|
+
label: "BatchExecuteStatement",
|
|
559
|
+
value: "RedshiftData.BatchExecuteStatement"
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
label: "CancelStatement",
|
|
563
|
+
value: "RedshiftData.CancelStatement"
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
label: "DescribeStatement",
|
|
567
|
+
value: "RedshiftData.DescribeStatement"
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
label: "DescribeTable",
|
|
571
|
+
value: "RedshiftData.DescribeTable"
|
|
572
|
+
},
|
|
573
|
+
{
|
|
574
|
+
label: "ExecuteStatement",
|
|
575
|
+
value: "RedshiftData.ExecuteStatement"
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
label: "GetStatementResult",
|
|
579
|
+
value: "RedshiftData.GetStatementResult"
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
label: "GetStatementResultV2",
|
|
583
|
+
value: "RedshiftData.GetStatementResultV2"
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
label: "ListDatabases",
|
|
587
|
+
value: "RedshiftData.ListDatabases"
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
label: "ListSchemas",
|
|
591
|
+
value: "RedshiftData.ListSchemas"
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
label: "ListStatements",
|
|
595
|
+
value: "RedshiftData.ListStatements"
|
|
596
|
+
},
|
|
597
|
+
{
|
|
598
|
+
label: "ListTables",
|
|
599
|
+
value: "RedshiftData.ListTables"
|
|
600
|
+
}
|
|
601
|
+
];
|
|
602
|
+
//#endregion
|
|
603
|
+
//#region src/inputs/statement.ts
|
|
604
|
+
const databaseUser = (0, _prismatic_io_spectral.input)({
|
|
605
|
+
label: "Database User",
|
|
606
|
+
type: "string",
|
|
607
|
+
required: false,
|
|
608
|
+
comments: "The database user name. This parameter is required when connecting to a cluster as a database user and authenticating using temporary credentials.",
|
|
609
|
+
example: "admin",
|
|
610
|
+
placeholder: "Enter the database user",
|
|
611
|
+
clean: toOptionalString
|
|
612
|
+
});
|
|
613
|
+
const secretArn = (0, _prismatic_io_spectral.input)({
|
|
614
|
+
label: "Secret ARN",
|
|
615
|
+
type: "string",
|
|
616
|
+
required: false,
|
|
617
|
+
comments: "The ARN of the AWS Secrets Manager secret containing database credentials. Required when authenticating using Secrets Manager.",
|
|
618
|
+
example: "arn:aws:secretsmanager:us-east-1:123456789012:secret:redshift-credentials",
|
|
619
|
+
placeholder: "Enter the secret ARN",
|
|
620
|
+
clean: toOptionalString
|
|
621
|
+
});
|
|
622
|
+
const sqlStatement = (0, _prismatic_io_spectral.input)({
|
|
623
|
+
label: "SQL Statement",
|
|
624
|
+
type: "code",
|
|
625
|
+
language: "sql",
|
|
626
|
+
required: true,
|
|
627
|
+
comments: "The SQL statement to run against the Redshift database. Supports DML (INSERT, UPDATE, DELETE), DDL (CREATE, DROP, ALTER), and query (SELECT) statements.",
|
|
628
|
+
example: "SELECT * FROM users WHERE status = :status",
|
|
629
|
+
placeholder: "SELECT * FROM users WHERE status = :status",
|
|
630
|
+
clean: _prismatic_io_spectral.util.types.toString
|
|
631
|
+
});
|
|
632
|
+
const sqlParameters = (0, _prismatic_io_spectral.input)({
|
|
633
|
+
label: "SQL Parameters",
|
|
634
|
+
type: "string",
|
|
635
|
+
collection: "keyvaluelist",
|
|
636
|
+
required: false,
|
|
637
|
+
comments: "Named parameters that are substituted into the SQL statement at runtime using the colon-prefixed placeholder syntax (e.g., :status).",
|
|
638
|
+
example: "status: active, limit: 100",
|
|
639
|
+
clean: cleanSqlParameters
|
|
640
|
+
});
|
|
641
|
+
const resultFormat = (0, _prismatic_io_spectral.input)({
|
|
642
|
+
label: "Result Format",
|
|
643
|
+
type: "string",
|
|
644
|
+
required: false,
|
|
645
|
+
default: "JSON",
|
|
646
|
+
comments: "The format for query results (JSON or CSV).",
|
|
647
|
+
example: "JSON",
|
|
648
|
+
placeholder: "Enter the result format",
|
|
649
|
+
model: RESULT_FORMAT_OPTIONS,
|
|
650
|
+
clean: toOptionalResultFormatString
|
|
651
|
+
});
|
|
652
|
+
const sessionId = (0, _prismatic_io_spectral.input)({
|
|
653
|
+
label: "Session ID",
|
|
654
|
+
type: "string",
|
|
655
|
+
required: false,
|
|
656
|
+
comments: "The ID of an existing session to reuse for statement execution, enabling multiple statements to share temporary tables and transaction state.",
|
|
657
|
+
example: "session-12345678",
|
|
658
|
+
placeholder: "Enter the session ID",
|
|
659
|
+
clean: toOptionalString
|
|
660
|
+
});
|
|
661
|
+
const sessionKeepAliveSeconds = (0, _prismatic_io_spectral.input)({
|
|
662
|
+
label: "Session Keep Alive (seconds)",
|
|
663
|
+
type: "string",
|
|
664
|
+
required: false,
|
|
665
|
+
comments: "Number of seconds to keep the session alive after query completion (max 24 hours).",
|
|
666
|
+
example: "3600",
|
|
667
|
+
placeholder: "Enter the keep alive duration in seconds",
|
|
668
|
+
clean: toOptionalNumber
|
|
669
|
+
});
|
|
670
|
+
const clientToken = (0, _prismatic_io_spectral.input)({
|
|
671
|
+
label: "Client Token",
|
|
672
|
+
type: "string",
|
|
673
|
+
required: false,
|
|
674
|
+
comments: "Unique identifier to ensure idempotency of the request.",
|
|
675
|
+
example: "client-token-123",
|
|
676
|
+
placeholder: "Enter the client token",
|
|
677
|
+
clean: toOptionalString
|
|
678
|
+
});
|
|
679
|
+
const getStatementResult$1 = (0, _prismatic_io_spectral.input)({
|
|
680
|
+
label: "Get Statement Result",
|
|
681
|
+
type: "boolean",
|
|
682
|
+
required: false,
|
|
683
|
+
comments: "When true, waits for the statement to finish executing and returns its result set. Only SELECT statements produce result rows. <strong>Note:</strong> long-running statements may cause a timeout.",
|
|
684
|
+
example: "true",
|
|
685
|
+
default: "true",
|
|
686
|
+
clean: _prismatic_io_spectral.util.types.toBool
|
|
687
|
+
});
|
|
688
|
+
const nextToken = (0, _prismatic_io_spectral.input)({
|
|
689
|
+
label: "Next Token",
|
|
690
|
+
type: "string",
|
|
691
|
+
required: false,
|
|
692
|
+
comments: "The pagination token returned from a previous list request, used to retrieve the next page of results.",
|
|
693
|
+
example: "AQICAHi2k9rFZ...",
|
|
694
|
+
placeholder: "Enter the next token",
|
|
695
|
+
clean: toOptionalString
|
|
696
|
+
});
|
|
697
|
+
const status = (0, _prismatic_io_spectral.input)({
|
|
698
|
+
label: "Status",
|
|
699
|
+
type: "string",
|
|
700
|
+
required: true,
|
|
701
|
+
comments: "Filters the returned statements to only those matching this execution status. Use ALL to retrieve statements in any state.",
|
|
702
|
+
example: "ALL",
|
|
703
|
+
model: STATUS_OPTIONS,
|
|
704
|
+
default: "ALL",
|
|
705
|
+
clean: (value) => _prismatic_io_spectral.util.types.toString(value)
|
|
706
|
+
});
|
|
707
|
+
const executeStatementInputs = {
|
|
708
|
+
awsConnection,
|
|
709
|
+
sqlStatement,
|
|
710
|
+
databaseName,
|
|
711
|
+
awsRegion,
|
|
712
|
+
workgroupName,
|
|
713
|
+
clusterIdentifier,
|
|
714
|
+
getStatementResult: getStatementResult$1,
|
|
715
|
+
databaseUser,
|
|
716
|
+
secretArn,
|
|
717
|
+
sqlParameters,
|
|
718
|
+
additionalFields: (0, _prismatic_io_spectral.structuredObjectInput)({
|
|
719
|
+
label: "Additional Fields",
|
|
720
|
+
required: false,
|
|
721
|
+
comments: "Additional optional fields: includes Statement Name, Result Format, Session Keep Alive (seconds), Client Token, and Session ID.",
|
|
722
|
+
inputs: {
|
|
723
|
+
statementName,
|
|
724
|
+
resultFormat,
|
|
725
|
+
sessionKeepAliveSeconds,
|
|
726
|
+
clientToken,
|
|
727
|
+
sessionId
|
|
728
|
+
}
|
|
729
|
+
})
|
|
730
|
+
};
|
|
731
|
+
const getStatementResultInputs = {
|
|
732
|
+
awsConnection,
|
|
733
|
+
statementId: {
|
|
734
|
+
...statementId,
|
|
735
|
+
comments: `${statementId.comments} <strong>Note:</strong> Only statements that return results are supported.`
|
|
736
|
+
},
|
|
737
|
+
awsRegion,
|
|
738
|
+
nextToken
|
|
739
|
+
};
|
|
740
|
+
const pagination = (0, _prismatic_io_spectral.structuredObjectInput)({
|
|
741
|
+
label: "Pagination",
|
|
742
|
+
required: false,
|
|
743
|
+
comments: "Page and page-size controls.",
|
|
744
|
+
inputs: {
|
|
745
|
+
nextToken,
|
|
746
|
+
maxResults: (0, _prismatic_io_spectral.input)({
|
|
747
|
+
label: "Max Results",
|
|
748
|
+
type: "string",
|
|
749
|
+
required: false,
|
|
750
|
+
comments: "The maximum number of SQL statements to return per page. Valid range: 0-100.",
|
|
751
|
+
example: "100",
|
|
752
|
+
placeholder: "100",
|
|
753
|
+
clean: toOptionalNumber
|
|
754
|
+
})
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
const listStatementsInputs = {
|
|
758
|
+
awsConnection,
|
|
759
|
+
awsRegion,
|
|
760
|
+
status,
|
|
761
|
+
filters: (0, _prismatic_io_spectral.structuredObjectInput)({
|
|
762
|
+
label: "Filters",
|
|
763
|
+
required: false,
|
|
764
|
+
comments: "Optional filters to narrow the returned statements by database, workgroup, cluster, and statement name.",
|
|
765
|
+
inputs: {
|
|
766
|
+
databaseName: {
|
|
767
|
+
...databaseName,
|
|
768
|
+
required: false,
|
|
769
|
+
comments: "The name of the database when listing statements run against a <code>ClusterIdentifier</code> or <code>WorkgroupName</code>."
|
|
770
|
+
},
|
|
771
|
+
workgroupName: {
|
|
772
|
+
...workgroupName,
|
|
773
|
+
required: false,
|
|
774
|
+
comments: "The serverless workgroup name or Amazon Resource Name (ARN). Only statements that ran on this workgroup are returned. When providing <code>WorkgroupName</code>, then <code>ClusterIdentifier</code> can't be specified."
|
|
775
|
+
},
|
|
776
|
+
clusterIdentifier: {
|
|
777
|
+
...clusterIdentifier,
|
|
778
|
+
required: false,
|
|
779
|
+
comments: "The cluster identifier. Only statements that ran on this cluster are returned. When providing <code>ClusterIdentifier</code>, then <code>WorkgroupName</code> can't be specified."
|
|
780
|
+
},
|
|
781
|
+
statementName: {
|
|
782
|
+
...statementName,
|
|
783
|
+
comments: "The name of the SQL statement specified as input to <code>BatchExecuteStatement</code> or <code>ExecuteStatement</code> to identify the query. Multiple statements can be matched by providing a prefix that matches the beginning of the statement name."
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}),
|
|
787
|
+
fetchAll,
|
|
788
|
+
pagination
|
|
789
|
+
};
|
|
790
|
+
const describeStatementInputs = {
|
|
791
|
+
awsConnection,
|
|
792
|
+
statementId,
|
|
793
|
+
awsRegion
|
|
794
|
+
};
|
|
795
|
+
const rawRequestInputs = {
|
|
796
|
+
awsConnection,
|
|
797
|
+
awsRegion,
|
|
798
|
+
body: (0, _prismatic_io_spectral.input)({
|
|
799
|
+
label: "Body",
|
|
800
|
+
type: "code",
|
|
801
|
+
language: "json",
|
|
802
|
+
required: true,
|
|
803
|
+
comments: "The JSON payload sent to the selected Redshift Data API operation. The required fields vary by action — refer to the AWS Redshift Data API documentation for the expected structure of each operation.",
|
|
804
|
+
example: JSON.stringify({
|
|
805
|
+
WorkgroupName: "my-workgroup",
|
|
806
|
+
Database: "analytics",
|
|
807
|
+
Sql: "SELECT * FROM users WHERE status = 'active'",
|
|
808
|
+
SecretArn: "arn:aws:secretsmanager:us-east-1:123456789012:secret:redshift-credentials"
|
|
809
|
+
}, null, 2),
|
|
810
|
+
clean: _prismatic_io_spectral.util.types.toString
|
|
811
|
+
}),
|
|
812
|
+
action: (0, _prismatic_io_spectral.input)({
|
|
813
|
+
label: "Action",
|
|
814
|
+
type: "string",
|
|
815
|
+
required: true,
|
|
816
|
+
comments: "The Redshift Data API operation to invoke. Determines which API method is called with the provided body.",
|
|
817
|
+
example: "RedshiftData.ExecuteStatement",
|
|
818
|
+
placeholder: "Enter the action",
|
|
819
|
+
model: RAW_REQUEST_ACTION_OPTIONS,
|
|
820
|
+
clean: _prismatic_io_spectral.util.types.toString
|
|
821
|
+
})
|
|
822
|
+
};
|
|
823
|
+
//#endregion
|
|
824
|
+
//#region src/actions/misc/index.ts
|
|
825
|
+
var misc_default = { rawRequest: (0, _prismatic_io_spectral.action)({
|
|
826
|
+
display: {
|
|
827
|
+
label: "Raw Request",
|
|
828
|
+
description: "Send raw HTTP request to Redshift Data API."
|
|
829
|
+
},
|
|
830
|
+
inputs: rawRequestInputs,
|
|
831
|
+
perform: async (context, { awsConnection, awsRegion, body, action }) => {
|
|
832
|
+
const { client, credentials, host } = await getRedshiftDataApiClient(awsConnection, awsRegion, context.debug.enabled);
|
|
833
|
+
const requestOpts = {
|
|
834
|
+
host,
|
|
835
|
+
path: "/",
|
|
836
|
+
service: "redshift-data",
|
|
837
|
+
region: awsRegion,
|
|
838
|
+
method: "POST",
|
|
839
|
+
headers: {
|
|
840
|
+
"Content-Type": "application/x-amz-json-1.1",
|
|
841
|
+
"X-Amz-Target": action
|
|
842
|
+
},
|
|
843
|
+
body
|
|
844
|
+
};
|
|
845
|
+
(0, aws4.sign)(requestOpts, credentials);
|
|
846
|
+
const { data } = await client.post("/", requestOpts.body, { headers: requestOpts.headers });
|
|
847
|
+
return { data };
|
|
848
|
+
}
|
|
849
|
+
}) };
|
|
850
|
+
//#endregion
|
|
851
|
+
//#region src/examplePayloads/getStatementResultExamplePayload.ts
|
|
852
|
+
const getStatementResultExamplePayload = { data: {
|
|
853
|
+
$metadata: {
|
|
854
|
+
httpStatusCode: 200,
|
|
855
|
+
requestId: "example-request-id-12345-67890-abcdef",
|
|
856
|
+
extendedRequestId: void 0,
|
|
857
|
+
cfId: void 0,
|
|
858
|
+
attempts: 1,
|
|
859
|
+
totalRetryDelay: 0
|
|
860
|
+
},
|
|
861
|
+
ColumnMetadata: [
|
|
862
|
+
{
|
|
863
|
+
isCaseSensitive: false,
|
|
864
|
+
isCurrency: false,
|
|
865
|
+
isSigned: true,
|
|
866
|
+
label: "id",
|
|
867
|
+
length: 0,
|
|
868
|
+
name: "id",
|
|
869
|
+
nullable: 1,
|
|
870
|
+
precision: 10,
|
|
871
|
+
scale: 0,
|
|
872
|
+
schemaName: "public",
|
|
873
|
+
tableName: "users",
|
|
874
|
+
typeName: "int4"
|
|
875
|
+
},
|
|
876
|
+
{
|
|
877
|
+
isCaseSensitive: true,
|
|
878
|
+
isCurrency: false,
|
|
879
|
+
isSigned: false,
|
|
880
|
+
label: "name",
|
|
881
|
+
length: 0,
|
|
882
|
+
name: "name",
|
|
883
|
+
nullable: 1,
|
|
884
|
+
precision: 50,
|
|
885
|
+
scale: 0,
|
|
886
|
+
schemaName: "public",
|
|
887
|
+
tableName: "users",
|
|
888
|
+
typeName: "varchar"
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
isCaseSensitive: true,
|
|
892
|
+
isCurrency: false,
|
|
893
|
+
isSigned: false,
|
|
894
|
+
label: "email",
|
|
895
|
+
length: 0,
|
|
896
|
+
name: "email",
|
|
897
|
+
nullable: 1,
|
|
898
|
+
precision: 100,
|
|
899
|
+
scale: 0,
|
|
900
|
+
schemaName: "public",
|
|
901
|
+
tableName: "users",
|
|
902
|
+
typeName: "varchar"
|
|
903
|
+
}
|
|
904
|
+
],
|
|
905
|
+
Records: [[
|
|
906
|
+
{ longValue: 1 },
|
|
907
|
+
{ stringValue: "Alice" },
|
|
908
|
+
{ stringValue: "alice@example.com" }
|
|
909
|
+
]],
|
|
910
|
+
TotalNumRows: 1
|
|
911
|
+
} };
|
|
912
|
+
//#endregion
|
|
913
|
+
//#region src/examplePayloads/executeStatementExamplePayload.ts
|
|
914
|
+
const executeStatementExamplePayload = { data: {
|
|
915
|
+
executeStatement: {
|
|
916
|
+
$metadata: {
|
|
917
|
+
httpStatusCode: 200,
|
|
918
|
+
requestId: "example-request-id-12345-67890-abcdef",
|
|
919
|
+
extendedRequestId: void 0,
|
|
920
|
+
cfId: void 0,
|
|
921
|
+
attempts: 1,
|
|
922
|
+
totalRetryDelay: 0
|
|
923
|
+
},
|
|
924
|
+
CreatedAt: /* @__PURE__ */ new Date("2025-01-15T10:30:00.000Z"),
|
|
925
|
+
Database: "example_database",
|
|
926
|
+
Id: "example-statement-id-12345-67890-abcdef",
|
|
927
|
+
SecretArn: "arn:aws:secretsmanager:us-east-1:123456789012:secret:redshift/example-secret-abc123",
|
|
928
|
+
WorkgroupName: "example_workgroup"
|
|
929
|
+
},
|
|
930
|
+
statementResults: getStatementResultExamplePayload.data
|
|
931
|
+
} };
|
|
932
|
+
//#endregion
|
|
933
|
+
//#region src/examplePayloads/listStatementsExamplePayload.ts
|
|
934
|
+
const listStatementsExamplePayload = { data: {
|
|
935
|
+
$metadata: {
|
|
936
|
+
httpStatusCode: 200,
|
|
937
|
+
requestId: "example-list-request-id-12345-67890-abcdef",
|
|
938
|
+
extendedRequestId: void 0,
|
|
939
|
+
cfId: void 0,
|
|
940
|
+
attempts: 1,
|
|
941
|
+
totalRetryDelay: 0
|
|
942
|
+
},
|
|
943
|
+
Statements: [{
|
|
944
|
+
CreatedAt: /* @__PURE__ */ new Date("2025-01-15T10:30:00.000Z"),
|
|
945
|
+
Id: "example-statement-id-12345-67890-abcdef",
|
|
946
|
+
QueryString: "CREATE TABLE users (\n id INT,\n name VARCHAR(50),\n email VARCHAR(100)\n);\n",
|
|
947
|
+
ResultFormat: "JSON",
|
|
948
|
+
SecretArn: "arn:aws:secretsmanager:us-east-1:123456789012:secret:redshift/example-secret-abc123",
|
|
949
|
+
StatementName: "ExampleStatement",
|
|
950
|
+
Status: "PICKED",
|
|
951
|
+
UpdatedAt: /* @__PURE__ */ new Date("2025-01-15T10:31:00.000Z")
|
|
952
|
+
}]
|
|
953
|
+
} };
|
|
954
|
+
//#endregion
|
|
955
|
+
//#region src/examplePayloads/describeStatementExamplePayload.ts
|
|
956
|
+
const describeStatementExamplePayload = { data: {
|
|
957
|
+
$metadata: {
|
|
958
|
+
httpStatusCode: 200,
|
|
959
|
+
requestId: "example-request-id-12345-67890-abcdef",
|
|
960
|
+
extendedRequestId: void 0,
|
|
961
|
+
cfId: void 0,
|
|
962
|
+
attempts: 1,
|
|
963
|
+
totalRetryDelay: 0
|
|
964
|
+
},
|
|
965
|
+
CreatedAt: /* @__PURE__ */ new Date("2025-01-15T10:30:00.000Z"),
|
|
966
|
+
Database: "example_database",
|
|
967
|
+
Duration: 257716773,
|
|
968
|
+
HasResultSet: false,
|
|
969
|
+
Id: "example-statement-id-12345-67890-abcdef",
|
|
970
|
+
QueryString: "INSERT INTO example_table (id, name, email)\nVALUES (1, 'Example User', 'user@example.com');\n",
|
|
971
|
+
RedshiftPid: 123456789,
|
|
972
|
+
RedshiftQueryId: 987654,
|
|
973
|
+
ResultFormat: "JSON",
|
|
974
|
+
ResultRows: 1,
|
|
975
|
+
ResultSize: 0,
|
|
976
|
+
SecretArn: "arn:aws:secretsmanager:us-east-1:123456789012:secret:redshift/example-secret-name",
|
|
977
|
+
Status: "FINISHED",
|
|
978
|
+
UpdatedAt: /* @__PURE__ */ new Date("2025-01-15T10:31:00.000Z"),
|
|
979
|
+
WorkgroupName: "example-workgroup"
|
|
980
|
+
} };
|
|
981
|
+
//#endregion
|
|
982
|
+
//#region src/actions/statements/index.ts
|
|
983
|
+
var statements_default = {
|
|
984
|
+
describeStatement: (0, _prismatic_io_spectral.action)({
|
|
985
|
+
display: {
|
|
986
|
+
label: "Describe Statement",
|
|
987
|
+
description: "Get detailed information about a specific SQL statement in Redshift."
|
|
988
|
+
},
|
|
989
|
+
inputs: describeStatementInputs,
|
|
990
|
+
perform: async (context, { awsConnection, awsRegion, statementId }) => {
|
|
991
|
+
const client = await createRedshiftClient(awsConnection, awsRegion, context.debug.enabled);
|
|
992
|
+
const command = new _aws_sdk_client_redshift_data.DescribeStatementCommand({ Id: statementId });
|
|
993
|
+
return { data: await client.send(command) };
|
|
994
|
+
},
|
|
995
|
+
examplePayload: describeStatementExamplePayload
|
|
996
|
+
}),
|
|
997
|
+
executeStatement: (0, _prismatic_io_spectral.action)({
|
|
998
|
+
display: {
|
|
999
|
+
label: "Execute SQL Statement",
|
|
1000
|
+
description: "Execute a SQL statement in Redshift."
|
|
1001
|
+
},
|
|
1002
|
+
inputs: executeStatementInputs,
|
|
1003
|
+
perform: async (context, { awsConnection, sqlStatement, databaseName, awsRegion, workgroupName, clusterIdentifier, getStatementResult, databaseUser, secretArn, sqlParameters, additionalFields = {} }) => {
|
|
1004
|
+
const client = await createRedshiftClient(awsConnection, awsRegion, context.debug.enabled);
|
|
1005
|
+
if (!clusterIdentifier && !workgroupName) throw new Error("Either Cluster Identifier or Workgroup Name must be provided");
|
|
1006
|
+
const command = new _aws_sdk_client_redshift_data.ExecuteStatementCommand({
|
|
1007
|
+
Sql: sqlStatement,
|
|
1008
|
+
Database: databaseName,
|
|
1009
|
+
StatementName: additionalFields.statementName,
|
|
1010
|
+
DbUser: databaseUser,
|
|
1011
|
+
SecretArn: secretArn,
|
|
1012
|
+
Parameters: sqlParameters,
|
|
1013
|
+
ResultFormat: additionalFields.resultFormat,
|
|
1014
|
+
SessionId: additionalFields.sessionId,
|
|
1015
|
+
SessionKeepAliveSeconds: additionalFields.sessionKeepAliveSeconds,
|
|
1016
|
+
ClientToken: additionalFields.clientToken,
|
|
1017
|
+
ClusterIdentifier: clusterIdentifier,
|
|
1018
|
+
WorkgroupName: workgroupName
|
|
1019
|
+
});
|
|
1020
|
+
const response = await client.send(command);
|
|
1021
|
+
if (!getStatementResult) return { data: { executeStatement: response } };
|
|
1022
|
+
const id = response.Id;
|
|
1023
|
+
if (!id) throw new Error("Statement ID not found in execute statement response");
|
|
1024
|
+
const describeCommandInput = { Id: id };
|
|
1025
|
+
let needsToWait = true;
|
|
1026
|
+
let status;
|
|
1027
|
+
let hasResultSet = false;
|
|
1028
|
+
do {
|
|
1029
|
+
const describeCommand = new _aws_sdk_client_redshift_data.DescribeStatementCommand(describeCommandInput);
|
|
1030
|
+
const describeResponse = await client.send(describeCommand);
|
|
1031
|
+
status = describeResponse.Status;
|
|
1032
|
+
if (!status) throw new Error("Status not found in describe statement response");
|
|
1033
|
+
needsToWait = ![
|
|
1034
|
+
"FINISHED",
|
|
1035
|
+
"FAILED",
|
|
1036
|
+
"ABORTED"
|
|
1037
|
+
].includes(status);
|
|
1038
|
+
hasResultSet = describeResponse.HasResultSet ?? false;
|
|
1039
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
1040
|
+
} while (needsToWait);
|
|
1041
|
+
if (status === _aws_sdk_client_redshift_data.StatusString.FAILED) throw new Error("Statement failed");
|
|
1042
|
+
if (status === _aws_sdk_client_redshift_data.StatusString.ABORTED) throw new Error("Statement aborted");
|
|
1043
|
+
if (hasResultSet) {
|
|
1044
|
+
const getStatementResultCommand = new _aws_sdk_client_redshift_data.GetStatementResultCommand({ Id: id });
|
|
1045
|
+
return { data: {
|
|
1046
|
+
executeStatement: response,
|
|
1047
|
+
statementResults: await client.send(getStatementResultCommand)
|
|
1048
|
+
} };
|
|
1049
|
+
}
|
|
1050
|
+
return { data: {
|
|
1051
|
+
executeStatement: response,
|
|
1052
|
+
statementResults: null
|
|
1053
|
+
} };
|
|
1054
|
+
},
|
|
1055
|
+
examplePayload: executeStatementExamplePayload
|
|
1056
|
+
}),
|
|
1057
|
+
getStatementResult: (0, _prismatic_io_spectral.action)({
|
|
1058
|
+
display: {
|
|
1059
|
+
label: "Get Statement Result",
|
|
1060
|
+
description: "Retrieve the results of an executed SQL statement from Redshift."
|
|
1061
|
+
},
|
|
1062
|
+
inputs: getStatementResultInputs,
|
|
1063
|
+
perform: async (context, { awsConnection, awsRegion, statementId, nextToken }) => {
|
|
1064
|
+
const client = await createRedshiftClient(awsConnection, awsRegion, context.debug.enabled);
|
|
1065
|
+
const command = new _aws_sdk_client_redshift_data.GetStatementResultCommand({
|
|
1066
|
+
Id: statementId,
|
|
1067
|
+
NextToken: nextToken
|
|
1068
|
+
});
|
|
1069
|
+
return { data: await client.send(command) };
|
|
1070
|
+
},
|
|
1071
|
+
examplePayload: getStatementResultExamplePayload
|
|
1072
|
+
}),
|
|
1073
|
+
listStatements: (0, _prismatic_io_spectral.action)({
|
|
1074
|
+
display: {
|
|
1075
|
+
label: "List Statements",
|
|
1076
|
+
description: "List executed SQL statements in Redshift."
|
|
1077
|
+
},
|
|
1078
|
+
inputs: listStatementsInputs,
|
|
1079
|
+
perform: async (context, { awsConnection, awsRegion, status, fetchAll, filters = {}, pagination = {} }) => {
|
|
1080
|
+
const client = await createRedshiftClient(awsConnection, awsRegion, context.debug.enabled);
|
|
1081
|
+
if (fetchAll) {
|
|
1082
|
+
const { allStatements, lastResponse } = await getAllStatements({
|
|
1083
|
+
client,
|
|
1084
|
+
databaseName: filters.databaseName,
|
|
1085
|
+
workgroupName: filters.workgroupName,
|
|
1086
|
+
clusterIdentifier: filters.clusterIdentifier,
|
|
1087
|
+
status,
|
|
1088
|
+
statementName: filters.statementName
|
|
1089
|
+
});
|
|
1090
|
+
return { data: {
|
|
1091
|
+
...lastResponse,
|
|
1092
|
+
Statements: allStatements
|
|
1093
|
+
} };
|
|
1094
|
+
}
|
|
1095
|
+
const command = new _aws_sdk_client_redshift_data.ListStatementsCommand({
|
|
1096
|
+
Database: filters.databaseName,
|
|
1097
|
+
WorkgroupName: filters.workgroupName,
|
|
1098
|
+
ClusterIdentifier: filters.clusterIdentifier,
|
|
1099
|
+
Status: status,
|
|
1100
|
+
StatementName: filters.statementName,
|
|
1101
|
+
NextToken: pagination.nextToken,
|
|
1102
|
+
MaxResults: pagination.maxResults
|
|
1103
|
+
});
|
|
1104
|
+
return { data: await client.send(command) };
|
|
1105
|
+
},
|
|
1106
|
+
examplePayload: listStatementsExamplePayload
|
|
1107
|
+
})
|
|
1108
|
+
};
|
|
1109
|
+
//#endregion
|
|
1110
|
+
//#region src/actions/index.ts
|
|
1111
|
+
var actions_default = {
|
|
1112
|
+
...misc_default,
|
|
1113
|
+
...statements_default
|
|
1114
|
+
};
|
|
1115
|
+
//#endregion
|
|
1116
|
+
//#region src/dataSources/index.ts
|
|
1117
|
+
var dataSources_default = { selectRegion };
|
|
1118
|
+
//#endregion
|
|
1119
|
+
//#region src/index.ts
|
|
1120
|
+
var src_default = (0, _prismatic_io_spectral.component)({
|
|
1121
|
+
key: "aws-redshift",
|
|
1122
|
+
public: true,
|
|
1123
|
+
display: {
|
|
1124
|
+
label: "Redshift",
|
|
1125
|
+
description: "Execute SQL statements and manage data in Amazon Redshift using the AWS Redshift Data API",
|
|
1126
|
+
iconPath: "icon.png",
|
|
1127
|
+
category: "Application Connectors"
|
|
1128
|
+
},
|
|
1129
|
+
documentationUrl: "https://prismatic.io/docs/components/aws-redshift/",
|
|
1130
|
+
connections: connections_default,
|
|
1131
|
+
dataSources: dataSources_default,
|
|
1132
|
+
actions: actions_default,
|
|
1133
|
+
hooks: { error: _prismatic_io_spectral_http.handleErrors }
|
|
1134
|
+
});
|
|
1135
|
+
//#endregion
|
|
1136
|
+
//#region npm-dist/.entry.ts
|
|
1137
|
+
var _entry_default = (0, _prismatic_io_spectral.callableComponent)(src_default);
|
|
1138
|
+
//#endregion
|
|
1139
|
+
module.exports = _entry_default;
|