@xfcfam/xf-sql-postgres 0.1.0 → 0.1.1
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 +8 -5
- package/package.json +5 -5
- package/dist/src/repository/base/PostgresDatabaseRepository.d.ts +0 -91
- package/dist/src/repository/base/PostgresDatabaseRepository.d.ts.map +0 -1
- package/dist/src/repository/base/PostgresDatabaseRepository.js +0 -88
- package/dist/src/repository/base/PostgresDatabaseRepository.js.map +0 -1
package/README.md
CHANGED
|
@@ -5,15 +5,18 @@ Encapsulates `kysely`'s `PostgresDialect` over the [`pg`](https://node-postgres.
|
|
|
5
5
|
driver and ships the SQLSTATE → typed-Exception translation so the
|
|
6
6
|
Business Layer never sees `pg` errors.
|
|
7
7
|
|
|
8
|
-
Peer dependencies: [`@xfcfam/xf`](https://www.npmjs.com/package/@xfcfam/xf)
|
|
9
|
-
[`@xfcfam/xf-sql`](https://www.npmjs.com/package/@xfcfam/xf-sql)
|
|
10
|
-
[`
|
|
11
|
-
|
|
8
|
+
Peer dependencies: [`@xfcfam/xf`](https://www.npmjs.com/package/@xfcfam/xf)
|
|
9
|
+
and [`@xfcfam/xf-sql`](https://www.npmjs.com/package/@xfcfam/xf-sql). The
|
|
10
|
+
[`pg`](https://node-postgres.com) driver and the
|
|
11
|
+
[`kysely`](https://kysely.dev) query builder are **bundled and wired
|
|
12
|
+
internally**: the adapter builds the `pg.Pool` and the `PostgresDialect`
|
|
13
|
+
for you in its constructor, so the implementer never installs or imports
|
|
14
|
+
either one (`kysely` arrives transitively through `@xfcfam/xf-sql`).
|
|
12
15
|
|
|
13
16
|
## Install
|
|
14
17
|
|
|
15
18
|
```bash
|
|
16
|
-
pnpm add @xfcfam/xf @xfcfam/xf-sql @xfcfam/xf-sql-postgres
|
|
19
|
+
pnpm add @xfcfam/xf @xfcfam/xf-sql @xfcfam/xf-sql-postgres
|
|
17
20
|
```
|
|
18
21
|
|
|
19
22
|
## What ships here
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xfcfam/xf-sql-postgres",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "PostgreSQL dialect adapter for @xfcfam/xf-sql. Encapsulates kysely's PostgresDialect and the `pg` driver. Translates Postgres SQLSTATE codes into the typed Exceptions of @xfcfam/xf-sql.",
|
|
5
5
|
"author": "XF Contributors",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,16 +35,16 @@
|
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
|
-
"@xfcfam/xf
|
|
39
|
-
"@xfcfam/xf": "^0.2
|
|
38
|
+
"@xfcfam/xf": "^0.2.0",
|
|
39
|
+
"@xfcfam/xf-sql": "^0.1.2"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"pg": "^8.11.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"typescript": "^5.4.0",
|
|
46
|
-
"vitest": "^2.
|
|
47
|
-
"kysely": "^0.
|
|
46
|
+
"vitest": "^3.2.6",
|
|
47
|
+
"kysely": "^0.28.17",
|
|
48
48
|
"@types/pg": "^8.11.0"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { TransactionalDatabaseRepository } from '@xfarch/xf-sql';
|
|
2
|
-
import { type PoolConfig } from 'pg';
|
|
3
|
-
/**
|
|
4
|
-
* Configuration accepted by {@link PostgresDatabaseRepository}'s
|
|
5
|
-
* constructor.
|
|
6
|
-
*
|
|
7
|
-
* Either provide a `connectionString` (the simplest path), a full
|
|
8
|
-
* `pg.PoolConfig`, or both — they are merged with the connection
|
|
9
|
-
* string taking precedence for connection coordinates.
|
|
10
|
-
*/
|
|
11
|
-
export interface PostgresOptions {
|
|
12
|
-
/** Postgres connection string (`postgres://user:pass@host:port/db?…`). */
|
|
13
|
-
connectionString?: string;
|
|
14
|
-
/** Extra `pg.PoolConfig` fields: `max`, `idleTimeoutMillis`, `ssl`, … */
|
|
15
|
-
pool?: PoolConfig;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Ready-to-use Generalization for the Access Layer when the backing
|
|
19
|
-
* store is **PostgreSQL**.
|
|
20
|
-
*
|
|
21
|
-
* Wraps `kysely`'s `PostgresDialect` over the `pg` driver behind a
|
|
22
|
-
* single XF-canonical class. The implementer's concrete Logical
|
|
23
|
-
* extends this and exposes domain-meaningful methods that compose
|
|
24
|
-
* queries against `this.db`. Transactions via `this.transaction(...)`,
|
|
25
|
-
* one-shot error translation via `this.exec(...)`.
|
|
26
|
-
*
|
|
27
|
-
* The default `translateError` maps Postgres SQLSTATE codes to the
|
|
28
|
-
* typed Exceptions exported from `@xfarch/xf-sql`
|
|
29
|
-
* (`UniqueViolationException`, `ForeignKeyViolationException`,
|
|
30
|
-
* `CheckViolationException`, `NotNullViolationException`,
|
|
31
|
-
* `DeadlockException`) and transport-level errors (`ECONNREFUSED`,
|
|
32
|
-
* `ETIMEDOUT`, …) to `ConnectionException`. The implementer's
|
|
33
|
-
* Business Layer never sees `pg` types.
|
|
34
|
-
*
|
|
35
|
-
* @typeParam Schema Implementer-defined TypeScript interface mapping
|
|
36
|
-
* table names to their column shapes.
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* ```ts
|
|
40
|
-
* import { PostgresDatabaseRepository } from '@xfarch/xf-sql-postgres'
|
|
41
|
-
* import { UniqueViolationException } from '@xfarch/xf-sql'
|
|
42
|
-
*
|
|
43
|
-
* interface Schema {
|
|
44
|
-
* users: { id: number; name: string; email: string; created_at: Date }
|
|
45
|
-
* }
|
|
46
|
-
*
|
|
47
|
-
* export class UsersDb extends PostgresDatabaseRepository<Schema> {
|
|
48
|
-
* constructor() {
|
|
49
|
-
* super({
|
|
50
|
-
* connectionString: process.env.DATABASE_URL!,
|
|
51
|
-
* pool: { max: 10, idleTimeoutMillis: 30_000 },
|
|
52
|
-
* })
|
|
53
|
-
* }
|
|
54
|
-
* async init() { await super.init() } // ← required
|
|
55
|
-
* async terminate() { await super.terminate() } // ← required
|
|
56
|
-
*
|
|
57
|
-
* getUser(id: number) {
|
|
58
|
-
* return this.exec(() =>
|
|
59
|
-
* this.db.selectFrom('users').where('id', '=', id).selectAll().executeTakeFirstOrThrow()
|
|
60
|
-
* )
|
|
61
|
-
* }
|
|
62
|
-
*
|
|
63
|
-
* async createUser(input: { name: string; email: string }) {
|
|
64
|
-
* try {
|
|
65
|
-
* return await this.exec(() =>
|
|
66
|
-
* this.db.insertInto('users').values({ ...input, created_at: new Date() }).returningAll().executeTakeFirstOrThrow()
|
|
67
|
-
* )
|
|
68
|
-
* } catch (err) {
|
|
69
|
-
* if (err instanceof UniqueViolationException && err.column === 'email') {
|
|
70
|
-
* throw new DomainError('Email already registered')
|
|
71
|
-
* }
|
|
72
|
-
* throw err
|
|
73
|
-
* }
|
|
74
|
-
* }
|
|
75
|
-
* }
|
|
76
|
-
* ```
|
|
77
|
-
*/
|
|
78
|
-
export declare abstract class PostgresDatabaseRepository<Schema = unknown> extends TransactionalDatabaseRepository<Schema> {
|
|
79
|
-
constructor(options: PostgresOptions);
|
|
80
|
-
/**
|
|
81
|
-
* Translate `pg` / Kysely driver errors into the typed Exceptions
|
|
82
|
-
* exported from `@xfarch/xf-sql`. Delegates to
|
|
83
|
-
* {@link PostgresErrorUtils.translate}.
|
|
84
|
-
*
|
|
85
|
-
* Subclasses may override to layer additional mappings on top, but
|
|
86
|
-
* should `return super.translateError(err)` for unrecognised
|
|
87
|
-
* errors so the base policy still applies.
|
|
88
|
-
*/
|
|
89
|
-
protected translateError(err: unknown): unknown;
|
|
90
|
-
}
|
|
91
|
-
//# sourceMappingURL=PostgresDatabaseRepository.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PostgresDatabaseRepository.d.ts","sourceRoot":"","sources":["../../../../src/repository/base/PostgresDatabaseRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAA;AAEhE,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,IAAI,CAAA;AAG1C;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,yEAAyE;IACzE,IAAI,CAAC,EAAE,UAAU,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,8BAAsB,0BAA0B,CAAC,MAAM,GAAG,OAAO,CAC/D,SAAQ,+BAA+B,CAAC,MAAM,CAAC;gBAEnC,OAAO,EAAE,eAAe;IASpC;;;;;;;;OAQG;cACgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO;CAGzD"}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { TransactionalDatabaseRepository } from '@xfarch/xf-sql';
|
|
2
|
-
import { PostgresDialect } from 'kysely';
|
|
3
|
-
import { Pool } from 'pg';
|
|
4
|
-
import { PostgresErrorUtils } from '../utils/PostgresErrorUtils.js';
|
|
5
|
-
/**
|
|
6
|
-
* Ready-to-use Generalization for the Access Layer when the backing
|
|
7
|
-
* store is **PostgreSQL**.
|
|
8
|
-
*
|
|
9
|
-
* Wraps `kysely`'s `PostgresDialect` over the `pg` driver behind a
|
|
10
|
-
* single XF-canonical class. The implementer's concrete Logical
|
|
11
|
-
* extends this and exposes domain-meaningful methods that compose
|
|
12
|
-
* queries against `this.db`. Transactions via `this.transaction(...)`,
|
|
13
|
-
* one-shot error translation via `this.exec(...)`.
|
|
14
|
-
*
|
|
15
|
-
* The default `translateError` maps Postgres SQLSTATE codes to the
|
|
16
|
-
* typed Exceptions exported from `@xfarch/xf-sql`
|
|
17
|
-
* (`UniqueViolationException`, `ForeignKeyViolationException`,
|
|
18
|
-
* `CheckViolationException`, `NotNullViolationException`,
|
|
19
|
-
* `DeadlockException`) and transport-level errors (`ECONNREFUSED`,
|
|
20
|
-
* `ETIMEDOUT`, …) to `ConnectionException`. The implementer's
|
|
21
|
-
* Business Layer never sees `pg` types.
|
|
22
|
-
*
|
|
23
|
-
* @typeParam Schema Implementer-defined TypeScript interface mapping
|
|
24
|
-
* table names to their column shapes.
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```ts
|
|
28
|
-
* import { PostgresDatabaseRepository } from '@xfarch/xf-sql-postgres'
|
|
29
|
-
* import { UniqueViolationException } from '@xfarch/xf-sql'
|
|
30
|
-
*
|
|
31
|
-
* interface Schema {
|
|
32
|
-
* users: { id: number; name: string; email: string; created_at: Date }
|
|
33
|
-
* }
|
|
34
|
-
*
|
|
35
|
-
* export class UsersDb extends PostgresDatabaseRepository<Schema> {
|
|
36
|
-
* constructor() {
|
|
37
|
-
* super({
|
|
38
|
-
* connectionString: process.env.DATABASE_URL!,
|
|
39
|
-
* pool: { max: 10, idleTimeoutMillis: 30_000 },
|
|
40
|
-
* })
|
|
41
|
-
* }
|
|
42
|
-
* async init() { await super.init() } // ← required
|
|
43
|
-
* async terminate() { await super.terminate() } // ← required
|
|
44
|
-
*
|
|
45
|
-
* getUser(id: number) {
|
|
46
|
-
* return this.exec(() =>
|
|
47
|
-
* this.db.selectFrom('users').where('id', '=', id).selectAll().executeTakeFirstOrThrow()
|
|
48
|
-
* )
|
|
49
|
-
* }
|
|
50
|
-
*
|
|
51
|
-
* async createUser(input: { name: string; email: string }) {
|
|
52
|
-
* try {
|
|
53
|
-
* return await this.exec(() =>
|
|
54
|
-
* this.db.insertInto('users').values({ ...input, created_at: new Date() }).returningAll().executeTakeFirstOrThrow()
|
|
55
|
-
* )
|
|
56
|
-
* } catch (err) {
|
|
57
|
-
* if (err instanceof UniqueViolationException && err.column === 'email') {
|
|
58
|
-
* throw new DomainError('Email already registered')
|
|
59
|
-
* }
|
|
60
|
-
* throw err
|
|
61
|
-
* }
|
|
62
|
-
* }
|
|
63
|
-
* }
|
|
64
|
-
* ```
|
|
65
|
-
*/
|
|
66
|
-
export class PostgresDatabaseRepository extends TransactionalDatabaseRepository {
|
|
67
|
-
constructor(options) {
|
|
68
|
-
const poolConfig = { ...options.pool };
|
|
69
|
-
if (options.connectionString !== undefined) {
|
|
70
|
-
poolConfig.connectionString = options.connectionString;
|
|
71
|
-
}
|
|
72
|
-
const pool = new Pool(poolConfig);
|
|
73
|
-
super({ dialect: new PostgresDialect({ pool }) });
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Translate `pg` / Kysely driver errors into the typed Exceptions
|
|
77
|
-
* exported from `@xfarch/xf-sql`. Delegates to
|
|
78
|
-
* {@link PostgresErrorUtils.translate}.
|
|
79
|
-
*
|
|
80
|
-
* Subclasses may override to layer additional mappings on top, but
|
|
81
|
-
* should `return super.translateError(err)` for unrecognised
|
|
82
|
-
* errors so the base policy still applies.
|
|
83
|
-
*/
|
|
84
|
-
translateError(err) {
|
|
85
|
-
return PostgresErrorUtils.translate(err);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
//# sourceMappingURL=PostgresDatabaseRepository.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PostgresDatabaseRepository.js","sourceRoot":"","sources":["../../../../src/repository/base/PostgresDatabaseRepository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAA;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAA;AACxC,OAAO,EAAE,IAAI,EAAmB,MAAM,IAAI,CAAA;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AAiBnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,MAAM,OAAgB,0BACpB,SAAQ,+BAAuC;IAE/C,YAAY,OAAwB;QAClC,MAAM,UAAU,GAAe,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAA;QAClD,IAAI,OAAO,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;YAC3C,UAAU,CAAC,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAA;QACxD,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAA;QACjC,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAA;IACnD,CAAC;IAED;;;;;;;;OAQG;IACgB,cAAc,CAAC,GAAY;QAC5C,OAAO,kBAAkB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;IAC1C,CAAC;CACF"}
|