@hazeljs/data 0.2.4 → 0.3.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.
Files changed (33) hide show
  1. package/dist/connectors/__tests__/jsonl.connector.test.d.ts +2 -0
  2. package/dist/connectors/__tests__/jsonl.connector.test.d.ts.map +1 -0
  3. package/dist/connectors/__tests__/jsonl.connector.test.js +261 -0
  4. package/dist/connectors/jsonl.connector.d.ts +51 -0
  5. package/dist/connectors/jsonl.connector.d.ts.map +1 -0
  6. package/dist/connectors/jsonl.connector.js +100 -0
  7. package/dist/connectors/postgres.connector.d.ts +78 -0
  8. package/dist/connectors/postgres.connector.d.ts.map +1 -0
  9. package/dist/connectors/postgres.connector.js +224 -0
  10. package/dist/contracts/__tests__/contract-registry.test.d.ts +2 -0
  11. package/dist/contracts/__tests__/contract-registry.test.d.ts.map +1 -0
  12. package/dist/contracts/__tests__/contract-registry.test.js +770 -0
  13. package/dist/contracts/__tests__/contract.decorator.test.d.ts +2 -0
  14. package/dist/contracts/__tests__/contract.decorator.test.d.ts.map +1 -0
  15. package/dist/contracts/__tests__/contract.decorator.test.js +177 -0
  16. package/dist/contracts/contract-registry.d.ts +57 -0
  17. package/dist/contracts/contract-registry.d.ts.map +1 -0
  18. package/dist/contracts/contract-registry.js +285 -0
  19. package/dist/contracts/contract.decorator.d.ts +70 -0
  20. package/dist/contracts/contract.decorator.d.ts.map +1 -0
  21. package/dist/contracts/contract.decorator.js +55 -0
  22. package/dist/contracts/contract.types.d.ts +65 -0
  23. package/dist/contracts/contract.types.d.ts.map +1 -0
  24. package/dist/contracts/contract.types.js +5 -0
  25. package/dist/contracts/index.d.ts +9 -0
  26. package/dist/contracts/index.d.ts.map +1 -0
  27. package/dist/contracts/index.js +16 -0
  28. package/dist/index.d.ts +3 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +14 -2
  31. package/dist/testing/schema-faker.test.js +33 -0
  32. package/dist/transformers/transformer.service.test.js +40 -0
  33. package/package.json +2 -2
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=jsonl.connector.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl.connector.test.d.ts","sourceRoot":"","sources":["../../../src/connectors/__tests__/jsonl.connector.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const jsonl_connector_1 = require("../jsonl.connector");
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const TEST_DIR = (0, path_1.join)(__dirname, '__test_data__');
7
+ const TEST_FILE = (0, path_1.join)(TEST_DIR, 'test.jsonl');
8
+ const OUTPUT_FILE = (0, path_1.join)(TEST_DIR, 'output.jsonl');
9
+ describe('JsonlSource', () => {
10
+ beforeAll(() => {
11
+ if (!(0, fs_1.existsSync)(TEST_DIR)) {
12
+ (0, fs_1.mkdirSync)(TEST_DIR, { recursive: true });
13
+ }
14
+ });
15
+ afterAll(() => {
16
+ if ((0, fs_1.existsSync)(TEST_DIR)) {
17
+ (0, fs_1.rmSync)(TEST_DIR, { recursive: true, force: true });
18
+ }
19
+ });
20
+ beforeEach(() => {
21
+ // Clean up test files
22
+ [TEST_FILE, OUTPUT_FILE].forEach((file) => {
23
+ if ((0, fs_1.existsSync)(file)) {
24
+ (0, fs_1.unlinkSync)(file);
25
+ }
26
+ });
27
+ });
28
+ describe('constructor', () => {
29
+ it('should create source with default name', () => {
30
+ const source = new jsonl_connector_1.JsonlSource({ filePath: TEST_FILE });
31
+ expect(source.name).toBe(`jsonl:${TEST_FILE}`);
32
+ });
33
+ it('should create source with custom name', () => {
34
+ const source = new jsonl_connector_1.JsonlSource({ filePath: TEST_FILE, name: 'custom-source' });
35
+ expect(source.name).toBe('custom-source');
36
+ });
37
+ });
38
+ describe('open', () => {
39
+ it('should throw error if file does not exist', async () => {
40
+ const source = new jsonl_connector_1.JsonlSource({ filePath: TEST_FILE });
41
+ await expect(source.open()).rejects.toThrow('JSONL file not found');
42
+ });
43
+ it('should open successfully if file exists', async () => {
44
+ (0, fs_1.writeFileSync)(TEST_FILE, '{"id": 1}\n');
45
+ const source = new jsonl_connector_1.JsonlSource({ filePath: TEST_FILE });
46
+ await expect(source.open()).resolves.toBeUndefined();
47
+ });
48
+ });
49
+ describe('close', () => {
50
+ it('should close without error', async () => {
51
+ (0, fs_1.writeFileSync)(TEST_FILE, '{"id": 1}\n');
52
+ const source = new jsonl_connector_1.JsonlSource({ filePath: TEST_FILE });
53
+ await source.open();
54
+ await expect(source.close()).resolves.toBeUndefined();
55
+ });
56
+ });
57
+ describe('read', () => {
58
+ it('should read records from JSONL file', async () => {
59
+ const data = [
60
+ { id: 1, name: 'Alice' },
61
+ { id: 2, name: 'Bob' },
62
+ { id: 3, name: 'Charlie' },
63
+ ];
64
+ (0, fs_1.writeFileSync)(TEST_FILE, data.map((d) => JSON.stringify(d)).join('\n'));
65
+ const source = new jsonl_connector_1.JsonlSource({ filePath: TEST_FILE });
66
+ await source.open();
67
+ const records = [];
68
+ for await (const record of source.read()) {
69
+ records.push(record);
70
+ }
71
+ expect(records).toHaveLength(3);
72
+ expect(records[0]).toEqual({ id: 1, name: 'Alice' });
73
+ expect(records[1]).toEqual({ id: 2, name: 'Bob' });
74
+ expect(records[2]).toEqual({ id: 3, name: 'Charlie' });
75
+ await source.close();
76
+ });
77
+ it('should skip empty lines', async () => {
78
+ const content = '{"id": 1}\n\n{"id": 2}\n \n{"id": 3}\n';
79
+ (0, fs_1.writeFileSync)(TEST_FILE, content);
80
+ const source = new jsonl_connector_1.JsonlSource({ filePath: TEST_FILE });
81
+ await source.open();
82
+ const records = [];
83
+ for await (const record of source.read()) {
84
+ records.push(record);
85
+ }
86
+ expect(records).toHaveLength(3);
87
+ await source.close();
88
+ });
89
+ it('should throw error for invalid JSON', async () => {
90
+ (0, fs_1.writeFileSync)(TEST_FILE, '{"id": 1}\n{invalid json}\n{"id": 3}\n');
91
+ const source = new jsonl_connector_1.JsonlSource({ filePath: TEST_FILE });
92
+ await source.open();
93
+ await expect(async () => {
94
+ for await (const record of source.read()) {
95
+ // Process records
96
+ void record;
97
+ }
98
+ }).rejects.toThrow('Failed to parse JSONL line');
99
+ await source.close();
100
+ });
101
+ it('should handle empty file', async () => {
102
+ (0, fs_1.writeFileSync)(TEST_FILE, '');
103
+ const source = new jsonl_connector_1.JsonlSource({ filePath: TEST_FILE });
104
+ await source.open();
105
+ const records = [];
106
+ for await (const record of source.read()) {
107
+ records.push(record);
108
+ }
109
+ expect(records).toHaveLength(0);
110
+ await source.close();
111
+ });
112
+ });
113
+ describe('readAll', () => {
114
+ it('should read all records at once', async () => {
115
+ const data = [
116
+ { id: 1, value: 'a' },
117
+ { id: 2, value: 'b' },
118
+ ];
119
+ (0, fs_1.writeFileSync)(TEST_FILE, data.map((d) => JSON.stringify(d)).join('\n'));
120
+ const source = new jsonl_connector_1.JsonlSource({ filePath: TEST_FILE });
121
+ await source.open();
122
+ const records = await source.readAll();
123
+ expect(records).toHaveLength(2);
124
+ expect(records[0]).toEqual({ id: 1, value: 'a' });
125
+ expect(records[1]).toEqual({ id: 2, value: 'b' });
126
+ await source.close();
127
+ });
128
+ });
129
+ });
130
+ describe('JsonlSink', () => {
131
+ beforeAll(() => {
132
+ if (!(0, fs_1.existsSync)(TEST_DIR)) {
133
+ (0, fs_1.mkdirSync)(TEST_DIR, { recursive: true });
134
+ }
135
+ });
136
+ afterAll(() => {
137
+ if ((0, fs_1.existsSync)(TEST_DIR)) {
138
+ (0, fs_1.rmSync)(TEST_DIR, { recursive: true, force: true });
139
+ }
140
+ });
141
+ beforeEach(() => {
142
+ [TEST_FILE, OUTPUT_FILE].forEach((file) => {
143
+ if ((0, fs_1.existsSync)(file)) {
144
+ (0, fs_1.unlinkSync)(file);
145
+ }
146
+ });
147
+ });
148
+ describe('constructor', () => {
149
+ it('should create sink with default name', () => {
150
+ const sink = new jsonl_connector_1.JsonlSink({ filePath: OUTPUT_FILE });
151
+ expect(sink.name).toBe(`jsonl:${OUTPUT_FILE}`);
152
+ });
153
+ it('should create sink with custom name', () => {
154
+ const sink = new jsonl_connector_1.JsonlSink({ filePath: OUTPUT_FILE, name: 'custom-sink' });
155
+ expect(sink.name).toBe('custom-sink');
156
+ });
157
+ });
158
+ describe('open', () => {
159
+ it('should create write stream', async () => {
160
+ const sink = new jsonl_connector_1.JsonlSink({ filePath: OUTPUT_FILE });
161
+ await expect(sink.open()).resolves.toBeUndefined();
162
+ await sink.close();
163
+ });
164
+ });
165
+ describe('write', () => {
166
+ it('should write single record', async () => {
167
+ const sink = new jsonl_connector_1.JsonlSink({ filePath: OUTPUT_FILE });
168
+ await sink.open();
169
+ await sink.write({ id: 1, name: 'Test' });
170
+ await sink.close();
171
+ const source = new jsonl_connector_1.JsonlSource({ filePath: OUTPUT_FILE });
172
+ await source.open();
173
+ const records = await source.readAll();
174
+ await source.close();
175
+ expect(records).toHaveLength(1);
176
+ expect(records[0]).toEqual({ id: 1, name: 'Test' });
177
+ });
178
+ it('should throw error if not opened', async () => {
179
+ const sink = new jsonl_connector_1.JsonlSink({ filePath: OUTPUT_FILE });
180
+ await expect(sink.write({ id: 1 })).rejects.toThrow('call open() before write()');
181
+ });
182
+ it('should write multiple records sequentially', async () => {
183
+ const sink = new jsonl_connector_1.JsonlSink({ filePath: OUTPUT_FILE });
184
+ await sink.open();
185
+ await sink.write({ id: 1 });
186
+ await sink.write({ id: 2 });
187
+ await sink.write({ id: 3 });
188
+ await sink.close();
189
+ const source = new jsonl_connector_1.JsonlSource({ filePath: OUTPUT_FILE });
190
+ await source.open();
191
+ const records = await source.readAll();
192
+ await source.close();
193
+ expect(records).toHaveLength(3);
194
+ });
195
+ });
196
+ describe('writeBatch', () => {
197
+ it('should write batch of records', async () => {
198
+ const sink = new jsonl_connector_1.JsonlSink({ filePath: OUTPUT_FILE });
199
+ await sink.open();
200
+ const records = [
201
+ { id: 1, name: 'Alice' },
202
+ { id: 2, name: 'Bob' },
203
+ { id: 3, name: 'Charlie' },
204
+ ];
205
+ await sink.writeBatch(records);
206
+ await sink.close();
207
+ const source = new jsonl_connector_1.JsonlSource({ filePath: OUTPUT_FILE });
208
+ await source.open();
209
+ const readRecords = await source.readAll();
210
+ await source.close();
211
+ expect(readRecords).toHaveLength(3);
212
+ expect(readRecords).toEqual(records);
213
+ });
214
+ it('should throw error if not opened', async () => {
215
+ const sink = new jsonl_connector_1.JsonlSink({ filePath: OUTPUT_FILE });
216
+ await expect(sink.writeBatch([{ id: 1 }])).rejects.toThrow('call open() before writeBatch()');
217
+ });
218
+ it('should handle empty batch', async () => {
219
+ const sink = new jsonl_connector_1.JsonlSink({ filePath: OUTPUT_FILE });
220
+ await sink.open();
221
+ await sink.writeBatch([]);
222
+ await sink.close();
223
+ const source = new jsonl_connector_1.JsonlSource({ filePath: OUTPUT_FILE });
224
+ await source.open();
225
+ const records = await source.readAll();
226
+ await source.close();
227
+ expect(records).toHaveLength(0);
228
+ });
229
+ });
230
+ describe('close', () => {
231
+ it('should close stream successfully', async () => {
232
+ const sink = new jsonl_connector_1.JsonlSink({ filePath: OUTPUT_FILE });
233
+ await sink.open();
234
+ await expect(sink.close()).resolves.toBeUndefined();
235
+ });
236
+ it('should handle close without open', async () => {
237
+ const sink = new jsonl_connector_1.JsonlSink({ filePath: OUTPUT_FILE });
238
+ await expect(sink.close()).resolves.toBeUndefined();
239
+ });
240
+ });
241
+ describe('integration', () => {
242
+ it('should write and read back data correctly', async () => {
243
+ const originalData = [
244
+ { id: 1, name: 'Alice', age: 30, active: true },
245
+ { id: 2, name: 'Bob', age: 25, active: false },
246
+ { id: 3, name: 'Charlie', age: 35, active: true },
247
+ ];
248
+ // Write data
249
+ const sink = new jsonl_connector_1.JsonlSink({ filePath: OUTPUT_FILE });
250
+ await sink.open();
251
+ await sink.writeBatch(originalData);
252
+ await sink.close();
253
+ // Read data back
254
+ const source = new jsonl_connector_1.JsonlSource({ filePath: OUTPUT_FILE });
255
+ await source.open();
256
+ const readData = await source.readAll();
257
+ await source.close();
258
+ expect(readData).toEqual(originalData);
259
+ });
260
+ });
261
+ });
@@ -0,0 +1,51 @@
1
+ import type { DataSource, DataSink } from './connector.interface';
2
+ export interface JsonlSourceOptions {
3
+ filePath: string;
4
+ name?: string;
5
+ }
6
+ export interface JsonlSinkOptions {
7
+ filePath: string;
8
+ name?: string;
9
+ }
10
+ /**
11
+ * JSONL (newline-delimited JSON) data source — reads records from a .jsonl file.
12
+ * Each line is a valid JSON object. Efficient for streaming and large datasets.
13
+ *
14
+ * @example
15
+ * const source = new JsonlSource({ filePath: './data.jsonl' });
16
+ * await source.open();
17
+ * for await (const record of source.read()) {
18
+ * console.log(record);
19
+ * }
20
+ * await source.close();
21
+ */
22
+ export declare class JsonlSource implements DataSource<Record<string, unknown>> {
23
+ readonly name: string;
24
+ private readonly filePath;
25
+ constructor(options: JsonlSourceOptions);
26
+ open(): Promise<void>;
27
+ close(): Promise<void>;
28
+ readAll(): Promise<Record<string, unknown>[]>;
29
+ read(): AsyncGenerator<Record<string, unknown>>;
30
+ }
31
+ /**
32
+ * JSONL data sink — writes records to a .jsonl file.
33
+ * Each record is written as a single line of JSON.
34
+ *
35
+ * @example
36
+ * const sink = new JsonlSink({ filePath: './output.jsonl' });
37
+ * await sink.open();
38
+ * await sink.writeBatch(records);
39
+ * await sink.close();
40
+ */
41
+ export declare class JsonlSink implements DataSink<Record<string, unknown>> {
42
+ readonly name: string;
43
+ private readonly filePath;
44
+ private stream;
45
+ constructor(options: JsonlSinkOptions);
46
+ open(): Promise<void>;
47
+ close(): Promise<void>;
48
+ write(record: Record<string, unknown>): Promise<void>;
49
+ writeBatch(records: Record<string, unknown>[]): Promise<void>;
50
+ }
51
+ //# sourceMappingURL=jsonl.connector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl.connector.d.ts","sourceRoot":"","sources":["../../src/connectors/jsonl.connector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,WAAY,YAAW,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,OAAO,EAAE,kBAAkB;IAKjC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAMrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAQ5C,IAAI,IAAI,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAkBvD;AAED;;;;;;;;;GASG;AACH,qBAAa,SAAU,YAAW,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,MAAM,CAAqD;gBAEvD,OAAO,EAAE,gBAAgB;IAK/B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAUtB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAOrD,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAQpE"}
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JsonlSink = exports.JsonlSource = void 0;
4
+ const fs_1 = require("fs");
5
+ const readline_1 = require("readline");
6
+ /**
7
+ * JSONL (newline-delimited JSON) data source — reads records from a .jsonl file.
8
+ * Each line is a valid JSON object. Efficient for streaming and large datasets.
9
+ *
10
+ * @example
11
+ * const source = new JsonlSource({ filePath: './data.jsonl' });
12
+ * await source.open();
13
+ * for await (const record of source.read()) {
14
+ * console.log(record);
15
+ * }
16
+ * await source.close();
17
+ */
18
+ class JsonlSource {
19
+ constructor(options) {
20
+ this.name = options.name ?? `jsonl:${options.filePath}`;
21
+ this.filePath = options.filePath;
22
+ }
23
+ async open() {
24
+ if (!(0, fs_1.existsSync)(this.filePath)) {
25
+ throw new Error(`JSONL file not found: ${this.filePath}`);
26
+ }
27
+ }
28
+ async close() {
29
+ // No-op for file reads
30
+ }
31
+ async readAll() {
32
+ const records = [];
33
+ for await (const record of this.read()) {
34
+ records.push(record);
35
+ }
36
+ return records;
37
+ }
38
+ async *read() {
39
+ const rl = (0, readline_1.createInterface)({
40
+ input: (0, fs_1.createReadStream)(this.filePath),
41
+ crlfDelay: Infinity,
42
+ });
43
+ for await (const line of rl) {
44
+ if (!line.trim())
45
+ continue;
46
+ try {
47
+ const record = JSON.parse(line);
48
+ yield record;
49
+ }
50
+ catch (error) {
51
+ throw new Error(`Failed to parse JSONL line: ${line.substring(0, 100)}... Error: ${error instanceof Error ? error.message : String(error)}`);
52
+ }
53
+ }
54
+ }
55
+ }
56
+ exports.JsonlSource = JsonlSource;
57
+ /**
58
+ * JSONL data sink — writes records to a .jsonl file.
59
+ * Each record is written as a single line of JSON.
60
+ *
61
+ * @example
62
+ * const sink = new JsonlSink({ filePath: './output.jsonl' });
63
+ * await sink.open();
64
+ * await sink.writeBatch(records);
65
+ * await sink.close();
66
+ */
67
+ class JsonlSink {
68
+ constructor(options) {
69
+ this.stream = null;
70
+ this.name = options.name ?? `jsonl:${options.filePath}`;
71
+ this.filePath = options.filePath;
72
+ }
73
+ async open() {
74
+ this.stream = (0, fs_1.createWriteStream)(this.filePath, { encoding: 'utf8' });
75
+ }
76
+ async close() {
77
+ return new Promise((resolve, reject) => {
78
+ if (!this.stream) {
79
+ resolve();
80
+ return;
81
+ }
82
+ this.stream.end((err) => (err ? reject(err) : resolve()));
83
+ });
84
+ }
85
+ async write(record) {
86
+ if (!this.stream)
87
+ throw new Error('JsonlSink: call open() before write()');
88
+ const line = JSON.stringify(record) + '\n';
89
+ this.stream.write(line);
90
+ }
91
+ async writeBatch(records) {
92
+ if (!this.stream)
93
+ throw new Error('JsonlSink: call open() before writeBatch()');
94
+ for (const record of records) {
95
+ const line = JSON.stringify(record) + '\n';
96
+ this.stream.write(line);
97
+ }
98
+ }
99
+ }
100
+ exports.JsonlSink = JsonlSink;
@@ -0,0 +1,78 @@
1
+ import type { DataSource, DataSink } from './connector.interface';
2
+ export interface PostgresSourceOptions {
3
+ host: string;
4
+ port: number;
5
+ database: string;
6
+ user: string;
7
+ password: string;
8
+ table: string;
9
+ columns?: string[];
10
+ where?: string;
11
+ orderBy?: string;
12
+ batchSize?: number;
13
+ name?: string;
14
+ }
15
+ export interface PostgresSinkOptions {
16
+ host: string;
17
+ port: number;
18
+ database: string;
19
+ user: string;
20
+ password: string;
21
+ table: string;
22
+ columns: string[];
23
+ conflictColumn?: string;
24
+ batchSize?: number;
25
+ name?: string;
26
+ }
27
+ export declare class PostgresSource implements DataSource<Record<string, unknown>> {
28
+ readonly name: string;
29
+ private readonly options;
30
+ private pool;
31
+ constructor(options: PostgresSourceOptions);
32
+ private ensurePool;
33
+ open(): Promise<void>;
34
+ close(): Promise<void>;
35
+ readAll(): Promise<Record<string, unknown>[]>;
36
+ read(): AsyncGenerator<Record<string, unknown>>;
37
+ /**
38
+ * Execute a custom SQL query
39
+ */
40
+ query(sql: string, params?: unknown[]): Promise<Record<string, unknown>[]>;
41
+ }
42
+ /**
43
+ * PostgreSQL data sink — writes records to a Postgres table.
44
+ * Supports batch inserts and upserts.
45
+ *
46
+ * @example
47
+ * const sink = new PostgresSink({
48
+ * host: 'localhost',
49
+ * port: 5432,
50
+ * database: 'mydb',
51
+ * user: 'user',
52
+ * password: 'pass',
53
+ * table: 'users',
54
+ * columns: ['id', 'name', 'email'],
55
+ * conflictColumn: 'id', // for upserts
56
+ * });
57
+ * await sink.open();
58
+ * await sink.writeBatch(records);
59
+ * await sink.close();
60
+ */
61
+ export declare class PostgresSink implements DataSink<Record<string, unknown>> {
62
+ readonly name: string;
63
+ private readonly options;
64
+ private pool;
65
+ private buffer;
66
+ constructor(options: PostgresSinkOptions);
67
+ private ensurePool;
68
+ open(): Promise<void>;
69
+ close(): Promise<void>;
70
+ write(record: Record<string, unknown>): Promise<void>;
71
+ writeBatch(records: Record<string, unknown>[]): Promise<void>;
72
+ private flush;
73
+ /**
74
+ * Execute a custom SQL command
75
+ */
76
+ execute(sql: string, params?: unknown[]): Promise<void>;
77
+ }
78
+ //# sourceMappingURL=postgres.connector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.connector.d.ts","sourceRoot":"","sources":["../../src/connectors/postgres.connector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAElE,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA+BD,qBAAa,cAAe,YAAW,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,IAAI,CAAuB;gBAEvB,OAAO,EAAE,qBAAqB;YAK5B,UAAU;IAuBlB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAYrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAQ5C,IAAI,IAAI,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IA0BtD;;OAEG;IACG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CAWjF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,YAAa,YAAW,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,MAAM,CAAiC;gBAEnC,OAAO,EAAE,mBAAmB;YAK1B,UAAU;IAuBlB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAUtB,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAOrD,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAKrD,KAAK;IA4CnB;;OAEG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAU9D"}