@whaly/connector-sdk 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/LICENSE +201 -0
- package/dist/index.d.mts +725 -0
- package/dist/index.d.ts +725 -0
- package/dist/index.js +2878 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2786 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +68 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,725 @@
|
|
|
1
|
+
import winston from 'winston';
|
|
2
|
+
import { Validator, ValidationError } from 'jsonschema';
|
|
3
|
+
import moment from 'moment';
|
|
4
|
+
import { WriteStream } from 'fs';
|
|
5
|
+
import { AxiosInstance, AxiosRequestHeaders, AxiosResponse, AxiosRequestConfig, AxiosError } from 'axios';
|
|
6
|
+
|
|
7
|
+
interface StreamRelationship {
|
|
8
|
+
left: StreamId;
|
|
9
|
+
right: StreamId;
|
|
10
|
+
from: string;
|
|
11
|
+
to: string;
|
|
12
|
+
type: "1-1" | "1-N" | "N-1";
|
|
13
|
+
}
|
|
14
|
+
interface DirectionalRelationship {
|
|
15
|
+
type: "1-N" | "N-1" | "1-1";
|
|
16
|
+
streamId: StreamId;
|
|
17
|
+
from: string;
|
|
18
|
+
to: string;
|
|
19
|
+
}
|
|
20
|
+
interface DirectionalRelationships {
|
|
21
|
+
left: DirectionalRelationship[];
|
|
22
|
+
right: DirectionalRelationship[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface PropertiesMetadata {
|
|
26
|
+
[propName: string]: {
|
|
27
|
+
label: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
interface Schema {
|
|
32
|
+
"jsonSchema": {
|
|
33
|
+
"type": "object";
|
|
34
|
+
"properties": any;
|
|
35
|
+
};
|
|
36
|
+
"propertiesMetadata"?: PropertiesMetadata;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
type MessageType = "RECORD" | "STATE" | "SCHEMA" | "ACTIVATE_VERSION" | "REPLICATION_METHOD";
|
|
40
|
+
interface Message {
|
|
41
|
+
type: MessageType;
|
|
42
|
+
toString(): string;
|
|
43
|
+
}
|
|
44
|
+
declare class RecordMessage implements Message {
|
|
45
|
+
type: MessageType;
|
|
46
|
+
stream: StreamId;
|
|
47
|
+
record: any;
|
|
48
|
+
constructor(record: any, stream: StreamId);
|
|
49
|
+
toString(): string;
|
|
50
|
+
}
|
|
51
|
+
declare class StateMessage implements Message {
|
|
52
|
+
type: MessageType;
|
|
53
|
+
value: any;
|
|
54
|
+
constructor(value: any);
|
|
55
|
+
toString(): string;
|
|
56
|
+
}
|
|
57
|
+
declare class ReplicationMethodMessage implements Message {
|
|
58
|
+
type: MessageType;
|
|
59
|
+
stream: string;
|
|
60
|
+
replication: ReplicationMethod;
|
|
61
|
+
constructor(stream: string, version: ReplicationMethod);
|
|
62
|
+
toString(): string;
|
|
63
|
+
}
|
|
64
|
+
declare class SchemaMessage implements Message {
|
|
65
|
+
type: MessageType;
|
|
66
|
+
stream: StreamId;
|
|
67
|
+
schema: any;
|
|
68
|
+
keyProperties: string[];
|
|
69
|
+
bookmarkProperties: string[] | undefined;
|
|
70
|
+
displayLabel: string | undefined;
|
|
71
|
+
description: string | undefined;
|
|
72
|
+
propertiesMetadata: PropertiesMetadata | undefined;
|
|
73
|
+
relationships: DirectionalRelationships;
|
|
74
|
+
constructor(opts: {
|
|
75
|
+
stream: StreamId;
|
|
76
|
+
schema: any;
|
|
77
|
+
keyProperties: string[];
|
|
78
|
+
bookmarkProperties?: string[];
|
|
79
|
+
displayLabel?: string;
|
|
80
|
+
description?: string;
|
|
81
|
+
relationships: DirectionalRelationships;
|
|
82
|
+
propertiesMetadata?: PropertiesMetadata | undefined;
|
|
83
|
+
});
|
|
84
|
+
toString(): string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
interface TargetSchemaHookInput {
|
|
88
|
+
message: SchemaMessage;
|
|
89
|
+
databaseName: string;
|
|
90
|
+
schemaName: string;
|
|
91
|
+
tableName: string;
|
|
92
|
+
}
|
|
93
|
+
interface TargetSchemaHook {
|
|
94
|
+
writeSchema: (input: TargetSchemaHookInput) => Promise<void>;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
type ErrorType = "unauthorized" | "unknown";
|
|
98
|
+
|
|
99
|
+
declare abstract class Resolver {
|
|
100
|
+
constructor();
|
|
101
|
+
abstract checkIfCanSync(): Promise<boolean>;
|
|
102
|
+
abstract markSyncStarted(): Promise<void>;
|
|
103
|
+
abstract startVPNIfNeeded(): Promise<void>;
|
|
104
|
+
abstract getConfig(command: ShoreCommand): Promise<ShoreConfig>;
|
|
105
|
+
abstract writeCatalog(catalog: CatalogFile): Promise<void>;
|
|
106
|
+
abstract writeState(state: string): Promise<void>;
|
|
107
|
+
abstract markSyncFailed(): Promise<void>;
|
|
108
|
+
abstract markSyncComplete(): Promise<void>;
|
|
109
|
+
abstract markDiscoveryComplete(): Promise<void>;
|
|
110
|
+
abstract flushMetrics(): Promise<void>;
|
|
111
|
+
abstract onError(errorType: ErrorType, errorText: string, errorDebugText: string): Promise<void>;
|
|
112
|
+
abstract getSchemaHooks(): TargetSchemaHook[];
|
|
113
|
+
abstract updateSourceValue(optionKey: string, optionValue: string): Promise<void>;
|
|
114
|
+
abstract getLogFormat(): winston.Logform.Format;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
interface FlattenedSchema {
|
|
118
|
+
[unsafePropertyName: string]: JSONSchemaFieldDefinition;
|
|
119
|
+
}
|
|
120
|
+
interface JSONSchemaFieldDefinition {
|
|
121
|
+
type: string[] | string;
|
|
122
|
+
format?: "date-time" | "json";
|
|
123
|
+
items?: JSONSchemaFieldDefinition;
|
|
124
|
+
}
|
|
125
|
+
interface WarehouseTableField {
|
|
126
|
+
name: string;
|
|
127
|
+
type: string;
|
|
128
|
+
}
|
|
129
|
+
interface InternalTableField {
|
|
130
|
+
unsafeName: string;
|
|
131
|
+
name: string;
|
|
132
|
+
definition: JSONSchemaFieldDefinition;
|
|
133
|
+
}
|
|
134
|
+
interface TempFile {
|
|
135
|
+
stream: WriteStream;
|
|
136
|
+
path: string;
|
|
137
|
+
}
|
|
138
|
+
interface StreamWithTempFile {
|
|
139
|
+
streamId: StreamId;
|
|
140
|
+
tempFile: TempFile;
|
|
141
|
+
}
|
|
142
|
+
interface BaseConfig {
|
|
143
|
+
schema: string;
|
|
144
|
+
database: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
interface ColumnMappingStoreUnsafeToSafe {
|
|
148
|
+
[originalColumnName: string]: string;
|
|
149
|
+
}
|
|
150
|
+
type SafeColumnNameConverterFn = (unsafe: string) => string;
|
|
151
|
+
/**
|
|
152
|
+
* This stateful class is to be used to store all the columns names mapping between the "raw" column name
|
|
153
|
+
* found in the records and the destination column in the data warehouse
|
|
154
|
+
*
|
|
155
|
+
* A mapping exists between the fields declared by the Tap and the reality in the Warehouse for those reasons:
|
|
156
|
+
* - Columns that are versionned due to type changes since the last load
|
|
157
|
+
* - Columns that have a name conflict after "Warehouse" sanitization
|
|
158
|
+
*/
|
|
159
|
+
declare class RenameColumnStore {
|
|
160
|
+
private renamedColumns;
|
|
161
|
+
private safeColumnNameConverter?;
|
|
162
|
+
constructor();
|
|
163
|
+
setSafeColumnNameConverter: (fn: SafeColumnNameConverterFn) => void;
|
|
164
|
+
computeColumnNameForStream: (streamId: string, flattenedSchema: FlattenedSchema) => void;
|
|
165
|
+
getColumnTranslation: (streamId: string, originalColumnName: string) => string;
|
|
166
|
+
getUnsafeToSafeColumnMapping: (streamId: string) => ColumnMappingStoreUnsafeToSafe;
|
|
167
|
+
isReady: (streamId: string) => boolean;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
declare abstract class StreamWarehouseSyncService {
|
|
171
|
+
streamId: StreamId;
|
|
172
|
+
database: string;
|
|
173
|
+
schema: string;
|
|
174
|
+
table: string;
|
|
175
|
+
flattenedSchema: FlattenedSchema;
|
|
176
|
+
primaryKeys: string[];
|
|
177
|
+
maxRetryCount: number;
|
|
178
|
+
renamedColumnStore: RenameColumnStore;
|
|
179
|
+
constructor(streamId: StreamId, database: string, schema: string, table: string, renameColumnStore: RenameColumnStore);
|
|
180
|
+
abstract safeColumnName: (unsafe: string) => string;
|
|
181
|
+
abstract getWarehouseTypeFromJSONSchema: (definition: JSONSchemaFieldDefinition) => string | undefined;
|
|
182
|
+
getcolumnNameWithTypeSuffix(colName: string, warehouseType: string | undefined): string;
|
|
183
|
+
abstract getMergeQueries: () => string[];
|
|
184
|
+
abstract getReplaceQueries: () => string[];
|
|
185
|
+
abstract createDatabaseAndSchemaIfNotExists: (retryCount: number) => Promise<void>;
|
|
186
|
+
abstract createTable: () => Promise<void>;
|
|
187
|
+
abstract addColumns: (fields: InternalTableField[]) => Promise<void>;
|
|
188
|
+
abstract createStagingArea: () => Promise<void>;
|
|
189
|
+
abstract loadStreamInStagingArea: (localFilePath: string) => Promise<void>;
|
|
190
|
+
abstract deleteStagingArea: () => Promise<void>;
|
|
191
|
+
abstract getTablesInSchema: () => Promise<{
|
|
192
|
+
tableName: string;
|
|
193
|
+
}[]>;
|
|
194
|
+
abstract getTableColumnsFromWarehouse: () => Promise<WarehouseTableField[]>;
|
|
195
|
+
abstract runQueries: (queries: string[]) => Promise<void>;
|
|
196
|
+
abstract getSerializedRecord: (record: any) => string;
|
|
197
|
+
updateSchemaInWarehouse: (flattenedSchema: FlattenedSchema, primaryKeys: string[]) => Promise<void>;
|
|
198
|
+
renameColumns(record: any): any;
|
|
199
|
+
protected runQueriesWithRetry: (queries: string[]) => Promise<void>;
|
|
200
|
+
private syncTableSchemaWithWarehouse;
|
|
201
|
+
/**
|
|
202
|
+
* When there is a conflict between the synced data type and the data type of an
|
|
203
|
+
* already existing column in the Warehouse, this create a new column in Warehouse with the new
|
|
204
|
+
* datatype as suffix.
|
|
205
|
+
*
|
|
206
|
+
* This refer the fact that data should now be synced with the new column.
|
|
207
|
+
*
|
|
208
|
+
* @param tableFields
|
|
209
|
+
*/
|
|
210
|
+
private addVersionedColumns;
|
|
211
|
+
private updateTableColumns;
|
|
212
|
+
mergeTempTableWithDestination: (replicationMethod: ReplicationMethod) => Promise<void>;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
declare class StreamState$1 {
|
|
216
|
+
streamId: StreamId;
|
|
217
|
+
schema?: FlattenedSchema;
|
|
218
|
+
dbSync: StreamWarehouseSyncService;
|
|
219
|
+
batchDate: moment.Moment;
|
|
220
|
+
batchedRowCount: number;
|
|
221
|
+
fileToLoad: TempFile;
|
|
222
|
+
syncedRowCount: number;
|
|
223
|
+
keyProperties: string[];
|
|
224
|
+
_hasBeenLoadedYetDuringThisSync: boolean;
|
|
225
|
+
replicationMethod: ReplicationMethod;
|
|
226
|
+
constructor(streamId: StreamId, dbSync: StreamWarehouseSyncService, replicationMethod: ReplicationMethod);
|
|
227
|
+
setSchema(schema: FlattenedSchema): void;
|
|
228
|
+
getSchema(): FlattenedSchema | undefined;
|
|
229
|
+
getBatchDate(): string;
|
|
230
|
+
getBatchedRowCount(): number;
|
|
231
|
+
incrementBatchedRowCount(): void;
|
|
232
|
+
getFileToLoad(): TempFile;
|
|
233
|
+
resetFileToLoad(): void;
|
|
234
|
+
getKeyProperties(): string[];
|
|
235
|
+
setKeyProperties(keyProperties: string[]): void;
|
|
236
|
+
getDbSync(): StreamWarehouseSyncService;
|
|
237
|
+
getReplicationMethod(): ReplicationMethod;
|
|
238
|
+
setReplicationMethod(r: ReplicationMethod): void;
|
|
239
|
+
setHasBeenLoadedYet(): void;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
declare abstract class ITarget<C extends BaseConfig = BaseConfig> {
|
|
243
|
+
config: C;
|
|
244
|
+
schemaHooks: TargetSchemaHook[];
|
|
245
|
+
resolver: Resolver;
|
|
246
|
+
syncTime: moment.Moment;
|
|
247
|
+
batchedState: any;
|
|
248
|
+
flushedState: any;
|
|
249
|
+
renameColumnStore: RenameColumnStore;
|
|
250
|
+
streams: {
|
|
251
|
+
[streamName: string]: StreamState$1;
|
|
252
|
+
};
|
|
253
|
+
validator: Validator;
|
|
254
|
+
constructor(config: C, resolver: Resolver);
|
|
255
|
+
static requiredConfigKeys: string[];
|
|
256
|
+
abstract newDBSyncInstance: (streamId: StreamId, database: string, schema: string, table: string) => StreamWarehouseSyncService;
|
|
257
|
+
abstract genTableName: (streamId: string) => string;
|
|
258
|
+
abstract safeColumnNameConverter: SafeColumnNameConverterFn;
|
|
259
|
+
abstract validateDateRange: (reacord: any, schema: FlattenedSchema) => any;
|
|
260
|
+
abstract convertNumberIntoDecimal: (record: any, schema: FlattenedSchema) => any;
|
|
261
|
+
private analyzeSchemaChanges;
|
|
262
|
+
getSerializedRecord: (streamId: string, record: any) => string;
|
|
263
|
+
record: (message: RecordMessage) => Promise<void>;
|
|
264
|
+
private initStreamStateAndSyncService;
|
|
265
|
+
replicationMethod: (message: ReplicationMethodMessage) => void;
|
|
266
|
+
schema: (message: SchemaMessage) => Promise<void>;
|
|
267
|
+
state: (message: StateMessage) => Promise<void>;
|
|
268
|
+
complete: () => Promise<void>;
|
|
269
|
+
private shouldUploadIntermediateBatch;
|
|
270
|
+
private loadAllStreamsInWarehouse;
|
|
271
|
+
private emitState;
|
|
272
|
+
private uploadStreamsToWarehouse;
|
|
273
|
+
static uploadSingleStreamToWarehouse: (streamState: StreamState$1) => Promise<void>;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
type ReplicationMethod = "INCREMENTAL" | "FULL_TABLE" | "LOG_BASED";
|
|
277
|
+
type SyncFunction<C> = (target: ITarget, catalogStream: CatalogStream, config: C, catalog: Catalog) => Promise<void>;
|
|
278
|
+
type SourceType = `HUBSPOT` | `LAGROWTHMACHINE` | `SEGMENT` | `COHORT` | `AIRTABLE` | `AIRTABLE_OAUTH` | `BUBBLE` | `PIPEDRIVE` | `LINKEDIN_ADS` | `FACEBOOK_ADS` | `SEGMENT` | `SALESFORCE` | `SALESFORCE_SANDBOX` | `RECRUITCRM` | `GOOGLE_SHEETS` | `GOOGLE_ADS` | `GOOGLE_ANALYTICS` | `SLACK` | `STRIPE` | `ORBIT` | `GITHUB_STARS` | `JAFFLE_SHOP` | `POSTGRES` | `PENNYLANE` | `PENNYLANE_REDSHIFT` | `AIRCALL` | `AIRCALL_OAUTH` | `FAST_POSTGRES_FULL_TABLE` | `WOOCOMMERCE`;
|
|
279
|
+
type DestinationType = `GOOGLE_BIGQUERY` | `SNOWFLAKE`;
|
|
280
|
+
interface ShoreConfig {
|
|
281
|
+
command: ShoreCommand;
|
|
282
|
+
destination: DestinationType;
|
|
283
|
+
config: any;
|
|
284
|
+
targetConfig: any;
|
|
285
|
+
state?: any;
|
|
286
|
+
catalog?: CatalogFile;
|
|
287
|
+
}
|
|
288
|
+
type ShoreCommand = "READ" | "DISCOVER";
|
|
289
|
+
type ResolverType = "WHALY" | "LOCAL";
|
|
290
|
+
|
|
291
|
+
type InclusionMode = "available" | "automatic" | "unsupported";
|
|
292
|
+
interface MetadataEntry {
|
|
293
|
+
selected?: boolean;
|
|
294
|
+
"replication-method"?: ReplicationMethod;
|
|
295
|
+
"replication-key"?: string;
|
|
296
|
+
"view-key-properties"?: string[];
|
|
297
|
+
"inclusion"?: InclusionMode;
|
|
298
|
+
"selected-by-default"?: boolean;
|
|
299
|
+
"valid-replication-keys"?: string[];
|
|
300
|
+
"forced-replication-method"?: ReplicationMethod;
|
|
301
|
+
"forced-replication-key"?: string;
|
|
302
|
+
"table-key-properties"?: string[];
|
|
303
|
+
"schema-name"?: string;
|
|
304
|
+
"is-view"?: boolean;
|
|
305
|
+
"row-count"?: number;
|
|
306
|
+
"database-name"?: string;
|
|
307
|
+
"sql-datatype"?: string;
|
|
308
|
+
"whaly-display-label"?: string;
|
|
309
|
+
"whaly-description"?: string;
|
|
310
|
+
"whaly-parent-stream"?: StreamId;
|
|
311
|
+
}
|
|
312
|
+
interface CatalogMetadata {
|
|
313
|
+
breadcrumb: string[];
|
|
314
|
+
metadata: MetadataEntry;
|
|
315
|
+
}
|
|
316
|
+
declare class MetadataMap extends Map<string[], MetadataEntry> {
|
|
317
|
+
private areEquals;
|
|
318
|
+
private findExistingEntry;
|
|
319
|
+
get(key: string[]): MetadataEntry | undefined;
|
|
320
|
+
set(key: string[], value: MetadataEntry): this;
|
|
321
|
+
}
|
|
322
|
+
declare class StreamMetadata {
|
|
323
|
+
metadataByBreadcrumb: MetadataMap;
|
|
324
|
+
constructor();
|
|
325
|
+
fromCatalogStreamMetadata(metadataArr: CatalogMetadata[]): this;
|
|
326
|
+
toString(): MetadataMap;
|
|
327
|
+
get(breadcrumb: string[]): MetadataEntry | undefined;
|
|
328
|
+
write(breadcrumb: string[], key: string, value: any): this;
|
|
329
|
+
private getRootBreadcrumbMetadata;
|
|
330
|
+
isStreamSelected(): boolean;
|
|
331
|
+
getKeyProperties(): string[];
|
|
332
|
+
getReplicationKey(): string | undefined;
|
|
333
|
+
getReplicationMethod(): ReplicationMethod | undefined;
|
|
334
|
+
getForcedReplicationMethod(): ReplicationMethod | undefined;
|
|
335
|
+
toList(): CatalogMetadata[];
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
type StreamId = string;
|
|
339
|
+
type StreamName = string;
|
|
340
|
+
interface CatalogStream {
|
|
341
|
+
tap_stream_id: StreamId;
|
|
342
|
+
stream: StreamName;
|
|
343
|
+
schema: any;
|
|
344
|
+
metadata: CatalogMetadata[];
|
|
345
|
+
}
|
|
346
|
+
interface CatalogFile {
|
|
347
|
+
streams: CatalogStream[];
|
|
348
|
+
}
|
|
349
|
+
declare class Catalog {
|
|
350
|
+
streams?: CatalogStream[];
|
|
351
|
+
static fromFile(fileName: string): Catalog;
|
|
352
|
+
static fromCatalogFile(catalogFile: CatalogFile): Catalog;
|
|
353
|
+
getSelectedStreams(): CatalogStream[];
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
declare const writeStateFile: (resolver: Resolver, state: string) => Promise<void>;
|
|
357
|
+
declare const writeCatalogFile: (resolver: Resolver, catalog: CatalogFile) => Promise<void>;
|
|
358
|
+
declare const loadShoreConfig: (resolver: Resolver) => Promise<ShoreConfig>;
|
|
359
|
+
declare const loadJson: (fileName: string) => any;
|
|
360
|
+
declare const loadSchema: (streamId: string) => any;
|
|
361
|
+
declare const checkRequiredConfigKeys: (args: any, requiredConfigKeys: string[]) => void;
|
|
362
|
+
|
|
363
|
+
declare const getAxiosInstance: (retryCount?: number) => AxiosInstance;
|
|
364
|
+
interface GetConfig {
|
|
365
|
+
qs?: {
|
|
366
|
+
[key: string]: any;
|
|
367
|
+
};
|
|
368
|
+
headers?: AxiosRequestHeaders;
|
|
369
|
+
retryCount?: number;
|
|
370
|
+
}
|
|
371
|
+
declare const getRawJSONApiCall: <T>(endpoint: string, config: GetConfig, privateLogging?: boolean) => Promise<AxiosResponse<T>>;
|
|
372
|
+
declare const getJSONApiCallWithFullResponse: <T>(endpoint: string, config: GetConfig, privateLogging?: boolean) => Promise<AxiosResponse<any, any, {}>>;
|
|
373
|
+
declare const getJSONApiCall: <T>(endpoint: string, config: GetConfig, privateLogging?: boolean) => Promise<T>;
|
|
374
|
+
declare const getDownloadFileApiCall: <T>(endpoint: string, config: GetConfig, output: string, privateLogging?: boolean) => Promise<{
|
|
375
|
+
outputDir: string;
|
|
376
|
+
}>;
|
|
377
|
+
interface PostConfig {
|
|
378
|
+
qs?: {
|
|
379
|
+
[key: string]: any;
|
|
380
|
+
};
|
|
381
|
+
headers?: AxiosRequestHeaders;
|
|
382
|
+
retryCount?: number;
|
|
383
|
+
}
|
|
384
|
+
declare const postJSONApiCall: <T>(endpoint: string, config: PostConfig, payload: any) => Promise<T>;
|
|
385
|
+
declare const postFormDataApiCall: <T>(endpoint: string, config: PostConfig, payload: any) => Promise<T>;
|
|
386
|
+
declare const postUrlEncodedApiCall: (endpoint: string, config: PostConfig, payload: any) => Promise<any>;
|
|
387
|
+
|
|
388
|
+
declare const BATCH_INTERVAL_MS = 100;
|
|
389
|
+
declare const logger: {
|
|
390
|
+
info: (message: string | any, ...args: any[]) => void;
|
|
391
|
+
error: (message: string | any, ...args: any[]) => void;
|
|
392
|
+
debug: (message: string | any, ...args: any[]) => void;
|
|
393
|
+
warn: (message: string | any, ...args: any[]) => void;
|
|
394
|
+
closeWinston: (cb: () => void) => void;
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
declare const ALL_STREAM_ID_KEYWORD = "all";
|
|
398
|
+
declare const ROWS_SYNCED_METRIC_NAME = "rows_synced_count";
|
|
399
|
+
declare const API_CALLS_METRIC_NAME = "api_calls_count";
|
|
400
|
+
declare const EXECUTION_TIME_METRIC_NAME = "execution_time_ms";
|
|
401
|
+
interface MetricConfiguration {
|
|
402
|
+
isEnabled: () => boolean;
|
|
403
|
+
getStreamIds?: () => string[];
|
|
404
|
+
}
|
|
405
|
+
declare const getCounterMetrics: (name: string, streamIds: string[]) => CounterMetric[];
|
|
406
|
+
declare const getCounterMetric: (name: string, streamId?: string) => CounterMetric;
|
|
407
|
+
declare const getAllMetrics: () => CounterMetric[];
|
|
408
|
+
declare class CounterMetric {
|
|
409
|
+
private value;
|
|
410
|
+
name: string;
|
|
411
|
+
streamId: string;
|
|
412
|
+
constructor(name: string, streamId: string);
|
|
413
|
+
increment(inc?: number): void;
|
|
414
|
+
getStreamId(): string;
|
|
415
|
+
getName(): string;
|
|
416
|
+
getValue(): number;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
declare const printMemoryFootprint: (prefix: string) => void;
|
|
420
|
+
|
|
421
|
+
declare const haltAndCatchFire: (errorType: ErrorType, errorText: string, errorDebugText: string) => Promise<void>;
|
|
422
|
+
|
|
423
|
+
declare function gracefulExit(exitCode: number): Promise<void>;
|
|
424
|
+
|
|
425
|
+
declare const findRelatedRelationships: (streamId: StreamId, allRels: StreamRelationship[]) => DirectionalRelationships;
|
|
426
|
+
|
|
427
|
+
interface HTTPHeaders {
|
|
428
|
+
[headerName: string]: any;
|
|
429
|
+
}
|
|
430
|
+
interface URLParams {
|
|
431
|
+
[paramName: string]: any;
|
|
432
|
+
}
|
|
433
|
+
type HTTPMethod = "GET" | "POST";
|
|
434
|
+
|
|
435
|
+
interface InputTapState {
|
|
436
|
+
bookmarks?: {
|
|
437
|
+
[streamId: string]: StreamState;
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
interface TapState {
|
|
441
|
+
bookmarks: {
|
|
442
|
+
[streamId: string]: StreamState;
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
interface Bookmark {
|
|
446
|
+
replicationKey?: string;
|
|
447
|
+
replicationKeyValue?: string;
|
|
448
|
+
}
|
|
449
|
+
interface StreamState extends Bookmark {
|
|
450
|
+
progressMarkers?: ProgressMarkers;
|
|
451
|
+
replicationKeySignpost?: string;
|
|
452
|
+
}
|
|
453
|
+
interface ProgressMarkers extends Bookmark {
|
|
454
|
+
Note?: string;
|
|
455
|
+
}
|
|
456
|
+
interface State {
|
|
457
|
+
bookmarks: Bookmarks;
|
|
458
|
+
}
|
|
459
|
+
interface Bookmarks {
|
|
460
|
+
[streamId: string]: any;
|
|
461
|
+
}
|
|
462
|
+
declare const incrementStreamState: (state: StreamState, replicationKey: string, latestRecord: any, isSorted: boolean) => StreamState;
|
|
463
|
+
/**
|
|
464
|
+
* Promote or wipe progress markers once sync is complete."""
|
|
465
|
+
|
|
466
|
+
* @param state
|
|
467
|
+
* @returns
|
|
468
|
+
*/
|
|
469
|
+
declare const finalizeStateProgressMarkers: (state: StreamState) => StreamState;
|
|
470
|
+
declare const _greaterThan: (aValue: string, bValue: string) => boolean;
|
|
471
|
+
declare const extractStateForStream: (state: InputTapState, streamId: StreamId) => StreamState;
|
|
472
|
+
declare class StateService {
|
|
473
|
+
private static instance;
|
|
474
|
+
bookmarks: Bookmarks;
|
|
475
|
+
constructor();
|
|
476
|
+
static getInstance(): StateService;
|
|
477
|
+
setBookmark(streamId: StreamId, ts: moment.Moment): void;
|
|
478
|
+
setBookmarkV2(streamId: StreamId, streamState: StreamState): void;
|
|
479
|
+
setBookmarkSignpostV2(streamId: StreamId, signpostValue: string): void;
|
|
480
|
+
getBookmark(streamId: StreamId): moment.Moment;
|
|
481
|
+
getBookmarkV2(streamId: StreamId): StreamState;
|
|
482
|
+
clearState(): void;
|
|
483
|
+
get(): State;
|
|
484
|
+
forwardStateToTarget(target: ITarget): Promise<void>;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* C: The type of the tap config
|
|
489
|
+
*/
|
|
490
|
+
declare class Authenticator<C> {
|
|
491
|
+
getAuthHeaders(config: C): Promise<HTTPHeaders>;
|
|
492
|
+
getAuthQS(config: C): Promise<URLParams>;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* TODO: Handle non timestamp based replication key
|
|
497
|
+
*
|
|
498
|
+
* O: Type of a resulted row after post processing
|
|
499
|
+
* C: Type of the tap configuration
|
|
500
|
+
* P: For children Streams, this is the type of the parent
|
|
501
|
+
*/
|
|
502
|
+
declare abstract class StreamV2<O = any, C = any, P = undefined> {
|
|
503
|
+
_config: C;
|
|
504
|
+
_tapName: string;
|
|
505
|
+
_tapState: InputTapState;
|
|
506
|
+
_target: ITarget;
|
|
507
|
+
rootMetadataEntry: MetadataEntry | undefined;
|
|
508
|
+
forcedReplicationMethod: ReplicationMethod | undefined;
|
|
509
|
+
selectedByDefault: boolean;
|
|
510
|
+
STATE_MSG_FREQUENCY: number;
|
|
511
|
+
streamId: StreamId;
|
|
512
|
+
schemaPath: string | undefined;
|
|
513
|
+
displayLabel: string | undefined;
|
|
514
|
+
description: string | undefined;
|
|
515
|
+
primaryKey: string[];
|
|
516
|
+
forcedReplicationKey: string | undefined;
|
|
517
|
+
useStateFromStreamId: string | undefined;
|
|
518
|
+
relationships: StreamRelationship[];
|
|
519
|
+
children: StreamV2<any, any, O | O[]>[];
|
|
520
|
+
isSorted: boolean;
|
|
521
|
+
isSilent: boolean;
|
|
522
|
+
childConcurrency: number;
|
|
523
|
+
rowsSyncedMetricsConf: MetricConfiguration;
|
|
524
|
+
executionTimeMetricsConf: MetricConfiguration;
|
|
525
|
+
constructor(tapName: string, config: C, state: InputTapState, target: ITarget, childConcurrency?: number);
|
|
526
|
+
setRootMetadataEntry: (rootMetadataEntry: MetadataEntry) => void;
|
|
527
|
+
/**
|
|
528
|
+
* Sync this stream
|
|
529
|
+
* Called only for streams with no parents, aka. "root tap streams"
|
|
530
|
+
* @returns
|
|
531
|
+
*/
|
|
532
|
+
sync: () => Promise<void>;
|
|
533
|
+
flush: () => Promise<void>;
|
|
534
|
+
/**
|
|
535
|
+
* Write out a STATE message with the latest state.
|
|
536
|
+
*/
|
|
537
|
+
_writeStateMessage: () => Promise<void>;
|
|
538
|
+
/**
|
|
539
|
+
* Write out a ACTIVATE_VERSION message.
|
|
540
|
+
*/
|
|
541
|
+
_writeReplicationMethodMessage: () => Promise<void>;
|
|
542
|
+
/**
|
|
543
|
+
* Write out a SCHEMA message with the stream schema.
|
|
544
|
+
*/
|
|
545
|
+
_writeSchemaMessage: (skipChildrenSchema?: boolean) => Promise<void>;
|
|
546
|
+
_writeSignpostInState: () => Promise<void>;
|
|
547
|
+
/**
|
|
548
|
+
* Update state of stream with data from the provided record.
|
|
549
|
+
*/
|
|
550
|
+
_incrementStreamState: (latestRecord: O) => void;
|
|
551
|
+
/**
|
|
552
|
+
* Return True if the stream uses a timestamp-based replication key.
|
|
553
|
+
*
|
|
554
|
+
* Developers can override with `is_timestamp_replication_key = True` in
|
|
555
|
+
order to force this value.
|
|
556
|
+
*/
|
|
557
|
+
isTimestampReplicationKey: () => Promise<boolean>;
|
|
558
|
+
/**
|
|
559
|
+
* Return state timestamp if set for the stream,
|
|
560
|
+
* or `start_date` config if set,
|
|
561
|
+
* or the UNIX Epoch
|
|
562
|
+
**/
|
|
563
|
+
getStartingTimestamp(): moment.Moment;
|
|
564
|
+
/**
|
|
565
|
+
* Return the max allowable bookmark value for this stream's replication key.
|
|
566
|
+
*
|
|
567
|
+
* For timestamp-based replication keys, this defaults to `moment()`. For
|
|
568
|
+
* non-timestamp replication keys, default to `undefined`.
|
|
569
|
+
*
|
|
570
|
+
* Override this value to prevent bookmarks from being advanced in cases where we
|
|
571
|
+
* may only have a partial set of records.
|
|
572
|
+
*/
|
|
573
|
+
getReplicationKeySignpost: () => Promise<moment.Moment | undefined>;
|
|
574
|
+
/**
|
|
575
|
+
* Return the default replication method for the stream that will be used to write the catalog.
|
|
576
|
+
*/
|
|
577
|
+
defaultReplicationConfig: () => {
|
|
578
|
+
replicationMethod: ReplicationMethod;
|
|
579
|
+
replicationKey: string | undefined;
|
|
580
|
+
isForced: boolean;
|
|
581
|
+
};
|
|
582
|
+
/**
|
|
583
|
+
* Return the configured replication method that will be used for the sync.
|
|
584
|
+
*/
|
|
585
|
+
configuredReplicationConfig: () => {
|
|
586
|
+
replicationMethod: ReplicationMethod;
|
|
587
|
+
replicationKey: string | undefined;
|
|
588
|
+
};
|
|
589
|
+
_syncRecords(parent?: P): Promise<void>;
|
|
590
|
+
asyncInit(parent?: P): Promise<void>;
|
|
591
|
+
/**
|
|
592
|
+
* Return the stream schema.
|
|
593
|
+
*
|
|
594
|
+
* Can be overriden to return a dynamic schema
|
|
595
|
+
*/
|
|
596
|
+
getSchema(): Promise<Schema | undefined>;
|
|
597
|
+
getRowCount(): Promise<number | undefined>;
|
|
598
|
+
/**
|
|
599
|
+
* Abstract row generator function. Must be overridden by the child class.
|
|
600
|
+
*/
|
|
601
|
+
_getRecords(parent?: P): AsyncIterable<O>;
|
|
602
|
+
/**
|
|
603
|
+
* Return the list of keys that can be configured in the UI by the end user as the replication key
|
|
604
|
+
* @returns
|
|
605
|
+
*/
|
|
606
|
+
getValidReplicationKeys(): Promise<string[]>;
|
|
607
|
+
/**
|
|
608
|
+
* Called at the end of the sync. Use to flush all records before closing the Stream.
|
|
609
|
+
* @returns
|
|
610
|
+
*/
|
|
611
|
+
_flush(): Promise<void>;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/**
|
|
615
|
+
* R: Type of the API result
|
|
616
|
+
* NPT: Type of the "nextPageToken"
|
|
617
|
+
*/
|
|
618
|
+
declare abstract class RESTStreamV2<R, O, NPT, C, P = undefined> extends StreamV2<O, C, P> {
|
|
619
|
+
axiosInstance: AxiosInstance | undefined;
|
|
620
|
+
constructor(tapName: string, config: C, state: InputTapState, target: ITarget, childConcurrency?: number);
|
|
621
|
+
/**
|
|
622
|
+
* Prepare an Axios request object.
|
|
623
|
+
* Pagination information can be parsed from `nextPageToken` if `nextPageToken` is not undefined.
|
|
624
|
+
* @param nextPageToken
|
|
625
|
+
* @returns
|
|
626
|
+
*/
|
|
627
|
+
_prepareRequest: (nextPageToken: NPT | undefined, parent?: P) => Promise<AxiosRequestConfig>;
|
|
628
|
+
_requestWithRetry(request: AxiosRequestConfig, privateLogging?: boolean): Promise<R | "STOP_SYNC">;
|
|
629
|
+
_requestRecords(parent?: P): AsyncIterable<O>;
|
|
630
|
+
_getRecords(parent?: P): AsyncIterable<O>;
|
|
631
|
+
httpMethod: HTTPMethod;
|
|
632
|
+
baseUrl: string;
|
|
633
|
+
path: string;
|
|
634
|
+
httpRetryCount: number;
|
|
635
|
+
authenticator?: Authenticator<C>;
|
|
636
|
+
apiCallsMetricsConf: MetricConfiguration;
|
|
637
|
+
httpErrorHandler(url: string | undefined, err: AxiosError): Promise<R | undefined>;
|
|
638
|
+
/**
|
|
639
|
+
* Return a dictionary of values to be used in URL parameterization.
|
|
640
|
+
* If paging is supported, developers may override with specific paging logic.
|
|
641
|
+
*
|
|
642
|
+
* By default, no params are passed.
|
|
643
|
+
*/
|
|
644
|
+
getNextUrlParams(nextPageToken: NPT | undefined, parent?: P): URLParams;
|
|
645
|
+
/**
|
|
646
|
+
* Prepare the data payload for the REST API request.
|
|
647
|
+
* Useful when working with POST APIs.
|
|
648
|
+
*
|
|
649
|
+
* By default, no payload will be sent (return undefined).
|
|
650
|
+
*/
|
|
651
|
+
getRequestBodyForNextCall(nextPageToken: NPT | undefined, parent?: P): any;
|
|
652
|
+
/**
|
|
653
|
+
* Return token identifying next page or undefined if all records have been read.
|
|
654
|
+
*
|
|
655
|
+
* By default, no token will be returned and a single API call will be made.
|
|
656
|
+
*
|
|
657
|
+
* @param response
|
|
658
|
+
* @param previousToken
|
|
659
|
+
* @returns
|
|
660
|
+
*/
|
|
661
|
+
getNextPageToken(response: R, previousToken?: NPT): NPT | undefined;
|
|
662
|
+
/**
|
|
663
|
+
* Return custom headers to be used for HTTP requests.
|
|
664
|
+
*
|
|
665
|
+
* By default, no additional header will be added
|
|
666
|
+
*/
|
|
667
|
+
getCustomHTTPHeaders(parent?: P): HTTPHeaders | undefined;
|
|
668
|
+
/**
|
|
669
|
+
* Return a URL, optionally targeted to a specific partition.
|
|
670
|
+
* This can be overriden to perform dynamic URL generation.
|
|
671
|
+
*
|
|
672
|
+
* TODO: Make URL + Path templatisable and replace those with Extractor (or Tap) config
|
|
673
|
+
* @returns
|
|
674
|
+
*/
|
|
675
|
+
getUrl(parent?: P): string;
|
|
676
|
+
/**
|
|
677
|
+
* Parse the response and return an iterator of result rows.
|
|
678
|
+
*
|
|
679
|
+
* Default impl assume that R = O or R = O[]
|
|
680
|
+
* @param response
|
|
681
|
+
*/
|
|
682
|
+
parseResponse(response: R, parent?: P, nextPageToken?: NPT): AsyncIterable<O>;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
declare const DEFAULT_MAX_CONCURRENT_STREAMS = 5;
|
|
686
|
+
declare abstract class Tap<C> {
|
|
687
|
+
_target: ITarget;
|
|
688
|
+
_config: C;
|
|
689
|
+
_streams: StreamV2[];
|
|
690
|
+
_concurrency: number;
|
|
691
|
+
abstract init(): Promise<void>;
|
|
692
|
+
abstract requiredConfigKeys(): string[];
|
|
693
|
+
constructor(target: ITarget, config: C);
|
|
694
|
+
discover: (existingCatalog: CatalogFile | undefined) => Promise<CatalogFile>;
|
|
695
|
+
sync: (catalog: Catalog) => Promise<void>;
|
|
696
|
+
generateMetadataFromStream(stream: StreamV2, parentStreamId: string | undefined): Promise<{
|
|
697
|
+
metadata: CatalogMetadata[];
|
|
698
|
+
}>;
|
|
699
|
+
initiateSync(catalog: Catalog): Promise<void>;
|
|
700
|
+
end(): Promise<void>;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
declare class SchemaValidationError extends Error {
|
|
704
|
+
streamId: StreamId;
|
|
705
|
+
validationErrors: ValidationError[];
|
|
706
|
+
constructor(message: string, streamId: StreamId, errors: ValidationError[]);
|
|
707
|
+
}
|
|
708
|
+
declare class MissingFieldInSchemaError extends Error {
|
|
709
|
+
streamId: StreamId;
|
|
710
|
+
constructor(message: string, streamId: StreamId);
|
|
711
|
+
}
|
|
712
|
+
declare class MissingSchemaError extends Error {
|
|
713
|
+
streamId: StreamId;
|
|
714
|
+
constructor(message: string, streamId: StreamId);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
declare const removeParasiteProperties: (record: any, schema: FlattenedSchema) => any;
|
|
718
|
+
declare const addWhalyFields: (record: any, batchDate: string) => any;
|
|
719
|
+
|
|
720
|
+
declare const flattenSchema: <T>(streamId: StreamId, schema: T) => FlattenedSchema;
|
|
721
|
+
|
|
722
|
+
declare const createTemporaryFileStream: (streamId: StreamId) => TempFile;
|
|
723
|
+
declare function safePath(path: string): string;
|
|
724
|
+
|
|
725
|
+
export { ALL_STREAM_ID_KEYWORD, API_CALLS_METRIC_NAME, Authenticator, BATCH_INTERVAL_MS, type BaseConfig, type Bookmark, type Bookmarks, Catalog, type CatalogFile, type CatalogMetadata, type CatalogStream, type ColumnMappingStoreUnsafeToSafe, CounterMetric, DEFAULT_MAX_CONCURRENT_STREAMS, type DestinationType, type DirectionalRelationship, type DirectionalRelationships, EXECUTION_TIME_METRIC_NAME, type ErrorType, type FlattenedSchema, type GetConfig, type HTTPHeaders, type HTTPMethod, ITarget, type InclusionMode, type InputTapState, type InternalTableField, type JSONSchemaFieldDefinition, type Message, type MessageType, type MetadataEntry, type MetricConfiguration, MissingFieldInSchemaError, MissingSchemaError, type PostConfig, type ProgressMarkers, type PropertiesMetadata, RESTStreamV2, ROWS_SYNCED_METRIC_NAME, RecordMessage, RenameColumnStore, type ReplicationMethod, ReplicationMethodMessage, Resolver, type ResolverType, type SafeColumnNameConverterFn, type Schema, SchemaMessage, SchemaValidationError, type ShoreCommand, type ShoreConfig, type SourceType, type State, StateMessage, StateService, type StreamId, StreamMetadata, type StreamName, type StreamRelationship, type StreamState, StreamV2, StreamWarehouseSyncService, type StreamWithTempFile, type SyncFunction, Tap, type TapState, type TargetSchemaHook, type TargetSchemaHookInput, type TempFile, type URLParams, type WarehouseTableField, _greaterThan, addWhalyFields, checkRequiredConfigKeys, createTemporaryFileStream, extractStateForStream, finalizeStateProgressMarkers, findRelatedRelationships, flattenSchema, getAllMetrics, getAxiosInstance, getCounterMetric, getCounterMetrics, getDownloadFileApiCall, getJSONApiCall, getJSONApiCallWithFullResponse, getRawJSONApiCall, gracefulExit, haltAndCatchFire, incrementStreamState, loadJson, loadSchema, loadShoreConfig, logger, postFormDataApiCall, postJSONApiCall, postUrlEncodedApiCall, printMemoryFootprint, removeParasiteProperties, safePath, writeCatalogFile, writeStateFile };
|