@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.
Files changed (86) hide show
  1. package/README.md +61 -8
  2. package/dist/api/api.d.ts.map +1 -1
  3. package/dist/api/api.js +8 -3
  4. package/dist/api/api.js.map +1 -1
  5. package/dist/api/api.test.js +24 -6
  6. package/dist/api/api.test.js.map +1 -1
  7. package/dist/cli/commands/migrate.d.ts.map +1 -1
  8. package/dist/cli/commands/migrate.js +4 -3
  9. package/dist/cli/commands/migrate.js.map +1 -1
  10. package/dist/cli/commands/migrate.test.js +42 -4
  11. package/dist/cli/commands/migrate.test.js.map +1 -1
  12. package/dist/client/base.d.ts +1 -1
  13. package/dist/client/base.js +1 -1
  14. package/dist/generator/connection.d.ts +1 -1
  15. package/dist/generator/connection.d.ts.map +1 -1
  16. package/dist/generator/connection.js +25 -2
  17. package/dist/generator/connection.js.map +1 -1
  18. package/dist/generator/connection.test.js +37 -14
  19. package/dist/generator/connection.test.js.map +1 -1
  20. package/dist/generator/datasource.d.ts.map +1 -1
  21. package/dist/generator/datasource.js +23 -0
  22. package/dist/generator/datasource.js.map +1 -1
  23. package/dist/generator/datasource.test.js +53 -9
  24. package/dist/generator/datasource.test.js.map +1 -1
  25. package/dist/index.d.ts +3 -3
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/index.js.map +1 -1
  29. package/dist/infer/index.d.ts +3 -3
  30. package/dist/migrate/emit-ts.d.ts.map +1 -1
  31. package/dist/migrate/emit-ts.js +69 -13
  32. package/dist/migrate/emit-ts.js.map +1 -1
  33. package/dist/migrate/parse-connection.d.ts +2 -2
  34. package/dist/migrate/parse-connection.d.ts.map +1 -1
  35. package/dist/migrate/parse-connection.js +61 -18
  36. package/dist/migrate/parse-connection.js.map +1 -1
  37. package/dist/migrate/parse-datasource.d.ts.map +1 -1
  38. package/dist/migrate/parse-datasource.js +31 -0
  39. package/dist/migrate/parse-datasource.js.map +1 -1
  40. package/dist/migrate/types.d.ts +18 -1
  41. package/dist/migrate/types.d.ts.map +1 -1
  42. package/dist/schema/connection.d.ts +49 -6
  43. package/dist/schema/connection.d.ts.map +1 -1
  44. package/dist/schema/connection.js +44 -9
  45. package/dist/schema/connection.js.map +1 -1
  46. package/dist/schema/connection.test.js +72 -17
  47. package/dist/schema/connection.test.js.map +1 -1
  48. package/dist/schema/datasource.d.ts +16 -1
  49. package/dist/schema/datasource.d.ts.map +1 -1
  50. package/dist/schema/datasource.js +3 -0
  51. package/dist/schema/datasource.js.map +1 -1
  52. package/dist/schema/datasource.test.js +21 -0
  53. package/dist/schema/datasource.test.js.map +1 -1
  54. package/dist/schema/params.d.ts +3 -3
  55. package/dist/schema/params.d.ts.map +1 -1
  56. package/dist/schema/params.js +3 -3
  57. package/dist/schema/params.js.map +1 -1
  58. package/dist/schema/project.d.ts +3 -3
  59. package/dist/schema/project.js +3 -3
  60. package/dist/schema/types.d.ts +8 -8
  61. package/dist/schema/types.d.ts.map +1 -1
  62. package/dist/schema/types.js +4 -4
  63. package/dist/schema/types.js.map +1 -1
  64. package/package.json +1 -1
  65. package/src/api/api.test.ts +32 -6
  66. package/src/api/api.ts +14 -3
  67. package/src/cli/commands/migrate.test.ts +58 -4
  68. package/src/cli/commands/migrate.ts +6 -4
  69. package/src/client/base.ts +1 -1
  70. package/src/generator/connection.test.ts +45 -14
  71. package/src/generator/connection.ts +30 -2
  72. package/src/generator/datasource.test.ts +61 -9
  73. package/src/generator/datasource.ts +38 -1
  74. package/src/index.ts +12 -1
  75. package/src/infer/index.ts +3 -3
  76. package/src/migrate/emit-ts.ts +80 -16
  77. package/src/migrate/parse-connection.ts +108 -30
  78. package/src/migrate/parse-datasource.ts +46 -1
  79. package/src/migrate/types.ts +24 -2
  80. package/src/schema/connection.test.ts +92 -17
  81. package/src/schema/connection.ts +86 -10
  82. package/src/schema/datasource.test.ts +25 -0
  83. package/src/schema/datasource.ts +21 -1
  84. package/src/schema/params.ts +3 -3
  85. package/src/schema/project.ts +3 -3
  86. 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 { createKafkaConnection, isConnectionDefinition, isKafkaConnectionDefinition, getConnectionType } from "./schema/connection.js";
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 ============
@@ -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: Date }
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: Date }
159
+ * // { id: string; timestamp: string }
160
160
  *
161
161
  * // Use for type-safe event ingestion
162
- * const event: Event = { id: '123', timestamp: new Date() };
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>;
@@ -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} = createKafkaConnection(${escapeString(connection.name)}, {`
318
+ `export const ${variableName} = defineS3Connection(${escapeString(connection.name)}, {`
278
319
  );
279
- lines.push(` bootstrapServers: ${escapeString(connection.bootstrapServers)},`);
280
- if (connection.securityProtocol) {
281
- lines.push(` securityProtocol: ${escapeString(connection.securityProtocol)},`);
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.key) {
287
- lines.push(` key: ${escapeString(connection.key)},`);
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 => resource.kind === "connection"
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>(["createKafkaConnection", "defineDatasource", "definePipe", "defineMaterializedView", "defineCopyPipe", "node", "t", "engine"]);
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 { ${Array.from(imports).join(", ")} } from "@tinybirdco/sdk";`);
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(resource: ResourceFile): KafkaConnectionModel {
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 !== "kafka") {
98
- throw new MigrationParseError(
99
- resource.filePath,
100
- "connection",
101
- resource.name,
102
- `Unsupported connection type in strict mode: "${connectionType}"`
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 (!bootstrapServers) {
107
- throw new MigrationParseError(
108
- resource.filePath,
109
- "connection",
110
- resource.name,
111
- "KAFKA_BOOTSTRAP_SERVERS is required for kafka connections."
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
- return {
116
- kind: "connection",
117
- name: resource.name,
118
- filePath: resource.filePath,
119
- connectionType: "kafka",
120
- bootstrapServers,
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
-
@@ -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 type ParsedResource = DatasourceModel | PipeModel | KafkaConnectionModel;
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
-