@tinybirdco/sdk 0.0.44 → 0.0.46
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 +61 -8
- package/dist/api/api.d.ts.map +1 -1
- package/dist/api/api.js +8 -3
- package/dist/api/api.js.map +1 -1
- package/dist/api/api.test.js +24 -6
- package/dist/api/api.test.js.map +1 -1
- package/dist/cli/commands/migrate.d.ts.map +1 -1
- package/dist/cli/commands/migrate.js +4 -3
- package/dist/cli/commands/migrate.js.map +1 -1
- package/dist/cli/commands/migrate.test.js +42 -4
- package/dist/cli/commands/migrate.test.js.map +1 -1
- package/dist/client/base.d.ts +1 -1
- package/dist/client/base.js +1 -1
- package/dist/generator/connection.d.ts +1 -1
- package/dist/generator/connection.d.ts.map +1 -1
- package/dist/generator/connection.js +25 -2
- package/dist/generator/connection.js.map +1 -1
- package/dist/generator/connection.test.js +37 -14
- package/dist/generator/connection.test.js.map +1 -1
- package/dist/generator/datasource.d.ts.map +1 -1
- package/dist/generator/datasource.js +23 -0
- package/dist/generator/datasource.js.map +1 -1
- package/dist/generator/datasource.test.js +53 -9
- package/dist/generator/datasource.test.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/infer/index.d.ts +3 -3
- package/dist/migrate/emit-ts.d.ts.map +1 -1
- package/dist/migrate/emit-ts.js +69 -13
- package/dist/migrate/emit-ts.js.map +1 -1
- package/dist/migrate/parse-connection.d.ts +2 -2
- package/dist/migrate/parse-connection.d.ts.map +1 -1
- package/dist/migrate/parse-connection.js +61 -18
- package/dist/migrate/parse-connection.js.map +1 -1
- package/dist/migrate/parse-datasource.d.ts.map +1 -1
- package/dist/migrate/parse-datasource.js +31 -0
- package/dist/migrate/parse-datasource.js.map +1 -1
- package/dist/migrate/types.d.ts +18 -1
- package/dist/migrate/types.d.ts.map +1 -1
- package/dist/schema/connection.d.ts +49 -6
- package/dist/schema/connection.d.ts.map +1 -1
- package/dist/schema/connection.js +44 -9
- package/dist/schema/connection.js.map +1 -1
- package/dist/schema/connection.test.js +72 -17
- package/dist/schema/connection.test.js.map +1 -1
- package/dist/schema/datasource.d.ts +16 -1
- package/dist/schema/datasource.d.ts.map +1 -1
- package/dist/schema/datasource.js +3 -0
- package/dist/schema/datasource.js.map +1 -1
- package/dist/schema/datasource.test.js +21 -0
- package/dist/schema/datasource.test.js.map +1 -1
- package/dist/schema/params.d.ts +3 -3
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js +3 -3
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/project.d.ts +3 -3
- package/dist/schema/project.js +3 -3
- package/dist/schema/types.d.ts +8 -8
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +4 -4
- package/dist/schema/types.js.map +1 -1
- package/package.json +1 -1
- package/src/api/api.test.ts +32 -6
- package/src/api/api.ts +14 -3
- package/src/cli/commands/migrate.test.ts +58 -4
- package/src/cli/commands/migrate.ts +6 -4
- package/src/client/base.ts +1 -1
- package/src/generator/connection.test.ts +45 -14
- package/src/generator/connection.ts +30 -2
- package/src/generator/datasource.test.ts +61 -9
- package/src/generator/datasource.ts +38 -1
- package/src/index.ts +12 -1
- package/src/infer/index.ts +3 -3
- package/src/migrate/emit-ts.ts +80 -16
- package/src/migrate/parse-connection.ts +108 -30
- package/src/migrate/parse-datasource.ts +46 -1
- package/src/migrate/types.ts +24 -2
- package/src/schema/connection.test.ts +92 -17
- package/src/schema/connection.ts +86 -10
- package/src/schema/datasource.test.ts +25 -0
- package/src/schema/datasource.ts +21 -1
- package/src/schema/params.ts +3 -3
- package/src/schema/project.ts +3 -3
- package/src/schema/types.ts +10 -10
package/src/index.ts
CHANGED
|
@@ -109,16 +109,27 @@ export type {
|
|
|
109
109
|
DatasourceTokenReference,
|
|
110
110
|
ExtractSchema,
|
|
111
111
|
KafkaConfig,
|
|
112
|
+
S3Config,
|
|
112
113
|
} from "./schema/datasource.js";
|
|
113
114
|
|
|
114
115
|
// ============ Connection ============
|
|
115
|
-
export {
|
|
116
|
+
export {
|
|
117
|
+
defineKafkaConnection,
|
|
118
|
+
createKafkaConnection,
|
|
119
|
+
defineS3Connection,
|
|
120
|
+
isConnectionDefinition,
|
|
121
|
+
isKafkaConnectionDefinition,
|
|
122
|
+
isS3ConnectionDefinition,
|
|
123
|
+
getConnectionType,
|
|
124
|
+
} from "./schema/connection.js";
|
|
116
125
|
export type {
|
|
117
126
|
ConnectionDefinition,
|
|
118
127
|
KafkaConnectionDefinition,
|
|
119
128
|
KafkaConnectionOptions,
|
|
120
129
|
KafkaSecurityProtocol,
|
|
121
130
|
KafkaSaslMechanism,
|
|
131
|
+
S3ConnectionDefinition,
|
|
132
|
+
S3ConnectionOptions,
|
|
122
133
|
} from "./schema/connection.js";
|
|
123
134
|
|
|
124
135
|
// ============ Token ============
|
package/src/infer/index.ts
CHANGED
|
@@ -52,7 +52,7 @@ type InferColumn<T> = T extends TypeValidator<infer U, string, TypeModifiers>
|
|
|
52
52
|
* });
|
|
53
53
|
*
|
|
54
54
|
* type EventRow = InferRow<typeof events>;
|
|
55
|
-
* // { id: string; count: number; timestamp:
|
|
55
|
+
* // { id: string; count: number; timestamp: string }
|
|
56
56
|
* ```
|
|
57
57
|
*/
|
|
58
58
|
export type InferRow<T> = T extends DatasourceDefinition<infer S>
|
|
@@ -156,10 +156,10 @@ export type InferOutputRow<T> = T extends PipeDefinition<ParamsDefinition, infer
|
|
|
156
156
|
* });
|
|
157
157
|
*
|
|
158
158
|
* type Event = InferEvent<typeof events>;
|
|
159
|
-
* // { id: string; timestamp:
|
|
159
|
+
* // { id: string; timestamp: string }
|
|
160
160
|
*
|
|
161
161
|
* // Use for type-safe event ingestion
|
|
162
|
-
* const event: Event = { id: '123', timestamp:
|
|
162
|
+
* const event: Event = { id: '123', timestamp: '2024-01-01 00:00:00' };
|
|
163
163
|
* ```
|
|
164
164
|
*/
|
|
165
165
|
export type InferEvent<T> = InferRow<T>;
|
package/src/migrate/emit-ts.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
KafkaConnectionModel,
|
|
7
7
|
ParsedResource,
|
|
8
8
|
PipeModel,
|
|
9
|
+
S3ConnectionModel,
|
|
9
10
|
} from "./types.js";
|
|
10
11
|
|
|
11
12
|
function escapeString(value: string): string {
|
|
@@ -243,6 +244,20 @@ function emitDatasource(ds: DatasourceModel): string {
|
|
|
243
244
|
lines.push(" },");
|
|
244
245
|
}
|
|
245
246
|
|
|
247
|
+
if (ds.s3) {
|
|
248
|
+
const connectionVar = toCamelCase(ds.s3.connectionName);
|
|
249
|
+
lines.push(" s3: {");
|
|
250
|
+
lines.push(` connection: ${connectionVar},`);
|
|
251
|
+
lines.push(` bucketUri: ${escapeString(ds.s3.bucketUri)},`);
|
|
252
|
+
if (ds.s3.schedule) {
|
|
253
|
+
lines.push(` schedule: ${escapeString(ds.s3.schedule)},`);
|
|
254
|
+
}
|
|
255
|
+
if (ds.s3.fromTimestamp) {
|
|
256
|
+
lines.push(` fromTimestamp: ${escapeString(ds.s3.fromTimestamp)},`);
|
|
257
|
+
}
|
|
258
|
+
lines.push(" },");
|
|
259
|
+
}
|
|
260
|
+
|
|
246
261
|
if (ds.forwardQuery) {
|
|
247
262
|
lines.push(" forwardQuery: `");
|
|
248
263
|
lines.push(ds.forwardQuery.replace(/`/g, "\\`").replace(/\${/g, "\\${"));
|
|
@@ -270,28 +285,48 @@ function emitDatasource(ds: DatasourceModel): string {
|
|
|
270
285
|
return lines.join("\n");
|
|
271
286
|
}
|
|
272
287
|
|
|
273
|
-
function emitConnection(connection: KafkaConnectionModel): string {
|
|
288
|
+
function emitConnection(connection: KafkaConnectionModel | S3ConnectionModel): string {
|
|
274
289
|
const variableName = toCamelCase(connection.name);
|
|
275
290
|
const lines: string[] = [];
|
|
291
|
+
|
|
292
|
+
if (connection.connectionType === "kafka") {
|
|
293
|
+
lines.push(
|
|
294
|
+
`export const ${variableName} = defineKafkaConnection(${escapeString(connection.name)}, {`
|
|
295
|
+
);
|
|
296
|
+
lines.push(` bootstrapServers: ${escapeString(connection.bootstrapServers)},`);
|
|
297
|
+
if (connection.securityProtocol) {
|
|
298
|
+
lines.push(` securityProtocol: ${escapeString(connection.securityProtocol)},`);
|
|
299
|
+
}
|
|
300
|
+
if (connection.saslMechanism) {
|
|
301
|
+
lines.push(` saslMechanism: ${escapeString(connection.saslMechanism)},`);
|
|
302
|
+
}
|
|
303
|
+
if (connection.key) {
|
|
304
|
+
lines.push(` key: ${escapeString(connection.key)},`);
|
|
305
|
+
}
|
|
306
|
+
if (connection.secret) {
|
|
307
|
+
lines.push(` secret: ${escapeString(connection.secret)},`);
|
|
308
|
+
}
|
|
309
|
+
if (connection.sslCaPem) {
|
|
310
|
+
lines.push(` sslCaPem: ${escapeString(connection.sslCaPem)},`);
|
|
311
|
+
}
|
|
312
|
+
lines.push("});");
|
|
313
|
+
lines.push("");
|
|
314
|
+
return lines.join("\n");
|
|
315
|
+
}
|
|
316
|
+
|
|
276
317
|
lines.push(
|
|
277
|
-
`export const ${variableName} =
|
|
318
|
+
`export const ${variableName} = defineS3Connection(${escapeString(connection.name)}, {`
|
|
278
319
|
);
|
|
279
|
-
lines.push(`
|
|
280
|
-
if (connection.
|
|
281
|
-
lines.push(`
|
|
282
|
-
}
|
|
283
|
-
if (connection.saslMechanism) {
|
|
284
|
-
lines.push(` saslMechanism: ${escapeString(connection.saslMechanism)},`);
|
|
320
|
+
lines.push(` region: ${escapeString(connection.region)},`);
|
|
321
|
+
if (connection.arn) {
|
|
322
|
+
lines.push(` arn: ${escapeString(connection.arn)},`);
|
|
285
323
|
}
|
|
286
|
-
if (connection.
|
|
287
|
-
lines.push(`
|
|
324
|
+
if (connection.accessKey) {
|
|
325
|
+
lines.push(` accessKey: ${escapeString(connection.accessKey)},`);
|
|
288
326
|
}
|
|
289
327
|
if (connection.secret) {
|
|
290
328
|
lines.push(` secret: ${escapeString(connection.secret)},`);
|
|
291
329
|
}
|
|
292
|
-
if (connection.sslCaPem) {
|
|
293
|
-
lines.push(` sslCaPem: ${escapeString(connection.sslCaPem)},`);
|
|
294
|
-
}
|
|
295
330
|
lines.push("});");
|
|
296
331
|
lines.push("");
|
|
297
332
|
return lines.join("\n");
|
|
@@ -398,7 +433,8 @@ function emitPipe(pipe: PipeModel): string {
|
|
|
398
433
|
|
|
399
434
|
export function emitMigrationFileContent(resources: ParsedResource[]): string {
|
|
400
435
|
const connections = resources.filter(
|
|
401
|
-
(resource): resource is KafkaConnectionModel
|
|
436
|
+
(resource): resource is KafkaConnectionModel | S3ConnectionModel =>
|
|
437
|
+
resource.kind === "connection"
|
|
402
438
|
);
|
|
403
439
|
const datasources = resources.filter(
|
|
404
440
|
(resource): resource is DatasourceModel => resource.kind === "datasource"
|
|
@@ -412,7 +448,21 @@ export function emitMigrationFileContent(resources: ParsedResource[]): string {
|
|
|
412
448
|
);
|
|
413
449
|
const needsParams = pipes.some((pipe) => pipe.params.length > 0);
|
|
414
450
|
|
|
415
|
-
const imports = new Set<string>([
|
|
451
|
+
const imports = new Set<string>([
|
|
452
|
+
"defineDatasource",
|
|
453
|
+
"definePipe",
|
|
454
|
+
"defineMaterializedView",
|
|
455
|
+
"defineCopyPipe",
|
|
456
|
+
"node",
|
|
457
|
+
"t",
|
|
458
|
+
"engine",
|
|
459
|
+
]);
|
|
460
|
+
if (connections.some((connection) => connection.connectionType === "kafka")) {
|
|
461
|
+
imports.add("defineKafkaConnection");
|
|
462
|
+
}
|
|
463
|
+
if (connections.some((connection) => connection.connectionType === "s3")) {
|
|
464
|
+
imports.add("defineS3Connection");
|
|
465
|
+
}
|
|
416
466
|
if (needsColumn) {
|
|
417
467
|
imports.add("column");
|
|
418
468
|
}
|
|
@@ -420,13 +470,27 @@ export function emitMigrationFileContent(resources: ParsedResource[]): string {
|
|
|
420
470
|
imports.add("p");
|
|
421
471
|
}
|
|
422
472
|
|
|
473
|
+
const orderedImports = [
|
|
474
|
+
"defineKafkaConnection",
|
|
475
|
+
"defineS3Connection",
|
|
476
|
+
"defineDatasource",
|
|
477
|
+
"definePipe",
|
|
478
|
+
"defineMaterializedView",
|
|
479
|
+
"defineCopyPipe",
|
|
480
|
+
"node",
|
|
481
|
+
"t",
|
|
482
|
+
"engine",
|
|
483
|
+
"column",
|
|
484
|
+
"p",
|
|
485
|
+
].filter((name) => imports.has(name));
|
|
486
|
+
|
|
423
487
|
const lines: string[] = [];
|
|
424
488
|
lines.push("/**");
|
|
425
489
|
lines.push(" * Generated by tinybird migrate.");
|
|
426
490
|
lines.push(" * Review endpoint output schemas and any defaults before production use.");
|
|
427
491
|
lines.push(" */");
|
|
428
492
|
lines.push("");
|
|
429
|
-
lines.push(`import { ${
|
|
493
|
+
lines.push(`import { ${orderedImports.join(", ")} } from "@tinybirdco/sdk";`);
|
|
430
494
|
lines.push("");
|
|
431
495
|
|
|
432
496
|
if (connections.length > 0) {
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import type { KafkaConnectionModel, ResourceFile } from "./types.js";
|
|
1
|
+
import type { KafkaConnectionModel, ResourceFile, S3ConnectionModel } from "./types.js";
|
|
2
2
|
import {
|
|
3
3
|
MigrationParseError,
|
|
4
4
|
isBlank,
|
|
5
5
|
parseDirectiveLine,
|
|
6
|
+
parseQuotedValue,
|
|
6
7
|
splitLines,
|
|
7
8
|
} from "./parser-utils.js";
|
|
8
9
|
|
|
9
|
-
export function parseConnectionFile(
|
|
10
|
+
export function parseConnectionFile(
|
|
11
|
+
resource: ResourceFile
|
|
12
|
+
): KafkaConnectionModel | S3ConnectionModel {
|
|
10
13
|
const lines = splitLines(resource.content);
|
|
11
14
|
let connectionType: string | undefined;
|
|
15
|
+
|
|
12
16
|
let bootstrapServers: string | undefined;
|
|
13
17
|
let securityProtocol:
|
|
14
18
|
| "SASL_SSL"
|
|
@@ -25,6 +29,11 @@ export function parseConnectionFile(resource: ResourceFile): KafkaConnectionMode
|
|
|
25
29
|
let secret: string | undefined;
|
|
26
30
|
let sslCaPem: string | undefined;
|
|
27
31
|
|
|
32
|
+
let region: string | undefined;
|
|
33
|
+
let arn: string | undefined;
|
|
34
|
+
let accessKey: string | undefined;
|
|
35
|
+
let accessSecret: string | undefined;
|
|
36
|
+
|
|
28
37
|
for (const rawLine of lines) {
|
|
29
38
|
const line = rawLine.trim();
|
|
30
39
|
if (isBlank(line)) {
|
|
@@ -34,7 +43,7 @@ export function parseConnectionFile(resource: ResourceFile): KafkaConnectionMode
|
|
|
34
43
|
const { key: directive, value } = parseDirectiveLine(line);
|
|
35
44
|
switch (directive) {
|
|
36
45
|
case "TYPE":
|
|
37
|
-
connectionType = value;
|
|
46
|
+
connectionType = parseQuotedValue(value);
|
|
38
47
|
break;
|
|
39
48
|
case "KAFKA_BOOTSTRAP_SERVERS":
|
|
40
49
|
bootstrapServers = value;
|
|
@@ -75,6 +84,18 @@ export function parseConnectionFile(resource: ResourceFile): KafkaConnectionMode
|
|
|
75
84
|
case "KAFKA_SSL_CA_PEM":
|
|
76
85
|
sslCaPem = value;
|
|
77
86
|
break;
|
|
87
|
+
case "S3_REGION":
|
|
88
|
+
region = parseQuotedValue(value);
|
|
89
|
+
break;
|
|
90
|
+
case "S3_ARN":
|
|
91
|
+
arn = parseQuotedValue(value);
|
|
92
|
+
break;
|
|
93
|
+
case "S3_ACCESS_KEY":
|
|
94
|
+
accessKey = parseQuotedValue(value);
|
|
95
|
+
break;
|
|
96
|
+
case "S3_SECRET":
|
|
97
|
+
accessSecret = parseQuotedValue(value);
|
|
98
|
+
break;
|
|
78
99
|
default:
|
|
79
100
|
throw new MigrationParseError(
|
|
80
101
|
resource.filePath,
|
|
@@ -94,35 +115,92 @@ export function parseConnectionFile(resource: ResourceFile): KafkaConnectionMode
|
|
|
94
115
|
);
|
|
95
116
|
}
|
|
96
117
|
|
|
97
|
-
if (connectionType
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
118
|
+
if (connectionType === "kafka") {
|
|
119
|
+
if (region || arn || accessKey || accessSecret) {
|
|
120
|
+
throw new MigrationParseError(
|
|
121
|
+
resource.filePath,
|
|
122
|
+
"connection",
|
|
123
|
+
resource.name,
|
|
124
|
+
"S3 directives are not valid for kafka connections."
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!bootstrapServers) {
|
|
129
|
+
throw new MigrationParseError(
|
|
130
|
+
resource.filePath,
|
|
131
|
+
"connection",
|
|
132
|
+
resource.name,
|
|
133
|
+
"KAFKA_BOOTSTRAP_SERVERS is required for kafka connections."
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
kind: "connection",
|
|
139
|
+
name: resource.name,
|
|
140
|
+
filePath: resource.filePath,
|
|
141
|
+
connectionType: "kafka",
|
|
142
|
+
bootstrapServers,
|
|
143
|
+
securityProtocol,
|
|
144
|
+
saslMechanism,
|
|
145
|
+
key,
|
|
146
|
+
secret,
|
|
147
|
+
sslCaPem,
|
|
148
|
+
};
|
|
104
149
|
}
|
|
105
150
|
|
|
106
|
-
if (
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
151
|
+
if (connectionType === "s3") {
|
|
152
|
+
if (bootstrapServers || securityProtocol || saslMechanism || key || secret || sslCaPem) {
|
|
153
|
+
throw new MigrationParseError(
|
|
154
|
+
resource.filePath,
|
|
155
|
+
"connection",
|
|
156
|
+
resource.name,
|
|
157
|
+
"Kafka directives are not valid for s3 connections."
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (!region) {
|
|
162
|
+
throw new MigrationParseError(
|
|
163
|
+
resource.filePath,
|
|
164
|
+
"connection",
|
|
165
|
+
resource.name,
|
|
166
|
+
"S3_REGION is required for s3 connections."
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (!arn && !(accessKey && accessSecret)) {
|
|
171
|
+
throw new MigrationParseError(
|
|
172
|
+
resource.filePath,
|
|
173
|
+
"connection",
|
|
174
|
+
resource.name,
|
|
175
|
+
"S3 connections require S3_ARN or both S3_ACCESS_KEY and S3_SECRET."
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if ((accessKey && !accessSecret) || (!accessKey && accessSecret)) {
|
|
180
|
+
throw new MigrationParseError(
|
|
181
|
+
resource.filePath,
|
|
182
|
+
"connection",
|
|
183
|
+
resource.name,
|
|
184
|
+
"S3_ACCESS_KEY and S3_SECRET must be provided together."
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
kind: "connection",
|
|
190
|
+
name: resource.name,
|
|
191
|
+
filePath: resource.filePath,
|
|
192
|
+
connectionType: "s3",
|
|
193
|
+
region,
|
|
194
|
+
arn,
|
|
195
|
+
accessKey,
|
|
196
|
+
secret: accessSecret,
|
|
197
|
+
};
|
|
113
198
|
}
|
|
114
199
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
securityProtocol,
|
|
122
|
-
saslMechanism,
|
|
123
|
-
key,
|
|
124
|
-
secret,
|
|
125
|
-
sslCaPem,
|
|
126
|
-
};
|
|
200
|
+
throw new MigrationParseError(
|
|
201
|
+
resource.filePath,
|
|
202
|
+
"connection",
|
|
203
|
+
resource.name,
|
|
204
|
+
`Unsupported connection type in strict mode: "${connectionType}"`
|
|
205
|
+
);
|
|
127
206
|
}
|
|
128
|
-
|
|
@@ -233,6 +233,11 @@ export function parseDatasourceFile(resource: ResourceFile): DatasourceModel {
|
|
|
233
233
|
let kafkaGroupId: string | undefined;
|
|
234
234
|
let kafkaAutoOffsetReset: "earliest" | "latest" | undefined;
|
|
235
235
|
|
|
236
|
+
let importConnectionName: string | undefined;
|
|
237
|
+
let importBucketUri: string | undefined;
|
|
238
|
+
let importSchedule: string | undefined;
|
|
239
|
+
let importFromTimestamp: string | undefined;
|
|
240
|
+
|
|
236
241
|
let i = 0;
|
|
237
242
|
while (i < lines.length) {
|
|
238
243
|
const rawLine = lines[i] ?? "";
|
|
@@ -365,6 +370,18 @@ export function parseDatasourceFile(resource: ResourceFile): DatasourceModel {
|
|
|
365
370
|
}
|
|
366
371
|
kafkaAutoOffsetReset = value;
|
|
367
372
|
break;
|
|
373
|
+
case "IMPORT_CONNECTION_NAME":
|
|
374
|
+
importConnectionName = parseQuotedValue(value);
|
|
375
|
+
break;
|
|
376
|
+
case "IMPORT_BUCKET_URI":
|
|
377
|
+
importBucketUri = parseQuotedValue(value);
|
|
378
|
+
break;
|
|
379
|
+
case "IMPORT_SCHEDULE":
|
|
380
|
+
importSchedule = parseQuotedValue(value);
|
|
381
|
+
break;
|
|
382
|
+
case "IMPORT_FROM_TIMESTAMP":
|
|
383
|
+
importFromTimestamp = parseQuotedValue(value);
|
|
384
|
+
break;
|
|
368
385
|
case "TOKEN":
|
|
369
386
|
tokens.push(parseToken(resource.filePath, resource.name, value));
|
|
370
387
|
break;
|
|
@@ -426,6 +443,34 @@ export function parseDatasourceFile(resource: ResourceFile): DatasourceModel {
|
|
|
426
443
|
);
|
|
427
444
|
}
|
|
428
445
|
|
|
446
|
+
const s3 =
|
|
447
|
+
importConnectionName || importBucketUri || importSchedule || importFromTimestamp
|
|
448
|
+
? {
|
|
449
|
+
connectionName: importConnectionName ?? "",
|
|
450
|
+
bucketUri: importBucketUri ?? "",
|
|
451
|
+
schedule: importSchedule,
|
|
452
|
+
fromTimestamp: importFromTimestamp,
|
|
453
|
+
}
|
|
454
|
+
: undefined;
|
|
455
|
+
|
|
456
|
+
if (s3 && (!s3.connectionName || !s3.bucketUri)) {
|
|
457
|
+
throw new MigrationParseError(
|
|
458
|
+
resource.filePath,
|
|
459
|
+
"datasource",
|
|
460
|
+
resource.name,
|
|
461
|
+
"IMPORT_CONNECTION_NAME and IMPORT_BUCKET_URI are required when S3 import directives are used."
|
|
462
|
+
);
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (kafka && s3) {
|
|
466
|
+
throw new MigrationParseError(
|
|
467
|
+
resource.filePath,
|
|
468
|
+
"datasource",
|
|
469
|
+
resource.name,
|
|
470
|
+
"Datasource cannot mix Kafka directives with S3 import directives."
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
|
|
429
474
|
return {
|
|
430
475
|
kind: "datasource",
|
|
431
476
|
name: resource.name,
|
|
@@ -445,9 +490,9 @@ export function parseDatasourceFile(resource: ResourceFile): DatasourceModel {
|
|
|
445
490
|
settings,
|
|
446
491
|
},
|
|
447
492
|
kafka,
|
|
493
|
+
s3,
|
|
448
494
|
forwardQuery,
|
|
449
495
|
tokens,
|
|
450
496
|
sharedWith,
|
|
451
497
|
};
|
|
452
498
|
}
|
|
453
|
-
|
package/src/migrate/types.ts
CHANGED
|
@@ -43,6 +43,13 @@ export interface DatasourceKafkaModel {
|
|
|
43
43
|
autoOffsetReset?: "earliest" | "latest";
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
export interface DatasourceS3Model {
|
|
47
|
+
connectionName: string;
|
|
48
|
+
bucketUri: string;
|
|
49
|
+
schedule?: string;
|
|
50
|
+
fromTimestamp?: string;
|
|
51
|
+
}
|
|
52
|
+
|
|
46
53
|
export interface DatasourceTokenModel {
|
|
47
54
|
name: string;
|
|
48
55
|
scope: "READ" | "APPEND";
|
|
@@ -56,6 +63,7 @@ export interface DatasourceModel {
|
|
|
56
63
|
columns: DatasourceColumnModel[];
|
|
57
64
|
engine: DatasourceEngineModel;
|
|
58
65
|
kafka?: DatasourceKafkaModel;
|
|
66
|
+
s3?: DatasourceS3Model;
|
|
59
67
|
forwardQuery?: string;
|
|
60
68
|
tokens: DatasourceTokenModel[];
|
|
61
69
|
sharedWith: string[];
|
|
@@ -112,7 +120,22 @@ export interface KafkaConnectionModel {
|
|
|
112
120
|
sslCaPem?: string;
|
|
113
121
|
}
|
|
114
122
|
|
|
115
|
-
export
|
|
123
|
+
export interface S3ConnectionModel {
|
|
124
|
+
kind: "connection";
|
|
125
|
+
name: string;
|
|
126
|
+
filePath: string;
|
|
127
|
+
connectionType: "s3";
|
|
128
|
+
region: string;
|
|
129
|
+
arn?: string;
|
|
130
|
+
accessKey?: string;
|
|
131
|
+
secret?: string;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export type ParsedResource =
|
|
135
|
+
| DatasourceModel
|
|
136
|
+
| PipeModel
|
|
137
|
+
| KafkaConnectionModel
|
|
138
|
+
| S3ConnectionModel;
|
|
116
139
|
|
|
117
140
|
export interface MigrationResult {
|
|
118
141
|
success: boolean;
|
|
@@ -122,4 +145,3 @@ export interface MigrationResult {
|
|
|
122
145
|
dryRun: boolean;
|
|
123
146
|
outputContent?: string;
|
|
124
147
|
}
|
|
125
|
-
|