@hexaijs/postgres 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -10
- package/dist/test.d.ts +14 -0
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +215 -0
- package/dist/test.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -274,26 +274,92 @@ await tableManager.dropAllTables();
|
|
|
274
274
|
await ensureConnection(client); // Safe to call multiple times
|
|
275
275
|
```
|
|
276
276
|
|
|
277
|
-
###
|
|
277
|
+
### PostgresUnitOfWorkForTesting
|
|
278
278
|
|
|
279
|
-
|
|
279
|
+
A test-specific `UnitOfWork` implementation that runs inside an external transaction. This allows tests to rollback all changes after each test, keeping the database clean without truncating tables.
|
|
280
280
|
|
|
281
281
|
```typescript
|
|
282
|
-
import {
|
|
282
|
+
import { PostgresUnitOfWorkForTesting } from "@hexaijs/postgres/test";
|
|
283
|
+
import { Client } from "pg";
|
|
284
|
+
|
|
285
|
+
describe("OrderService", () => {
|
|
286
|
+
let client: Client;
|
|
287
|
+
let uow: PostgresUnitOfWorkForTesting;
|
|
288
|
+
|
|
289
|
+
beforeEach(async () => {
|
|
290
|
+
client = new Client({ connectionString: "postgres://..." });
|
|
291
|
+
await client.connect();
|
|
292
|
+
await client.query("BEGIN"); // Start external transaction
|
|
293
|
+
uow = new PostgresUnitOfWorkForTesting(client);
|
|
294
|
+
});
|
|
283
295
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
296
|
+
afterEach(async () => {
|
|
297
|
+
await client.query("ROLLBACK"); // Rollback all changes
|
|
298
|
+
await client.end();
|
|
299
|
+
});
|
|
287
300
|
|
|
288
|
-
|
|
289
|
-
|
|
301
|
+
it("should create order", async () => {
|
|
302
|
+
await uow.wrap(async (c) => {
|
|
303
|
+
await c.query("INSERT INTO orders (id) VALUES ($1)", ["order-1"]);
|
|
304
|
+
});
|
|
290
305
|
|
|
291
|
-
|
|
292
|
-
// Use client for assertions
|
|
306
|
+
// Verify within the same transaction
|
|
293
307
|
const result = await client.query("SELECT * FROM orders");
|
|
294
308
|
expect(result.rows).toHaveLength(1);
|
|
295
309
|
});
|
|
310
|
+
|
|
311
|
+
// After this test, ROLLBACK cleans up - no data persists
|
|
312
|
+
});
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**How it works:**
|
|
316
|
+
|
|
317
|
+
| Operation | Production (`PostgresUnitOfWork`) | Testing (`PostgresUnitOfWorkForTesting`) |
|
|
318
|
+
|-----------|-----------------------------------|------------------------------------------|
|
|
319
|
+
| Start | `BEGIN` | `SAVEPOINT` |
|
|
320
|
+
| Commit | `COMMIT` | `RELEASE SAVEPOINT` |
|
|
321
|
+
| Rollback | `ROLLBACK` | `ROLLBACK TO SAVEPOINT` |
|
|
322
|
+
|
|
323
|
+
**Key behaviors:**
|
|
324
|
+
|
|
325
|
+
- **abortError propagation**: When a nested `EXISTING` operation throws (even if caught), the entire transaction is marked as aborted and will rollback - matching production behavior.
|
|
326
|
+
- **NESTED savepoints**: `Propagation.NESTED` creates independent savepoints that can rollback without affecting the parent.
|
|
327
|
+
- **Propagation.NEW**: Logs a warning and creates a new savepoint instead (true separate transactions are not possible within the external transaction).
|
|
328
|
+
- **Single client**: Does not support concurrent `Promise.all` wrap calls (PostgreSQL limitation with single connection).
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
// abortError behavior - matches production
|
|
332
|
+
await uow.wrap(async (c) => {
|
|
333
|
+
await insertOrder(c, 1);
|
|
334
|
+
|
|
335
|
+
try {
|
|
336
|
+
await uow.wrap(async () => {
|
|
337
|
+
throw new Error("fails");
|
|
338
|
+
});
|
|
339
|
+
} catch {
|
|
340
|
+
// Caught, but transaction is already marked as aborted
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
await insertOrder(c, 2); // Executes, but will be rolled back
|
|
344
|
+
});
|
|
345
|
+
// Result: Both orders rolled back (abortError propagation)
|
|
346
|
+
|
|
347
|
+
// NESTED savepoint - independent rollback
|
|
348
|
+
await uow.wrap(async (c) => {
|
|
349
|
+
await insertOrder(c, 1);
|
|
350
|
+
|
|
351
|
+
try {
|
|
352
|
+
await uow.wrap(async (sp) => {
|
|
353
|
+
await insertOrder(sp, 2);
|
|
354
|
+
throw new Error("fails");
|
|
355
|
+
}, { propagation: Propagation.NESTED });
|
|
356
|
+
} catch {
|
|
357
|
+
// Only savepoint rolled back
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
await insertOrder(c, 3);
|
|
296
361
|
});
|
|
362
|
+
// Result: Orders 1 and 3 committed, order 2 rolled back
|
|
297
363
|
```
|
|
298
364
|
|
|
299
365
|
## API Highlights
|
|
@@ -301,6 +367,7 @@ describe("OrderRepository", () => {
|
|
|
301
367
|
| Export | Description |
|
|
302
368
|
|--------|-------------|
|
|
303
369
|
| `PostgresUnitOfWork` | Transaction management with `AsyncLocalStorage` context |
|
|
370
|
+
| `PostgresUnitOfWorkForTesting` | Test-specific UnitOfWork that runs inside external transaction |
|
|
304
371
|
| `PostgresEventStore` | Event store implementation with batch insert support |
|
|
305
372
|
| `PostgresConfig` | Immutable configuration with builder pattern |
|
|
306
373
|
| `postgresConfig` | Config spec for `defineConfig` integration |
|
package/dist/test.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Client } from "pg";
|
|
2
|
+
import { UnitOfWork } from "@hexaijs/core";
|
|
2
3
|
import { TableManager } from "./helpers";
|
|
3
4
|
import { PostgresConfig } from "./config";
|
|
5
|
+
import { PostgresTransactionOptions } from "./types";
|
|
4
6
|
export declare function createTestContext(dbUrl: string | PostgresConfig): {
|
|
5
7
|
client: Client;
|
|
6
8
|
newClient: () => Client;
|
|
@@ -8,4 +10,16 @@ export declare function createTestContext(dbUrl: string | PostgresConfig): {
|
|
|
8
10
|
setup: () => Promise<void>;
|
|
9
11
|
teardown: () => Promise<void>;
|
|
10
12
|
};
|
|
13
|
+
export declare class PostgresUnitOfWorkForTesting implements UnitOfWork<Client, PostgresTransactionOptions> {
|
|
14
|
+
private client;
|
|
15
|
+
private executorStorage;
|
|
16
|
+
constructor(client: Client);
|
|
17
|
+
getClient(): Client;
|
|
18
|
+
wrap<T = unknown>(fn: (client: Client) => Promise<T>, options?: Partial<PostgresTransactionOptions>): Promise<T>;
|
|
19
|
+
private getCurrentExecutor;
|
|
20
|
+
private resolveOptions;
|
|
21
|
+
private resolveExecutor;
|
|
22
|
+
private createExecutor;
|
|
23
|
+
private executeInContext;
|
|
24
|
+
}
|
|
11
25
|
//# sourceMappingURL=test.d.ts.map
|
package/dist/test.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAE5B,OAAO,EAAe,UAAU,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAoC,YAAY,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAErD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc;;;;iBAUpC,OAAO,CAAC,IAAI,CAAC;oBAeV,OAAO,CAAC,IAAI,CAAC;EAa3C;AAED,qBAAa,4BACT,YAAW,UAAU,CAAC,MAAM,EAAE,0BAA0B,CAAC;IAI7C,OAAO,CAAC,MAAM;IAF1B,OAAO,CAAC,eAAe,CAAoD;gBAEvD,MAAM,EAAE,MAAM;IAE3B,SAAS,IAAI,MAAM;IAQpB,IAAI,CAAC,CAAC,GAAG,OAAO,EAClB,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAClC,OAAO,GAAE,OAAO,CAAC,0BAA0B,CAAM,GAClD,OAAO,CAAC,CAAC,CAAC;IASb,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,gBAAgB;CAM3B"}
|
package/dist/test.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PostgresUnitOfWorkForTesting = void 0;
|
|
3
4
|
exports.createTestContext = createTestContext;
|
|
5
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
4
6
|
const pg_1 = require("pg");
|
|
7
|
+
const core_1 = require("@hexaijs/core");
|
|
5
8
|
const helpers_1 = require("./helpers");
|
|
6
9
|
const config_1 = require("./config");
|
|
7
10
|
const run_hexai_migrations_1 = require("./run-hexai-migrations");
|
|
@@ -38,4 +41,216 @@ function createTestContext(dbUrl) {
|
|
|
38
41
|
teardown,
|
|
39
42
|
};
|
|
40
43
|
}
|
|
44
|
+
class PostgresUnitOfWorkForTesting {
|
|
45
|
+
client;
|
|
46
|
+
executorStorage = new node_async_hooks_1.AsyncLocalStorage();
|
|
47
|
+
constructor(client) {
|
|
48
|
+
this.client = client;
|
|
49
|
+
}
|
|
50
|
+
getClient() {
|
|
51
|
+
const executor = this.getCurrentExecutor();
|
|
52
|
+
if (!executor) {
|
|
53
|
+
throw new Error("Unit of work not started");
|
|
54
|
+
}
|
|
55
|
+
return this.client;
|
|
56
|
+
}
|
|
57
|
+
async wrap(fn, options = {}) {
|
|
58
|
+
const resolvedOptions = this.resolveOptions(options);
|
|
59
|
+
const executor = this.resolveExecutor(resolvedOptions);
|
|
60
|
+
return this.executeInContext(executor, (exec) => exec.execute(fn, resolvedOptions));
|
|
61
|
+
}
|
|
62
|
+
getCurrentExecutor() {
|
|
63
|
+
return this.executorStorage.getStore() ?? null;
|
|
64
|
+
}
|
|
65
|
+
resolveOptions(options) {
|
|
66
|
+
return {
|
|
67
|
+
propagation: core_1.Propagation.EXISTING,
|
|
68
|
+
...options,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
resolveExecutor(options) {
|
|
72
|
+
if (options.propagation === core_1.Propagation.NEW) {
|
|
73
|
+
console.warn("[PostgresUnitOfWorkForTesting] Propagation.NEW is not fully supported in testing mode. Using savepoint instead.");
|
|
74
|
+
return this.createExecutor();
|
|
75
|
+
}
|
|
76
|
+
return this.getCurrentExecutor() ?? this.createExecutor();
|
|
77
|
+
}
|
|
78
|
+
createExecutor() {
|
|
79
|
+
return new TestTransactionExecutor(this.client);
|
|
80
|
+
}
|
|
81
|
+
executeInContext(executor, callback) {
|
|
82
|
+
return this.executorStorage.run(executor, () => callback(executor));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.PostgresUnitOfWorkForTesting = PostgresUnitOfWorkForTesting;
|
|
86
|
+
class TestTransactionExecutor {
|
|
87
|
+
client;
|
|
88
|
+
initialized = false;
|
|
89
|
+
closed = false;
|
|
90
|
+
abortError;
|
|
91
|
+
nestingDepth = 0;
|
|
92
|
+
savepointCounter = 0;
|
|
93
|
+
savepoints = [];
|
|
94
|
+
savepointName;
|
|
95
|
+
constructor(client) {
|
|
96
|
+
this.client = client;
|
|
97
|
+
this.savepointName = `test_sp_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
98
|
+
}
|
|
99
|
+
async execute(fn, options) {
|
|
100
|
+
await this.ensureStarted();
|
|
101
|
+
const executor = this.resolveExecutor(options.propagation);
|
|
102
|
+
return executor === this
|
|
103
|
+
? this.runWithLifecycle(fn)
|
|
104
|
+
: executor.execute(fn, options);
|
|
105
|
+
}
|
|
106
|
+
getClient() {
|
|
107
|
+
return this.client;
|
|
108
|
+
}
|
|
109
|
+
async ensureStarted() {
|
|
110
|
+
if (this.initialized) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
this.initialized = true;
|
|
114
|
+
await this.client.query(`SAVEPOINT ${this.savepointName}`);
|
|
115
|
+
}
|
|
116
|
+
async runWithLifecycle(fn) {
|
|
117
|
+
try {
|
|
118
|
+
return await this.executeWithNesting(fn);
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
this.markAsAborted(e);
|
|
122
|
+
throw e;
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
await this.finalizeIfRoot();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async executeWithNesting(fn) {
|
|
129
|
+
this.nestingDepth++;
|
|
130
|
+
try {
|
|
131
|
+
return await fn(this.client);
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
this.nestingDepth--;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
markAsAborted(error) {
|
|
138
|
+
this.abortError = error;
|
|
139
|
+
}
|
|
140
|
+
async finalizeIfRoot() {
|
|
141
|
+
if (this.nestingDepth === 0) {
|
|
142
|
+
await (this.isAborted() ? this.rollback() : this.commit());
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
resolveExecutor(propagation) {
|
|
146
|
+
if (this.nestingDepth === 0) {
|
|
147
|
+
return this;
|
|
148
|
+
}
|
|
149
|
+
return propagation === core_1.Propagation.NESTED
|
|
150
|
+
? this.createSavepoint()
|
|
151
|
+
: (this.findActiveSavepoint() ?? this);
|
|
152
|
+
}
|
|
153
|
+
createSavepoint() {
|
|
154
|
+
this.savepointCounter++;
|
|
155
|
+
const savepoint = new TestSavepoint(`${this.savepointName}_nested_${this.savepointCounter}`, this.client, () => this.removeSavepoint());
|
|
156
|
+
this.savepoints.push(savepoint);
|
|
157
|
+
return savepoint;
|
|
158
|
+
}
|
|
159
|
+
findActiveSavepoint() {
|
|
160
|
+
for (let i = this.savepoints.length - 1; i >= 0; i--) {
|
|
161
|
+
if (!this.savepoints[i].isClosed()) {
|
|
162
|
+
return this.savepoints[i];
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
removeSavepoint() {
|
|
167
|
+
this.savepoints.pop();
|
|
168
|
+
}
|
|
169
|
+
async commit() {
|
|
170
|
+
if (this.closed) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
this.closed = true;
|
|
174
|
+
await this.client.query(`RELEASE SAVEPOINT ${this.savepointName}`);
|
|
175
|
+
}
|
|
176
|
+
async rollback() {
|
|
177
|
+
if (this.closed) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
this.closed = true;
|
|
181
|
+
await this.client.query(`ROLLBACK TO SAVEPOINT ${this.savepointName}`);
|
|
182
|
+
}
|
|
183
|
+
isAborted() {
|
|
184
|
+
return this.abortError !== undefined && !this.closed;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
class TestSavepoint {
|
|
188
|
+
name;
|
|
189
|
+
client;
|
|
190
|
+
onClose;
|
|
191
|
+
initialized = false;
|
|
192
|
+
closed = false;
|
|
193
|
+
abortError;
|
|
194
|
+
nestingDepth = 0;
|
|
195
|
+
constructor(name, client, onClose) {
|
|
196
|
+
this.name = name;
|
|
197
|
+
this.client = client;
|
|
198
|
+
this.onClose = onClose;
|
|
199
|
+
}
|
|
200
|
+
async execute(fn) {
|
|
201
|
+
await this.ensureStarted();
|
|
202
|
+
return this.runWithLifecycle(fn);
|
|
203
|
+
}
|
|
204
|
+
isClosed() {
|
|
205
|
+
return this.closed;
|
|
206
|
+
}
|
|
207
|
+
async ensureStarted() {
|
|
208
|
+
if (this.initialized) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
this.initialized = true;
|
|
212
|
+
await this.client.query(`SAVEPOINT ${this.name}`);
|
|
213
|
+
}
|
|
214
|
+
async runWithLifecycle(fn) {
|
|
215
|
+
this.nestingDepth++;
|
|
216
|
+
try {
|
|
217
|
+
return await fn(this.client);
|
|
218
|
+
}
|
|
219
|
+
catch (e) {
|
|
220
|
+
this.markAsAborted(e);
|
|
221
|
+
throw e;
|
|
222
|
+
}
|
|
223
|
+
finally {
|
|
224
|
+
this.nestingDepth--;
|
|
225
|
+
await this.finalizeIfRoot();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
markAsAborted(error) {
|
|
229
|
+
this.abortError = error;
|
|
230
|
+
}
|
|
231
|
+
async finalizeIfRoot() {
|
|
232
|
+
if (this.nestingDepth === 0) {
|
|
233
|
+
await (this.isAborted() ? this.rollback() : this.commit());
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
async commit() {
|
|
237
|
+
if (this.closed) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
this.closed = true;
|
|
241
|
+
await this.client.query(`RELEASE SAVEPOINT ${this.name}`);
|
|
242
|
+
this.onClose();
|
|
243
|
+
}
|
|
244
|
+
async rollback() {
|
|
245
|
+
if (this.closed) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
this.closed = true;
|
|
249
|
+
await this.client.query(`ROLLBACK TO SAVEPOINT ${this.name}`);
|
|
250
|
+
this.onClose();
|
|
251
|
+
}
|
|
252
|
+
isAborted() {
|
|
253
|
+
return this.abortError !== undefined && !this.closed;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
41
256
|
//# sourceMappingURL=test.js.map
|
package/dist/test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"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"}
|