kysely-repo-kit 0.2.3 → 0.2.5
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 +286 -0
- package/dist/builder.d.ts +12 -2
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +30 -3
- package/dist/builder.js.map +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# Kysely Repo Kit 🛡️🚀
|
|
2
|
+
|
|
3
|
+
A fully typed repository, relation population, and hook layer for [Kysely](https://github.com/kysely-org/kysely).
|
|
4
|
+
|
|
5
|
+
`kysely-repo-kit` provides a declarative, type-safe API to construct repositories with native soft-delete support, life-cycle hooks, complex filtering (`AND`, `OR`, `NOT`, `jsonb`, and raw expressions), and nested relation populating using high-performance JSON helpers.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **🛡️ 100% Type-Safe**: Complete autocomplete and compile-time type safety for inserts, updates, filters, selects, and nested population.
|
|
12
|
+
- **🔄 Auto-Population**: Effortlessly load relations (1-to-1 or 1-to-many) using native, highly optimized Postgres JSON helper functions (`jsonArrayFrom`, `jsonObjectFrom`).
|
|
13
|
+
- **🪝 Lifecycle Hooks**: Intercept database actions using `beforeCreate`, `afterCreate`, `beforeUpdate`, `afterUpdate`, `beforeDelete`, and `afterDelete`.
|
|
14
|
+
- **🗑️ Native Soft Delete**: Easily set up table-wide soft deletes. Safely filter out deleted records automatically across queries and populations.
|
|
15
|
+
- **🧩 Power Queries**: Multi-faceted filter system supporting nested `AND` / `OR` / `NOT`, Case-insensitive text searches, Jsonb paths filtering, and raw SQL escapes.
|
|
16
|
+
- **🤝 Transaction Session Propagation**: Easily pass Kysely transactions down using `.withSession(tx)`.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# With pnpm (recommended)
|
|
24
|
+
pnpm add kysely-repo-kit
|
|
25
|
+
|
|
26
|
+
# With npm
|
|
27
|
+
npm install kysely-repo-kit
|
|
28
|
+
|
|
29
|
+
# With yarn
|
|
30
|
+
yarn add kysely-repo-kit
|
|
31
|
+
|
|
32
|
+
# With bun
|
|
33
|
+
bun add kysely-repo-kit
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
*Note: `kysely` is a peer dependency of this library and must be installed in your project.*
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
### 1. Define your Database Schema & Types
|
|
43
|
+
|
|
44
|
+
Let's assume you have a typical Kysely database definition:
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { Kysely } from 'kysely';
|
|
48
|
+
|
|
49
|
+
export interface UserTable {
|
|
50
|
+
id: string;
|
|
51
|
+
email: string;
|
|
52
|
+
name: string;
|
|
53
|
+
created_at: Date;
|
|
54
|
+
deleted_at: Date | null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface PostTable {
|
|
58
|
+
id: string;
|
|
59
|
+
title: string;
|
|
60
|
+
content: string;
|
|
61
|
+
author_id: string;
|
|
62
|
+
created_at: Date;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface Database {
|
|
66
|
+
users: UserTable;
|
|
67
|
+
posts: PostTable;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const db = new Kysely<Database>({ ... });
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 2. Create the Repository Builder
|
|
74
|
+
|
|
75
|
+
Create a single instance of your repository builder associated with your `Database` type:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { createRepoBuilder } from 'kysely-repo-kit';
|
|
79
|
+
import { Database } from './db';
|
|
80
|
+
|
|
81
|
+
export const repoBuilder = createRepoBuilder<Database>();
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### 3. Build & Define Your Repositories
|
|
85
|
+
|
|
86
|
+
Using the builder, we declare relations, soft delete rules, hooks, and compile them into executable repository classes.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { repoBuilder } from './builder';
|
|
90
|
+
|
|
91
|
+
// Define PostRepository
|
|
92
|
+
export const PostRepository = repoBuilder
|
|
93
|
+
.table('posts')
|
|
94
|
+
.init;
|
|
95
|
+
|
|
96
|
+
// Define UserRepository with soft delete, hooks, and relationships
|
|
97
|
+
export const UserRepository = repoBuilder
|
|
98
|
+
.table('users')
|
|
99
|
+
.softDelete('deleted_at') // Automatically filters out soft-deleted users
|
|
100
|
+
.hooks({
|
|
101
|
+
beforeCreate: (data) => {
|
|
102
|
+
// Intercept and mutate data before inserting
|
|
103
|
+
return { ...data, name: data.name.trim() };
|
|
104
|
+
},
|
|
105
|
+
afterCreate: (user) => {
|
|
106
|
+
console.log(`User created: ${user.email}`);
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
.populate({
|
|
110
|
+
as: 'posts',
|
|
111
|
+
ref: 'posts',
|
|
112
|
+
foreignKey: 'author_id', // links posts.author_id to users.id
|
|
113
|
+
})
|
|
114
|
+
.init;
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 4. Perform Queries
|
|
118
|
+
|
|
119
|
+
Instantiate the repository classes with your Kysely database instance.
|
|
120
|
+
|
|
121
|
+
```typescript
|
|
122
|
+
import { db } from './db';
|
|
123
|
+
import { UserRepository } from './repositories';
|
|
124
|
+
|
|
125
|
+
const userRepo = new UserRepository(db);
|
|
126
|
+
|
|
127
|
+
// 1. Create a user
|
|
128
|
+
const newUser = await userRepo.create({
|
|
129
|
+
data: {
|
|
130
|
+
id: 'user-1',
|
|
131
|
+
email: 'alice@example.com',
|
|
132
|
+
name: ' Alice ',
|
|
133
|
+
}
|
|
134
|
+
}); // Hooks trim name automatically! -> 'Alice'
|
|
135
|
+
|
|
136
|
+
// 2. Query with type-safe nested relations population
|
|
137
|
+
const userWithPosts = await userRepo.findFirst({
|
|
138
|
+
where: { id: 'user-1' },
|
|
139
|
+
populate: {
|
|
140
|
+
posts: true // Auto-loaded via Postgres JSON serialization
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
console.log(userWithPosts?.posts); // Type-safe Array of Post records!
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Detailed Usage Guide
|
|
150
|
+
|
|
151
|
+
### CRUD Interface
|
|
152
|
+
|
|
153
|
+
Every generated repository inherits from `BaseRepository` and exposes the following API:
|
|
154
|
+
|
|
155
|
+
#### Retrieve Queries
|
|
156
|
+
* **`findMany({ where, select, populate, skip, take, orderBy, lock, includeDeleted })`**
|
|
157
|
+
* **`findFirst({ where, select, populate, lock, includeDeleted })`**
|
|
158
|
+
* **`findUnique({ where: { id }, select, populate, includeDeleted })`**
|
|
159
|
+
* **`count({ where, includeDeleted })`**
|
|
160
|
+
* **`exists({ where, includeDeleted })`**
|
|
161
|
+
|
|
162
|
+
#### Mutation Queries
|
|
163
|
+
* **`create({ data, select })`**
|
|
164
|
+
* **`createMany({ data })`**
|
|
165
|
+
* **`update({ where, data, select })`**
|
|
166
|
+
* **`updateUnique({ where: { id }, data, select })`**
|
|
167
|
+
* **`updateMany({ where, data })`**
|
|
168
|
+
* **`upsert({ where, create, update })`**
|
|
169
|
+
* **`delete({ where })`** (performs soft-delete if enabled, otherwise hard-delete)
|
|
170
|
+
* **`softDelete({ where, deletedAt })`** (explicitly soft-delete records)
|
|
171
|
+
* **`hardDelete({ where })`** (explicitly hard-delete records)
|
|
172
|
+
* **`deleteUnique({ where: { id } })`**
|
|
173
|
+
* **`deleteMany({ where })`**
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
### Rich Filtering (`WhereFilter`)
|
|
178
|
+
|
|
179
|
+
`kysely-repo-kit` provides a powerful, type-safe filtering engine.
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
const activePremiumUsers = await userRepo.findMany({
|
|
183
|
+
where: {
|
|
184
|
+
// 1. Column filters with specific matching options
|
|
185
|
+
name: {
|
|
186
|
+
contains: 'John',
|
|
187
|
+
mode: 'insensitive', // case-insensitive LIKE
|
|
188
|
+
},
|
|
189
|
+
// 2. OR / AND / NOT operators
|
|
190
|
+
OR: [
|
|
191
|
+
{ email: { endsWith: '@gmail.com' } },
|
|
192
|
+
{ email: { endsWith: '@outlook.com' } }
|
|
193
|
+
],
|
|
194
|
+
// 3. Raw Kysely expression fallback
|
|
195
|
+
_raw: (eb) => eb('created_at', '>', sql`NOW() - INTERVAL '30 days'`)
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### JSONB Filtering
|
|
201
|
+
Filter records by deeply nested keys within Postgres `JSONB` columns using type-safe path matching:
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
const users = await userRepo.findMany({
|
|
205
|
+
where: {
|
|
206
|
+
jsonb: {
|
|
207
|
+
'metadata.profile.theme': 'dark', // Type-safe leaf path matching!
|
|
208
|
+
'metadata.loginCount': { gte: 10 }
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
### Relation Populations
|
|
217
|
+
|
|
218
|
+
To populate complex, deeply nested relational schemas, declare relationship rules on the builder:
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
export const OrganisationRepository = repoBuilder
|
|
222
|
+
.table('organisations')
|
|
223
|
+
.init;
|
|
224
|
+
|
|
225
|
+
export const UserRepository = repoBuilder
|
|
226
|
+
.table('users')
|
|
227
|
+
.populate({
|
|
228
|
+
as: 'org',
|
|
229
|
+
ref: 'organisations',
|
|
230
|
+
foreignKey: 'id',
|
|
231
|
+
localKey: 'org_id',
|
|
232
|
+
justOne: true, // Populates as single object instead of an array
|
|
233
|
+
})
|
|
234
|
+
.populate({
|
|
235
|
+
as: 'posts',
|
|
236
|
+
ref: 'posts',
|
|
237
|
+
foreignKey: 'author_id',
|
|
238
|
+
nestedPopulations: () => ({
|
|
239
|
+
// Recursively nest population options!
|
|
240
|
+
comments: definePopulation({
|
|
241
|
+
table: 'comments',
|
|
242
|
+
foreignKey: 'post_id',
|
|
243
|
+
})
|
|
244
|
+
})
|
|
245
|
+
})
|
|
246
|
+
.init;
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Query with populated relations dynamically:
|
|
250
|
+
```typescript
|
|
251
|
+
const result = await userRepo.findMany({
|
|
252
|
+
populate: {
|
|
253
|
+
org: {
|
|
254
|
+
select: { id: true, name: true } // Limit columns returned by relation
|
|
255
|
+
},
|
|
256
|
+
posts: {
|
|
257
|
+
populate: {
|
|
258
|
+
comments: true // Nested population loaded automatically!
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
### Transactions & Session Propagation
|
|
268
|
+
|
|
269
|
+
To run operations safely within a database transaction, leverage the `.withSession()` method:
|
|
270
|
+
|
|
271
|
+
```typescript
|
|
272
|
+
await db.transaction().execute(async (tx) => {
|
|
273
|
+
// Spawn repository instances bound to the transaction session
|
|
274
|
+
const userRepoTx = userRepo.withSession(tx);
|
|
275
|
+
const postRepoTx = new PostRepository(db).withSession(tx);
|
|
276
|
+
|
|
277
|
+
const user = await userRepoTx.create({ data: { ... } });
|
|
278
|
+
await postRepoTx.create({ data: { author_id: user.id, ... } });
|
|
279
|
+
});
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## License
|
|
285
|
+
|
|
286
|
+
MIT © [jesulonimii](https://github.com/jesulonimii)
|
package/dist/builder.d.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import type { Kysely, Selectable, Transaction } from "kysely";
|
|
1
|
+
import type { Insertable, Kysely, Selectable, Transaction, Updateable } from "kysely";
|
|
2
2
|
import BaseRepository, { type InferTable, type PopulateInput, type PopulationMap, type SelectInput, type SoftDeleteRegistry, type WhereFilter } from "./base";
|
|
3
3
|
type EmptyPopulations = Record<never, never>;
|
|
4
|
+
type HooksConfig<DB, TableName extends keyof DB & string, Table extends object> = {
|
|
5
|
+
beforeCreate?: (data: Insertable<DB[TableName]>) => Promise<Insertable<DB[TableName]>> | Insertable<DB[TableName]>;
|
|
6
|
+
beforeUpdate?: (data: Updateable<DB[TableName]>, where: WhereFilter<DB, TableName, Table>) => Promise<Updateable<DB[TableName]>> | Updateable<DB[TableName]>;
|
|
7
|
+
beforeDelete?: (where: WhereFilter<DB, TableName, Table>) => Promise<void> | void;
|
|
8
|
+
afterCreate?: (row: Selectable<Table>) => Promise<void> | void;
|
|
9
|
+
afterUpdate?: (row: Selectable<Table> | null) => Promise<void> | void;
|
|
10
|
+
afterDelete?: (row: Selectable<Table> | null) => Promise<void> | void;
|
|
11
|
+
};
|
|
4
12
|
type InferSelectableRow<DB, TableName extends keyof DB & string> = DB[TableName] extends object ? Selectable<DB[TableName]> : never;
|
|
5
13
|
type InferRow<DB, TableName extends keyof DB & string> = DB[TableName] extends object ? Selectable<DB[TableName]> : never;
|
|
6
14
|
export type RepoInstance<DB, TableName extends keyof DB & string, Populations extends PopulationMap<DB>> = BaseRepository<DB, TableName, Populations> & {
|
|
@@ -32,8 +40,10 @@ declare class RepoBuilder<DB, TableName extends keyof DB & string, Populations e
|
|
|
32
40
|
private readonly currentPopulations;
|
|
33
41
|
private readonly currentSoftDeleteColumn?;
|
|
34
42
|
private readonly softDeleteRegistry?;
|
|
35
|
-
|
|
43
|
+
private readonly currentHooks?;
|
|
44
|
+
constructor(currentTableName: TableName, currentPopulations?: Populations, currentSoftDeleteColumn?: (keyof Selectable<Table> & string) | undefined, softDeleteRegistry?: SoftDeleteRegistry<DB> | undefined, currentHooks?: HooksConfig<DB, TableName, Table> | undefined);
|
|
36
45
|
softDelete<Column extends keyof Selectable<Table> & string>(column: Column | false): RepoBuilder<DB, TableName, Populations, Table>;
|
|
46
|
+
hooks(config: HooksConfig<DB, TableName, Table>): RepoBuilder<DB, TableName, Populations, Table>;
|
|
37
47
|
populate<Name extends string, Ref extends keyof DB & string, NestedPopulations extends PopulationMap<DB> = Record<never, never>>(def: PopulateConfig<DB, Name, Ref, NestedPopulations>): RepoBuilder<DB, TableName, Populations & Record<Name, import("./base").PopulationDefinition<DB, InferRow<DB, Ref> extends infer T ? T extends InferRow<DB, Ref> ? T extends any[] ? T : import("kysely").DrainOuterGeneric<{ [K_1 in { [K in keyof T]: import("kysely").SelectType<T[K]> extends infer T_1 ? T_1 extends import("kysely").SelectType<T[K]> ? T_1 extends never ? never : K : never : never; }[keyof T]]: import("kysely").SelectType<T[K_1]>; }> : never : never, NestedPopulations> & {
|
|
38
48
|
justOne: true;
|
|
39
49
|
}>, Table>;
|
package/dist/builder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
|
package/dist/builder.js
CHANGED
|
@@ -4,15 +4,20 @@ class RepoBuilder {
|
|
|
4
4
|
currentPopulations;
|
|
5
5
|
currentSoftDeleteColumn;
|
|
6
6
|
softDeleteRegistry;
|
|
7
|
-
|
|
7
|
+
currentHooks;
|
|
8
|
+
constructor(currentTableName, currentPopulations = {}, currentSoftDeleteColumn, softDeleteRegistry, currentHooks) {
|
|
8
9
|
this.currentTableName = currentTableName;
|
|
9
10
|
this.currentPopulations = currentPopulations;
|
|
10
11
|
this.currentSoftDeleteColumn = currentSoftDeleteColumn;
|
|
11
12
|
this.softDeleteRegistry = softDeleteRegistry;
|
|
13
|
+
this.currentHooks = currentHooks;
|
|
12
14
|
}
|
|
13
15
|
softDelete(column) {
|
|
14
16
|
this.softDeleteRegistry?.set(this.currentTableName, column === false ? false : column);
|
|
15
|
-
return new RepoBuilder(this.currentTableName, this.currentPopulations, (column === false ? undefined : column), this.softDeleteRegistry);
|
|
17
|
+
return new RepoBuilder(this.currentTableName, this.currentPopulations, (column === false ? undefined : column), this.softDeleteRegistry, this.currentHooks);
|
|
18
|
+
}
|
|
19
|
+
hooks(config) {
|
|
20
|
+
return new RepoBuilder(this.currentTableName, this.currentPopulations, this.currentSoftDeleteColumn, this.softDeleteRegistry, config);
|
|
16
21
|
}
|
|
17
22
|
populate(def) {
|
|
18
23
|
const isSingle = Boolean(def.localKey || def.justOne);
|
|
@@ -31,13 +36,14 @@ class RepoBuilder {
|
|
|
31
36
|
return new RepoBuilder(this.currentTableName, {
|
|
32
37
|
...this.currentPopulations,
|
|
33
38
|
[def.as]: population,
|
|
34
|
-
}, this.currentSoftDeleteColumn, this.softDeleteRegistry);
|
|
39
|
+
}, this.currentSoftDeleteColumn, this.softDeleteRegistry, this.currentHooks);
|
|
35
40
|
}
|
|
36
41
|
get init() {
|
|
37
42
|
const tableName = this.currentTableName;
|
|
38
43
|
const populations = this.currentPopulations;
|
|
39
44
|
const softDeleteColumn = this.currentSoftDeleteColumn;
|
|
40
45
|
const softDeleteRegistry = this.softDeleteRegistry;
|
|
46
|
+
const hooksConfig = this.currentHooks;
|
|
41
47
|
class GeneratedRepository extends BaseRepository {
|
|
42
48
|
static tableName = tableName;
|
|
43
49
|
static populations = populations;
|
|
@@ -54,6 +60,27 @@ class RepoBuilder {
|
|
|
54
60
|
opts() {
|
|
55
61
|
return {};
|
|
56
62
|
}
|
|
63
|
+
async beforeCreate(data) {
|
|
64
|
+
return hooksConfig?.beforeCreate ? hooksConfig.beforeCreate(data) : data;
|
|
65
|
+
}
|
|
66
|
+
async beforeUpdate(data, where) {
|
|
67
|
+
return hooksConfig?.beforeUpdate ? hooksConfig.beforeUpdate(data, where) : data;
|
|
68
|
+
}
|
|
69
|
+
async beforeDelete(where) {
|
|
70
|
+
await hooksConfig?.beforeDelete?.(where);
|
|
71
|
+
}
|
|
72
|
+
async afterCreate(row) {
|
|
73
|
+
await hooksConfig?.afterCreate?.(row);
|
|
74
|
+
return row;
|
|
75
|
+
}
|
|
76
|
+
async afterUpdate(row) {
|
|
77
|
+
await hooksConfig?.afterUpdate?.(row);
|
|
78
|
+
return row;
|
|
79
|
+
}
|
|
80
|
+
async afterDelete(row) {
|
|
81
|
+
await hooksConfig?.afterDelete?.(row);
|
|
82
|
+
return row;
|
|
83
|
+
}
|
|
57
84
|
}
|
|
58
85
|
return GeneratedRepository;
|
|
59
86
|
}
|
package/dist/builder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAEA,OAAO,cAAc,EAAE,EACnB,gBAAgB,GAOnB,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
|