@hexaijs/postgres 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.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +318 -0
  3. package/dist/config/index.d.ts +3 -0
  4. package/dist/config/index.d.ts.map +1 -0
  5. package/dist/config/index.js +19 -0
  6. package/dist/config/index.js.map +1 -0
  7. package/dist/config/postgres-config-spec.d.ts +32 -0
  8. package/dist/config/postgres-config-spec.d.ts.map +1 -0
  9. package/dist/config/postgres-config-spec.js +49 -0
  10. package/dist/config/postgres-config-spec.js.map +1 -0
  11. package/dist/config/postgres-config.d.ts +59 -0
  12. package/dist/config/postgres-config.d.ts.map +1 -0
  13. package/dist/config/postgres-config.js +181 -0
  14. package/dist/config/postgres-config.js.map +1 -0
  15. package/dist/helpers.d.ts +57 -0
  16. package/dist/helpers.d.ts.map +1 -0
  17. package/dist/helpers.js +276 -0
  18. package/dist/helpers.js.map +1 -0
  19. package/dist/index.d.ts +7 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +29 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/postgres-event-store.d.ts +18 -0
  24. package/dist/postgres-event-store.d.ts.map +1 -0
  25. package/dist/postgres-event-store.js +83 -0
  26. package/dist/postgres-event-store.js.map +1 -0
  27. package/dist/postgres-unit-of-work.d.ts +17 -0
  28. package/dist/postgres-unit-of-work.d.ts.map +1 -0
  29. package/dist/postgres-unit-of-work.js +251 -0
  30. package/dist/postgres-unit-of-work.js.map +1 -0
  31. package/dist/run-hexai-migrations.d.ts +3 -0
  32. package/dist/run-hexai-migrations.d.ts.map +1 -0
  33. package/dist/run-hexai-migrations.js +17 -0
  34. package/dist/run-hexai-migrations.js.map +1 -0
  35. package/dist/run-migrations.d.ts +11 -0
  36. package/dist/run-migrations.d.ts.map +1 -0
  37. package/dist/run-migrations.js +202 -0
  38. package/dist/run-migrations.js.map +1 -0
  39. package/dist/test-fixtures/config.d.ts +5 -0
  40. package/dist/test-fixtures/config.d.ts.map +1 -0
  41. package/dist/test-fixtures/config.js +14 -0
  42. package/dist/test-fixtures/config.js.map +1 -0
  43. package/dist/test-fixtures/hooks.d.ts +8 -0
  44. package/dist/test-fixtures/hooks.d.ts.map +1 -0
  45. package/dist/test-fixtures/hooks.js +77 -0
  46. package/dist/test-fixtures/hooks.js.map +1 -0
  47. package/dist/test-fixtures/index.d.ts +3 -0
  48. package/dist/test-fixtures/index.d.ts.map +1 -0
  49. package/dist/test-fixtures/index.js +19 -0
  50. package/dist/test-fixtures/index.js.map +1 -0
  51. package/dist/test.d.ts +11 -0
  52. package/dist/test.d.ts.map +1 -0
  53. package/dist/test.js +41 -0
  54. package/dist/test.js.map +1 -0
  55. package/dist/types.d.ts +14 -0
  56. package/dist/types.d.ts.map +1 -0
  57. package/dist/types.js +11 -0
  58. package/dist/types.js.map +1 -0
  59. package/migrations/01_postgres_event_store/migration.sql +10 -0
  60. package/package.json +67 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Sangwoo Hyun
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,318 @@
1
+ # @hexaijs/postgres
2
+
3
+ > PostgreSQL infrastructure for transaction management, event storage, and migrations
4
+
5
+ ## Overview
6
+
7
+ `@hexaijs/postgres` provides PostgreSQL implementations of the core infrastructure interfaces defined in `@hexaijs/core`. It bridges your domain layer to PostgreSQL with production-ready transaction management.
8
+
9
+ The package centers around `PostgresUnitOfWork`, which manages database transactions across your command handlers. It uses `AsyncLocalStorage` to maintain transaction context throughout async operations, ensuring all database operations within a handler share the same transaction. If your handler succeeds, the transaction commits automatically. If it throws, the transaction rolls back.
10
+
11
+ Beyond transactions, the package includes `PostgresEventStore` for storing domain events, a migration runner that integrates with `node-pg-migrate`, and configuration utilities for managing connection settings through environment variables.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ npm install @hexaijs/postgres
17
+ ```
18
+
19
+ **Peer dependencies:**
20
+
21
+ ```bash
22
+ npm install @hexaijs/core @hexaijs/utils pg
23
+ ```
24
+
25
+ ## Core Concepts
26
+
27
+ ### PostgresUnitOfWork
28
+
29
+ The `PostgresUnitOfWork` implements `UnitOfWork` from `@hexaijs/core`. It manages transaction lifecycle and provides access to the database client.
30
+
31
+ ```typescript
32
+ import * as pg from "pg";
33
+ import { PostgresUnitOfWork } from "@hexaijs/postgres";
34
+
35
+ // Create with a client factory
36
+ const pool = new pg.Pool({ connectionString: "postgres://..." });
37
+ const unitOfWork = new PostgresUnitOfWork(
38
+ () => new pg.Client({ connectionString: "postgres://..." }),
39
+ (client) => client.end() // cleanup function
40
+ );
41
+
42
+ // Or use a connection pool
43
+ const pooledUnitOfWork = new PostgresUnitOfWork(
44
+ async () => await pool.connect(),
45
+ (client) => (client as pg.PoolClient).release()
46
+ );
47
+ ```
48
+
49
+ The client factory creates a new client for each transaction. The optional cleanup function runs after the transaction completes (commit or rollback).
50
+
51
+ ### Transaction Execution
52
+
53
+ Use `wrap()` to execute operations within a transaction:
54
+
55
+ ```typescript
56
+ import { Propagation } from "@hexaijs/core";
57
+
58
+ // Execute within a transaction
59
+ const result = await unitOfWork.wrap(async (client) => {
60
+ await client.query("INSERT INTO orders (id, status) VALUES ($1, $2)", [orderId, "pending"]);
61
+ await client.query("INSERT INTO order_items (order_id, product_id) VALUES ($1, $2)", [orderId, productId]);
62
+ return { orderId };
63
+ });
64
+ ```
65
+
66
+ Within a command handler, access the client through `getClient()`:
67
+
68
+ ```typescript
69
+ // Inside a command handler
70
+ const client = ctx.getUnitOfWork().getClient();
71
+ await client.query("UPDATE orders SET status = $1 WHERE id = $2", ["confirmed", orderId]);
72
+ ```
73
+
74
+ ### Transaction Propagation
75
+
76
+ Control how nested operations participate in transactions using `Propagation`:
77
+
78
+ ```typescript
79
+ import { Propagation } from "@hexaijs/core";
80
+
81
+ // EXISTING (default): Join current transaction, or create new if none exists
82
+ await unitOfWork.wrap(async () => {
83
+ // This joins the outer transaction
84
+ await unitOfWork.wrap(async (client) => {
85
+ // Same transaction as outer
86
+ }, { propagation: Propagation.EXISTING });
87
+ });
88
+
89
+ // NEW: Always start a new transaction
90
+ await unitOfWork.wrap(async () => {
91
+ // This runs in a separate transaction
92
+ await unitOfWork.wrap(async (client) => {
93
+ // Independent transaction
94
+ }, { propagation: Propagation.NEW });
95
+ });
96
+
97
+ // NESTED: Create a savepoint within the current transaction
98
+ await unitOfWork.wrap(async () => {
99
+ try {
100
+ await unitOfWork.wrap(async (client) => {
101
+ // Runs in a savepoint
102
+ throw new Error("Rollback this part only");
103
+ }, { propagation: Propagation.NESTED });
104
+ } catch {
105
+ // Savepoint rolled back, outer transaction continues
106
+ }
107
+ });
108
+ ```
109
+
110
+ ### Isolation Levels
111
+
112
+ Configure transaction isolation levels when stricter guarantees are needed:
113
+
114
+ ```typescript
115
+ import { IsolationLevel } from "@hexaijs/postgres";
116
+
117
+ await unitOfWork.wrap(async (client) => {
118
+ // Serializable isolation prevents phantom reads
119
+ const result = await client.query("SELECT * FROM inventory WHERE product_id = $1", [productId]);
120
+ // ...
121
+ }, { isolationLevel: IsolationLevel.SERIALIZABLE });
122
+ ```
123
+
124
+ Available levels:
125
+ - `IsolationLevel.READ_UNCOMMITTED`
126
+ - `IsolationLevel.READ_COMMITTED` (PostgreSQL default)
127
+ - `IsolationLevel.REPEATABLE_READ`
128
+ - `IsolationLevel.SERIALIZABLE`
129
+
130
+ ### PostgresEventStore
131
+
132
+ The `PostgresEventStore` implements `EventStore` from `@hexaijs/core` for storing and retrieving domain events.
133
+
134
+ ```typescript
135
+ import { PostgresEventStore } from "@hexaijs/postgres";
136
+ import { DomainEvent } from "@hexaijs/core";
137
+
138
+ class OrderPlaced extends DomainEvent<{ orderId: string; customerId: string }> {
139
+ static readonly type = "order.order-placed";
140
+ }
141
+
142
+ // Create event store with the transaction client
143
+ const client = unitOfWork.getClient();
144
+ const eventStore = new PostgresEventStore(client);
145
+
146
+ // Store events
147
+ const stored = await eventStore.store(new OrderPlaced({
148
+ orderId: "order-123",
149
+ customerId: "customer-456"
150
+ }));
151
+ console.log(stored.position); // Event position in the store
152
+
153
+ // Store multiple events atomically
154
+ const storedEvents = await eventStore.storeAll([event1, event2, event3]);
155
+
156
+ // Fetch events for replay or projections
157
+ const { events, lastPosition } = await eventStore.fetch(0, 100);
158
+ // events: StoredEvent[] - events after position 0, up to 100
159
+ // lastPosition: number - highest position in store (for catchup detection)
160
+ ```
161
+
162
+ Custom table name:
163
+
164
+ ```typescript
165
+ const eventStore = new PostgresEventStore(client, {
166
+ tableName: "my_bounded_context_events"
167
+ });
168
+ ```
169
+
170
+ ## Usage
171
+
172
+ ### Running Migrations
173
+
174
+ The package provides a migration runner that supports both SQL and JavaScript migration formats.
175
+
176
+ ```typescript
177
+ import { runMigrations } from "@hexaijs/postgres";
178
+
179
+ // Run JavaScript migrations (node-pg-migrate format)
180
+ await runMigrations({
181
+ url: "postgres://user:pass@localhost:5432/mydb",
182
+ dir: "./migrations",
183
+ });
184
+
185
+ // With namespace (creates separate migrations table)
186
+ await runMigrations({
187
+ url: "postgres://user:pass@localhost:5432/mydb",
188
+ dir: "./migrations/orders",
189
+ namespace: "orders", // Table: hexai__migrations_orders
190
+ });
191
+
192
+ // SQL-based migrations (directories with migration.sql files)
193
+ // migrations/
194
+ // 001_create_orders/
195
+ // migration.sql
196
+ // 002_add_status/
197
+ // migration.sql
198
+ await runMigrations({
199
+ url: dbConfig,
200
+ dir: "./migrations",
201
+ });
202
+ ```
203
+
204
+ Run built-in hexai migrations (creates the event store table):
205
+
206
+ ```typescript
207
+ import { runHexaiMigrations } from "@hexaijs/postgres";
208
+
209
+ await runHexaiMigrations("postgres://user:pass@localhost:5432/mydb");
210
+ ```
211
+
212
+ ### Configuration
213
+
214
+ `PostgresConfig` provides immutable configuration management:
215
+
216
+ ```typescript
217
+ import { PostgresConfig } from "@hexaijs/postgres";
218
+
219
+ // From connection URL
220
+ const config = PostgresConfig.fromUrl("postgres://user:pass@localhost:5432/mydb");
221
+
222
+ // From environment variables
223
+ // URL mode: reads MY_DB_URL
224
+ const config = PostgresConfig.fromEnv("MY_DB");
225
+
226
+ // Fields mode: reads MY_DB_HOST, MY_DB_PORT, MY_DB_DATABASE, MY_DB_USER, MY_DB_PASSWORD
227
+ const config = PostgresConfig.fromEnv("MY_DB", { mode: "fields" });
228
+
229
+ // Builder pattern for modifications (returns new instance)
230
+ const testConfig = config
231
+ .withDatabase("mydb_test")
232
+ .withPoolSize(5);
233
+
234
+ // Use as connection string
235
+ new pg.Client({ connectionString: config.toString() });
236
+ ```
237
+
238
+ With `defineConfig` from `@hexaijs/utils`:
239
+
240
+ ```typescript
241
+ import { defineConfig } from "@hexaijs/utils/config";
242
+ import { postgresConfig } from "@hexaijs/postgres";
243
+
244
+ const getConfig = defineConfig({
245
+ db: postgresConfig("ORDER_DB"), // reads ORDER_DB_URL
246
+ readReplica: postgresConfig("REPLICA_DB", "fields"), // reads individual fields
247
+ });
248
+
249
+ const config = getConfig();
250
+ config.db.host; // "localhost"
251
+ config.db.toString(); // "postgres://..."
252
+ ```
253
+
254
+ ### Database Utilities
255
+
256
+ Helper classes for database management and testing:
257
+
258
+ ```typescript
259
+ import { DatabaseManager, TableManager, ensureConnection } from "@hexaijs/postgres";
260
+
261
+ // Create/drop databases
262
+ const dbManager = new DatabaseManager("postgres://user:pass@localhost:5432/postgres");
263
+ await dbManager.createDatabase("my_new_db");
264
+ await dbManager.dropDatabase("my_old_db");
265
+ await dbManager.close();
266
+
267
+ // Table operations
268
+ const tableManager = new TableManager(client);
269
+ await tableManager.tableExists("orders");
270
+ await tableManager.truncateTable("orders");
271
+ await tableManager.dropAllTables();
272
+
273
+ // Ensure client is connected
274
+ await ensureConnection(client); // Safe to call multiple times
275
+ ```
276
+
277
+ ### Test Fixtures
278
+
279
+ The package exports test utilities from `@hexaijs/postgres/test`:
280
+
281
+ ```typescript
282
+ import { useDatabase, useClient, useTableManager } from "@hexaijs/postgres/test";
283
+
284
+ describe("OrderRepository", () => {
285
+ // Creates database before tests, drops after
286
+ const dbUrl = useDatabase("order_test_db");
287
+
288
+ // Provides connected client
289
+ const client = useClient("order_test_db");
290
+
291
+ it("should persist orders", async () => {
292
+ // Use client for assertions
293
+ const result = await client.query("SELECT * FROM orders");
294
+ expect(result.rows).toHaveLength(1);
295
+ });
296
+ });
297
+ ```
298
+
299
+ ## API Highlights
300
+
301
+ | Export | Description |
302
+ |--------|-------------|
303
+ | `PostgresUnitOfWork` | Transaction management with `AsyncLocalStorage` context |
304
+ | `PostgresEventStore` | Event store implementation with batch insert support |
305
+ | `PostgresConfig` | Immutable configuration with builder pattern |
306
+ | `postgresConfig` | Config spec for `defineConfig` integration |
307
+ | `runMigrations` | Migration runner for SQL and JS migrations |
308
+ | `runHexaiMigrations` | Runs built-in hexai migrations |
309
+ | `DatabaseManager` | Create/drop databases |
310
+ | `TableManager` | Table operations (truncate, drop, schema info) |
311
+ | `IsolationLevel` | Transaction isolation level enum |
312
+ | `ensureConnection` | Safe connection helper |
313
+
314
+ ## See Also
315
+
316
+ - [@hexaijs/core](../core/README.md) - Core interfaces (`UnitOfWork`, `EventStore`, `Propagation`)
317
+ - [@hexaijs/sqlite](../sqlite/README.md) - SQLite implementation for testing
318
+ - [@hexaijs/application](../application/README.md) - Application context that provides `getUnitOfWork()`
@@ -0,0 +1,3 @@
1
+ export * from "./postgres-config";
2
+ export * from "./postgres-config-spec";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./postgres-config"), exports);
18
+ __exportStar(require("./postgres-config-spec"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAkC;AAClC,yDAAuC"}
@@ -0,0 +1,32 @@
1
+ import type { ConfigSpec } from "@hexaijs/utils/config";
2
+ import { PostgresConfig, type FromEnvOptions } from "./postgres-config";
3
+ export declare class PostgresConfigSpec implements ConfigSpec<PostgresConfig> {
4
+ private readonly prefix;
5
+ private readonly mode;
6
+ readonly _type = "postgres";
7
+ constructor(prefix: string, mode?: FromEnvOptions["mode"]);
8
+ resolve(errors: string[]): PostgresConfig | undefined;
9
+ }
10
+ /**
11
+ * PostgreSQL database configuration from environment variables.
12
+ * Returns a PostgresConfig instance.
13
+ *
14
+ * @param prefix - Environment variable prefix
15
+ * @param mode - "url" reads {PREFIX}_URL, "fields" reads individual fields
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * import { defineConfig, env } from "@hexaijs/core";
20
+ * import { postgresConfig } from "@hexaijs/postgres";
21
+ *
22
+ * const getConfig = defineConfig({
23
+ * db: postgresConfig("ORDER_DB"), // reads ORDER_DB_URL
24
+ * db2: postgresConfig("PG", "fields"), // reads PG_HOST, PG_PORT, etc.
25
+ * });
26
+ *
27
+ * getConfig().db.host; // "localhost"
28
+ * getConfig().db.toString(); // "postgres://..."
29
+ * ```
30
+ */
31
+ export declare function postgresConfig(prefix: string, mode?: FromEnvOptions["mode"]): PostgresConfigSpec;
32
+ //# sourceMappingURL=postgres-config-spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-config-spec.d.ts","sourceRoot":"","sources":["../../src/config/postgres-config-spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExE,qBAAa,kBAAmB,YAAW,UAAU,CAAC,cAAc,CAAC;IAI7D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJzB,QAAQ,CAAC,KAAK,cAAc;gBAGP,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,cAAc,CAAC,MAAM,CAAS;IAGzD,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,cAAc,GAAG,SAAS;CAQxD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,cAAc,CAAC,MAAM,CAAS,GACrC,kBAAkB,CAEpB"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PostgresConfigSpec = void 0;
4
+ exports.postgresConfig = postgresConfig;
5
+ const postgres_config_1 = require("./postgres-config");
6
+ class PostgresConfigSpec {
7
+ prefix;
8
+ mode;
9
+ _type = "postgres";
10
+ constructor(prefix, mode = "url") {
11
+ this.prefix = prefix;
12
+ this.mode = mode;
13
+ }
14
+ resolve(errors) {
15
+ try {
16
+ return postgres_config_1.PostgresConfig.fromEnv(this.prefix, { mode: this.mode });
17
+ }
18
+ catch (e) {
19
+ errors.push(e.message);
20
+ return undefined;
21
+ }
22
+ }
23
+ }
24
+ exports.PostgresConfigSpec = PostgresConfigSpec;
25
+ /**
26
+ * PostgreSQL database configuration from environment variables.
27
+ * Returns a PostgresConfig instance.
28
+ *
29
+ * @param prefix - Environment variable prefix
30
+ * @param mode - "url" reads {PREFIX}_URL, "fields" reads individual fields
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * import { defineConfig, env } from "@hexaijs/core";
35
+ * import { postgresConfig } from "@hexaijs/postgres";
36
+ *
37
+ * const getConfig = defineConfig({
38
+ * db: postgresConfig("ORDER_DB"), // reads ORDER_DB_URL
39
+ * db2: postgresConfig("PG", "fields"), // reads PG_HOST, PG_PORT, etc.
40
+ * });
41
+ *
42
+ * getConfig().db.host; // "localhost"
43
+ * getConfig().db.toString(); // "postgres://..."
44
+ * ```
45
+ */
46
+ function postgresConfig(prefix, mode = "url") {
47
+ return new PostgresConfigSpec(prefix, mode);
48
+ }
49
+ //# sourceMappingURL=postgres-config-spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-config-spec.js","sourceRoot":"","sources":["../../src/config/postgres-config-spec.ts"],"names":[],"mappings":";;;AA0CA,wCAKC;AA9CD,uDAAwE;AAExE,MAAa,kBAAkB;IAIN;IACA;IAJZ,KAAK,GAAG,UAAU,CAAC;IAE5B,YACqB,MAAc,EACd,OAA+B,KAAK;QADpC,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAgC;IACtD,CAAC;IAEJ,OAAO,CAAC,MAAgB;QACpB,IAAI,CAAC;YACD,OAAO,gCAAc,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACpE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,MAAM,CAAC,IAAI,CAAE,CAAW,CAAC,OAAO,CAAC,CAAC;YAClC,OAAO,SAAS,CAAC;QACrB,CAAC;IACL,CAAC;CACJ;AAhBD,gDAgBC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,cAAc,CAC1B,MAAc,EACd,OAA+B,KAAK;IAEpC,OAAO,IAAI,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,59 @@
1
+ import type { DatabaseConfig } from "@hexaijs/utils/config";
2
+ export interface PoolOptions {
3
+ size?: number;
4
+ connectionTimeout?: number;
5
+ idleTimeout?: number;
6
+ }
7
+ export interface FromEnvOptions {
8
+ /**
9
+ * Environment variable loading mode.
10
+ * - "url": Load from {PREFIX}_URL (default)
11
+ * - "fields": Load from {PREFIX}_HOST, {PREFIX}_PORT, {PREFIX}_DATABASE, {PREFIX}_USER, {PREFIX}_PASSWORD
12
+ */
13
+ mode?: "url" | "fields";
14
+ }
15
+ export declare class PostgresConfig implements DatabaseConfig {
16
+ readonly host: string;
17
+ readonly database: string;
18
+ readonly user: string;
19
+ readonly port: number;
20
+ readonly password?: string;
21
+ readonly pool?: PoolOptions;
22
+ constructor(config: {
23
+ database: string;
24
+ user?: string;
25
+ host?: string;
26
+ port?: number;
27
+ password?: string;
28
+ pool?: PoolOptions;
29
+ });
30
+ static fromUrl(value: string): PostgresConfig;
31
+ /**
32
+ * Creates a PostgresConfig from environment variables.
33
+ *
34
+ * @param prefix - Environment variable prefix
35
+ * @param options - Loading options (mode: "url" | "fields")
36
+ * @throws Error if required environment variables are not set
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * // URL mode (default): reads ASSIGNMENT_DB_URL
41
+ * const config = PostgresConfig.fromEnv("ASSIGNMENT_DB");
42
+ *
43
+ * // Fields mode: reads POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DATABASE, POSTGRES_USER, POSTGRES_PASSWORD
44
+ * const config = PostgresConfig.fromEnv("POSTGRES", { mode: "fields" });
45
+ * ```
46
+ */
47
+ static fromEnv(prefix: string, options?: FromEnvOptions): PostgresConfig;
48
+ private static parseUrl;
49
+ withDatabase(database: string): PostgresConfig;
50
+ withUser(user: string): PostgresConfig;
51
+ withPassword(password: string): PostgresConfig;
52
+ withHost(host: string): PostgresConfig;
53
+ withPort(port: number): PostgresConfig;
54
+ withPoolSize(size: number): PostgresConfig;
55
+ withConnectionTimeout(connectionTimeout: number): PostgresConfig;
56
+ withIdleTimeout(idleTimeout: number): PostgresConfig;
57
+ toString(): string;
58
+ }
59
+ //# sourceMappingURL=postgres-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-config.d.ts","sourceRoot":"","sources":["../../src/config/postgres-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,MAAM,WAAW,WAAW;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC3B;;;;OAIG;IACH,IAAI,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;CAC3B;AAED,qBAAa,cAAe,YAAW,cAAc;IACjD,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClC,SAAgB,IAAI,CAAC,EAAE,WAAW,CAAC;gBAEvB,MAAM,EAAE;QAChB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,WAAW,CAAC;KACtB;WASa,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc;IAIpD;;;;;;;;;;;;;;;OAeG;WACW,OAAO,CACjB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,cAAc,GACzB,cAAc;IAiCjB,OAAO,CAAC,MAAM,CAAC,QAAQ;IAqBhB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc;IAW9C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc;IAWtC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc;IAW9C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc;IAWtC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc;IAWtC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc;IAW1C,qBAAqB,CAAC,iBAAiB,EAAE,MAAM,GAAG,cAAc;IAWhE,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc;IAWpD,QAAQ,IAAI,MAAM;CA2B5B"}