kysely-rizzolver 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +21 -0
- package/README.md +147 -0
- package/dist/cjs/fetch-result-factory.d.ts +52 -0
- package/dist/cjs/fetch-result-factory.js +88 -0
- package/dist/cjs/fetch-result.d.ts +111 -0
- package/dist/cjs/fetch-result.js +117 -0
- package/dist/cjs/index.d.ts +10 -0
- package/dist/cjs/index.js +21 -0
- package/dist/cjs/kysely-rizzolver.d.ts +138 -0
- package/dist/cjs/kysely-rizzolver.js +147 -0
- package/dist/cjs/model-collection.d.ts +26 -0
- package/dist/cjs/model-collection.js +24 -0
- package/dist/cjs/query-builder.d.ts +156 -0
- package/dist/cjs/query-builder.js +92 -0
- package/dist/cjs/selector.d.ts +72 -0
- package/dist/cjs/selector.js +45 -0
- package/dist/cjs/type-helpers.d.ts +11 -0
- package/dist/cjs/type-helpers.js +2 -0
- package/dist/esm/fetch-result-factory.js +85 -0
- package/dist/esm/fetch-result.js +105 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/kysely-rizzolver.js +143 -0
- package/dist/esm/model-collection.js +21 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/query-builder.js +89 -0
- package/dist/esm/selector.js +42 -0
- package/dist/esm/type-helpers.js +1 -0
- package/dist/types/fetch-result-factory.d.ts +52 -0
- package/dist/types/fetch-result.d.ts +111 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/kysely-rizzolver.d.ts +138 -0
- package/dist/types/model-collection.d.ts +26 -0
- package/dist/types/query-builder.d.ts +156 -0
- package/dist/types/selector.d.ts +72 -0
- package/dist/types/type-helpers.d.ts +11 -0
- package/package.json +32 -0
package/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Yariv
|
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,147 @@
|
|
1
|
+
# Kysely Rizzolver
|
2
|
+
|
3
|
+
Complex Kysely queries, maximum rizz, type-safe every time.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
Kysely Rizzolver is a utility library for building complex, type-safe queries.
|
8
|
+
|
9
|
+
There are already a bunch of [awesome
|
10
|
+
tools](https://github.com/kysely-org/awesome-kysely) for working with Kysely out
|
11
|
+
there, but none strike the balance I'm looking for:
|
12
|
+
- [kysely-orm](https://github.com/seeeden/kysely-orm) is a full-fledged ORM.
|
13
|
+
It's a really cool project, but like all ORMs it works until it doesn't. If
|
14
|
+
you need fine control over your queries, it gets very cumbersome.
|
15
|
+
- [kysely-mapper](https://github.com/jtlapp/kysely-mapper) is a bit more
|
16
|
+
lightweight than an ORM, but it still wraps Kysely with a "hatch" to an
|
17
|
+
underlying Kysely instance. It is also quite verbose and rigid in my opinion.
|
18
|
+
|
19
|
+
Kysely Rizzolver in constast, works *with* Kysely. It does not replace, wrap,
|
20
|
+
abstract or hide it and can be incrementally added to an existing Kysely
|
21
|
+
project.
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
You can install it via npm:
|
26
|
+
|
27
|
+
```sh
|
28
|
+
npm install kysely-rizzolver
|
29
|
+
```
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
### Creating a KyselyRizzolver
|
34
|
+
|
35
|
+
`KyselyRizzolver` is the heart of Kysely Rizzolver. It is a definition of the
|
36
|
+
table names and columns in your database.
|
37
|
+
|
38
|
+
```typescript
|
39
|
+
import { KyselyRizzolver } from 'kysely-rizzolver';
|
40
|
+
|
41
|
+
const rizzolver = KyselyRizzolver.builderNoSchema()
|
42
|
+
.table('user', ['id', 'name', 'email'] as const)
|
43
|
+
.table('post', ['id', 'title', 'content', 'authorId'] as const)
|
44
|
+
.build();
|
45
|
+
```
|
46
|
+
|
47
|
+
or if you have a schema, for example from [kysely-codegen](https://github.com/RobinBlomberg/kysely-codegen), you can use it like this:
|
48
|
+
|
49
|
+
```typescript
|
50
|
+
import { KyselyRizzolver } from 'kysely-rizzolver';
|
51
|
+
import { DB } from './db-types-generated';
|
52
|
+
|
53
|
+
const rizzolver = KyselyRizzolver.builderForSchema<DB>()
|
54
|
+
.table('user', ['id', 'name', 'email'] as const)
|
55
|
+
.table('post', ['id', 'title', 'content', 'authorId'] as const)
|
56
|
+
.build();
|
57
|
+
```
|
58
|
+
|
59
|
+
You will get compile time errors if the fields don't actually match the schema.
|
60
|
+
|
61
|
+
### Creating a Query Builder
|
62
|
+
|
63
|
+
```typescript
|
64
|
+
import { rizzolver } from './rizzolver';
|
65
|
+
|
66
|
+
const qb = await rizzolver
|
67
|
+
.newQueryBuilder()
|
68
|
+
.add('session', 's')
|
69
|
+
.add('user', 'u')
|
70
|
+
.add('image', 'i');
|
71
|
+
```
|
72
|
+
|
73
|
+
The query builder exposes expressions to use in queries. For example:
|
74
|
+
|
75
|
+
- `qb.table('u')` returns `'user as u'`.
|
76
|
+
- `qb.fieldsOf('u')` returns `['u.id as _u_id', 'u.name as _u_name', 'u.email as _u_email']`.
|
77
|
+
- `qb.field('u.name').value` returns `'_u_name'`.
|
78
|
+
- `qb.field('u.name').from('a')` returns `'a._u_name'`.
|
79
|
+
|
80
|
+
### Using a Query Builder
|
81
|
+
|
82
|
+
For example, we can use the query builder above to fetch for each session the
|
83
|
+
user it is associated with and their avatar image if it exists:
|
84
|
+
|
85
|
+
```typescript
|
86
|
+
const rows = await db
|
87
|
+
.selectFrom(qb.table('s'))
|
88
|
+
.innerJoin(
|
89
|
+
(eb) =>
|
90
|
+
eb
|
91
|
+
.selectFrom(qb.table('u'))
|
92
|
+
.leftJoin(qb.table('i'), 'u.avatar_image_id', 'i.id')
|
93
|
+
.select(qb.fieldsOf('u', 'i'))
|
94
|
+
.as('a'),
|
95
|
+
(join) => join.onRef('s.user_id', '=', `'a._u_id'`)
|
96
|
+
)
|
97
|
+
.select(qb.fieldsOf('s'))
|
98
|
+
.selectAll('a')
|
99
|
+
.where('s.id', '=', sessionId)
|
100
|
+
.execute();
|
101
|
+
```
|
102
|
+
|
103
|
+
Note that Kysely remains as the main driver of the query. This makes it easy to
|
104
|
+
incrementally switch to Kysely Rizzolver.
|
105
|
+
|
106
|
+
### Parsing the Results
|
107
|
+
|
108
|
+
The fetched rows can be parsed into type-safe objects using the same query
|
109
|
+
builder that was used to create the query, as such:
|
110
|
+
|
111
|
+
```typescript
|
112
|
+
const results = await qb.run(rows);
|
113
|
+
|
114
|
+
// To get the user model
|
115
|
+
const first = results.first?.selectors.u;
|
116
|
+
|
117
|
+
// To get the first user's avatar image url
|
118
|
+
const avatarUrl = results.first?.selectors.i?.url;
|
119
|
+
|
120
|
+
// To collect all avatar image urls
|
121
|
+
const avatarUrls = results.rows.map((row) => row.selectors.i?.url);
|
122
|
+
```
|
123
|
+
|
124
|
+
To make it easier to work with the results and pass them around, accept them as
|
125
|
+
parameters in other functions, etc., you can further process the results into a
|
126
|
+
`FetchResult`:
|
127
|
+
|
128
|
+
```typescript
|
129
|
+
// Fetches the first user, or returns undefined if there are no results.
|
130
|
+
const maybeOneUser = results.newFetchOneResult('u');
|
131
|
+
|
132
|
+
// Fetches the first user, and throws an error if there are no results.
|
133
|
+
const oneUser = results.newFetchOneXResult('u');
|
134
|
+
|
135
|
+
// Fetches all users. May return an empty array if there are no results.
|
136
|
+
const someUsers = results.newFetchSomeResult('u');
|
137
|
+
```
|
138
|
+
|
139
|
+
Play around with the query builder and the results to get a feel for how they
|
140
|
+
work.
|
141
|
+
|
142
|
+
Everything is type-safe end to end.
|
143
|
+
|
144
|
+
## License
|
145
|
+
|
146
|
+
This project is licensed under the MIT License. See the [LICENSE](./LICENSE)
|
147
|
+
file for details.
|
@@ -0,0 +1,52 @@
|
|
1
|
+
import type { Selectable } from 'kysely';
|
2
|
+
import { type FetchOneResult, type FetchOneXResult, type FetchSomeResult } from './fetch-result.js';
|
3
|
+
import { type ModelCollection } from './model-collection.js';
|
4
|
+
/**
|
5
|
+
* A {@link FetchResultFactory} exposes variants of fetch-related functions, but
|
6
|
+
* with the `DB` type parameter already set.
|
7
|
+
*
|
8
|
+
* This makes it less verbose to work with fetch results in a type-safe way.
|
9
|
+
*/
|
10
|
+
export type FetchResultFactory<DB> = ReturnType<typeof newFetchResultFactory<DB>>;
|
11
|
+
export declare function newFetchResultFactory<DB>(): {
|
12
|
+
/**
|
13
|
+
* Creates a new {@link FetchOneResult} instance.
|
14
|
+
*/
|
15
|
+
newFetchOne<K extends keyof DB & string>(table: K, result: Selectable<DB[K]> | undefined, models?: ModelCollection<DB>): FetchOneResult<DB, K, Selectable<DB[K]>>;
|
16
|
+
/**
|
17
|
+
* Creates a new {@link FetchOneXResult} instance.
|
18
|
+
*
|
19
|
+
* Note: it may be counterintuitive, but this function accepts `undefined` as
|
20
|
+
* input. I found it is way more convenient to assert the type once in this
|
21
|
+
* funciton rather than in every caller.
|
22
|
+
*/
|
23
|
+
newFetchOneX<K extends keyof DB & string>(table: K, result: Selectable<DB[K]> | undefined, models?: ModelCollection<DB>): FetchOneXResult<DB, K, Selectable<DB[K]>>;
|
24
|
+
/**
|
25
|
+
* Creates a new {@link FetchSomeResult} instance.
|
26
|
+
*/
|
27
|
+
newFetchSome<K extends keyof DB & string>(table: K, result: Selectable<DB[K]>[], models?: ModelCollection<DB>): FetchSomeResult<DB, K, Selectable<DB[K]>>;
|
28
|
+
/**
|
29
|
+
* Checks if a {@link FetchResult} is a {@link FetchOneResult}.
|
30
|
+
*/
|
31
|
+
isFetchOne<K extends keyof DB & string>(table: K, result: unknown): result is FetchOneResult<DB, K, Selectable<DB[K]>>;
|
32
|
+
/**
|
33
|
+
* Checks if a {@link FetchResult} is a {@link FetchOneXResult}.
|
34
|
+
*/
|
35
|
+
isFetchOneX<K extends keyof DB & string>(table: K, result: unknown): result is FetchOneXResult<DB, K, Selectable<DB[K]>>;
|
36
|
+
/**
|
37
|
+
* Checks if a {@link FetchResult} is a {@link FetchSomeResult}.
|
38
|
+
*/
|
39
|
+
isFetchSome<K extends keyof DB & string>(table: K, result: unknown): result is FetchSomeResult<DB, K, Selectable<DB[K]>>;
|
40
|
+
/**
|
41
|
+
* Asserts that a {@link FetchResult} is a {@link FetchOneResult}.
|
42
|
+
*/
|
43
|
+
assertIsFetchOne<K extends keyof DB & string>(table: K, result: unknown): asserts result is FetchOneResult<DB, K, Selectable<DB[K]>>;
|
44
|
+
/**
|
45
|
+
* Asserts that a {@link FetchResult} is a {@link FetchOneXResult}.
|
46
|
+
*/
|
47
|
+
assertIsFetchOneX<K extends keyof DB & string>(table: K, result: unknown): asserts result is FetchOneXResult<DB, K, Selectable<DB[K]>>;
|
48
|
+
/**
|
49
|
+
* Asserts that a {@link FetchResult} is a {@link FetchSomeResult}.
|
50
|
+
*/
|
51
|
+
assertIsFetchSome<K extends keyof DB & string>(table: K, result: unknown): asserts result is FetchSomeResult<DB, K, Selectable<DB[K]>>;
|
52
|
+
};
|
@@ -0,0 +1,88 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.newFetchResultFactory = newFetchResultFactory;
|
4
|
+
const fetch_result_js_1 = require("./fetch-result.js");
|
5
|
+
const model_collection_js_1 = require("./model-collection.js");
|
6
|
+
function newFetchResultFactory() {
|
7
|
+
return {
|
8
|
+
/**
|
9
|
+
* Creates a new {@link FetchOneResult} instance.
|
10
|
+
*/
|
11
|
+
newFetchOne(table, result, models) {
|
12
|
+
models ??= (0, model_collection_js_1.newModelCollection)();
|
13
|
+
if (result) {
|
14
|
+
models.add(table, result);
|
15
|
+
}
|
16
|
+
return (0, fetch_result_js_1.newFetchOneResult)(table, result, models);
|
17
|
+
},
|
18
|
+
/**
|
19
|
+
* Creates a new {@link FetchOneXResult} instance.
|
20
|
+
*
|
21
|
+
* Note: it may be counterintuitive, but this function accepts `undefined` as
|
22
|
+
* input. I found it is way more convenient to assert the type once in this
|
23
|
+
* funciton rather than in every caller.
|
24
|
+
*/
|
25
|
+
newFetchOneX(table, result, models) {
|
26
|
+
models ??= (0, model_collection_js_1.newModelCollection)();
|
27
|
+
if (result) {
|
28
|
+
models.add(table, result);
|
29
|
+
}
|
30
|
+
return (0, fetch_result_js_1.newFetchOneXResult)(table, result, models);
|
31
|
+
},
|
32
|
+
/**
|
33
|
+
* Creates a new {@link FetchSomeResult} instance.
|
34
|
+
*/
|
35
|
+
newFetchSome(table, result, models) {
|
36
|
+
models ??= (0, model_collection_js_1.newModelCollection)();
|
37
|
+
for (const item of result) {
|
38
|
+
models.add(table, item);
|
39
|
+
}
|
40
|
+
return (0, fetch_result_js_1.newFetchSomeResult)(table, result, models);
|
41
|
+
},
|
42
|
+
/**
|
43
|
+
* Checks if a {@link FetchResult} is a {@link FetchOneResult}.
|
44
|
+
*/
|
45
|
+
isFetchOne(table, result) {
|
46
|
+
return (0, fetch_result_js_1.isFetchOneResult)(result) && result.table === table;
|
47
|
+
},
|
48
|
+
/**
|
49
|
+
* Checks if a {@link FetchResult} is a {@link FetchOneXResult}.
|
50
|
+
*/
|
51
|
+
isFetchOneX(table, result) {
|
52
|
+
return (0, fetch_result_js_1.isFetchOneXResult)(result) && result.table === table;
|
53
|
+
},
|
54
|
+
/**
|
55
|
+
* Checks if a {@link FetchResult} is a {@link FetchSomeResult}.
|
56
|
+
*/
|
57
|
+
isFetchSome(table, result) {
|
58
|
+
return (0, fetch_result_js_1.isFetchSomeResult)(result) && result.table === table;
|
59
|
+
},
|
60
|
+
/**
|
61
|
+
* Asserts that a {@link FetchResult} is a {@link FetchOneResult}.
|
62
|
+
*/
|
63
|
+
assertIsFetchOne(table, result) {
|
64
|
+
(0, fetch_result_js_1.assertIsFetchOneResult)(result);
|
65
|
+
if (result.table !== table) {
|
66
|
+
throw new Error(`Expected a fetchOne result for table ${table}`);
|
67
|
+
}
|
68
|
+
},
|
69
|
+
/**
|
70
|
+
* Asserts that a {@link FetchResult} is a {@link FetchOneXResult}.
|
71
|
+
*/
|
72
|
+
assertIsFetchOneX(table, result) {
|
73
|
+
(0, fetch_result_js_1.assertIsFetchOneXResult)(result);
|
74
|
+
if (result.table !== table) {
|
75
|
+
throw new Error(`Expected a fetchOne result with a non-null non for table ${table}`);
|
76
|
+
}
|
77
|
+
},
|
78
|
+
/**
|
79
|
+
* Asserts that a {@link FetchResult} is a {@link FetchSomeResult}.
|
80
|
+
*/
|
81
|
+
assertIsFetchSome(table, result) {
|
82
|
+
(0, fetch_result_js_1.assertIsFetchSomeResult)(result);
|
83
|
+
if (result.table !== table) {
|
84
|
+
throw new Error(`Expected a fetchSome result for table ${table}`);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
};
|
88
|
+
}
|
@@ -0,0 +1,111 @@
|
|
1
|
+
import type { Selectable } from 'kysely';
|
2
|
+
import type { ModelCollection } from './model-collection.js';
|
3
|
+
/**
|
4
|
+
* A {@link FetchResult} is a result of a fetch operation. It can be one of
|
5
|
+
* three types:
|
6
|
+
* - {@link FetchOneResult} - A result of a fetch operation that is expected to
|
7
|
+
* return up to one row,
|
8
|
+
* - {@link FetchOneXResult} - A result of a fetch operation that is expected to
|
9
|
+
* return exactly one row,
|
10
|
+
* - {@link FetchSomeResult} - A result of a fetch operation that is expected to
|
11
|
+
* return any number of rows.
|
12
|
+
*/
|
13
|
+
export type FetchResult<DB, T extends keyof DB & string, R extends Partial<Selectable<DB[T]>>> = FetchOneResult<DB, T, R> | FetchOneXResult<DB, T, R> | FetchSomeResult<DB, T, R>;
|
14
|
+
/**
|
15
|
+
* A {@link FetchOneResult} is a result of a fetch operation that is expected to
|
16
|
+
* return up to one row.
|
17
|
+
*/
|
18
|
+
export type FetchOneResult<DB, T extends keyof DB & string, R extends Partial<Selectable<DB[T]>> | undefined> = {
|
19
|
+
fetchType: 'fetchOne';
|
20
|
+
table: T;
|
21
|
+
result: R | undefined;
|
22
|
+
models?: ModelCollection<DB>;
|
23
|
+
/**
|
24
|
+
* Returns this result as a {@link FetchOneXResult}.
|
25
|
+
*
|
26
|
+
* @throws If the result is null or undefined.
|
27
|
+
*/
|
28
|
+
asFetchOneX(): FetchOneXResult<DB, T, R & {}>;
|
29
|
+
};
|
30
|
+
/**
|
31
|
+
* A {@link FetchOneXResult} is a result of a fetch operation that is expected
|
32
|
+
* to return exactly one row.
|
33
|
+
*/
|
34
|
+
export type FetchOneXResult<DB, T extends keyof DB & string, R extends Partial<Selectable<DB[T]>>> = {
|
35
|
+
fetchType: 'fetchOne';
|
36
|
+
table: T;
|
37
|
+
result: R;
|
38
|
+
models?: ModelCollection<DB>;
|
39
|
+
/**
|
40
|
+
* Returns self. This is a no-op, but it's here to make it possible to
|
41
|
+
* cast this object back to a {@link FetchOneXResult}.
|
42
|
+
*/
|
43
|
+
asFetchOneX(): FetchOneXResult<DB, T, R>;
|
44
|
+
};
|
45
|
+
/**
|
46
|
+
* A {@link FetchSomeResult} is a result of a fetch operation that is expected
|
47
|
+
* to return any number of rows.
|
48
|
+
*/
|
49
|
+
export type FetchSomeResult<DB, T extends keyof DB & string, R extends Partial<Selectable<DB[T]>>> = {
|
50
|
+
fetchType: 'fetchSome';
|
51
|
+
table: T;
|
52
|
+
result: R[];
|
53
|
+
models?: ModelCollection<DB>;
|
54
|
+
};
|
55
|
+
/**
|
56
|
+
* Used to type juggle between {@link FetchResult} and its subtypes.
|
57
|
+
*/
|
58
|
+
export type AsFetchOneResult<T extends FetchResult<any, string, Selectable<any>>> = T extends FetchResult<infer DB, infer T, infer R> ? FetchOneResult<DB, T, R> : never;
|
59
|
+
/**
|
60
|
+
* Used to type juggle between {@link FetchResult} and its subtypes.
|
61
|
+
*/
|
62
|
+
export type AsFetchOneXResult<T extends FetchResult<any, string, Selectable<any>>> = T extends FetchResult<infer DB, infer T, infer R> ? FetchOneXResult<DB, T, R> : never;
|
63
|
+
/**
|
64
|
+
* Used to type juggle between {@link FetchResult} and its subtypes.
|
65
|
+
*/
|
66
|
+
export type AsFetchSomeResult<T extends FetchResult<any, string, Selectable<any>>> = T extends FetchResult<infer DB, infer T, infer R> ? FetchSomeResult<DB, T, R> : never;
|
67
|
+
/**
|
68
|
+
* Creates a new {@link FetchOneResult} instance.
|
69
|
+
*/
|
70
|
+
export declare function newFetchOneResult<DB, T extends keyof DB & string, R extends Partial<Selectable<DB[T]>>>(table: T, result: R | undefined, models?: ModelCollection<DB>): FetchOneResult<DB, T, R>;
|
71
|
+
/**
|
72
|
+
* Creates a new {@link FetchOneXResult} instance.
|
73
|
+
*
|
74
|
+
* Note: it may be counterintuitive, but this function accepts `undefined` as
|
75
|
+
* input. I found it is way more convenient to assert the type once in this
|
76
|
+
* funciton rather than in every caller.
|
77
|
+
*/
|
78
|
+
export declare function newFetchOneXResult<DB, T extends keyof DB & string, R extends Partial<Selectable<DB[T]>>>(table: T, result: R | undefined, models?: ModelCollection<DB>): FetchOneXResult<DB, T, R>;
|
79
|
+
/**
|
80
|
+
* Creates a new {@link FetchSomeResult} instance.
|
81
|
+
*/
|
82
|
+
export declare function newFetchSomeResult<DB, T extends keyof DB & string, R extends Partial<Selectable<DB[T]>>>(table: T, result: R[], models?: ModelCollection<DB>): FetchSomeResult<DB, T, R>;
|
83
|
+
export declare function isFetchResult(result: unknown): result is FetchResult<any, any, any>;
|
84
|
+
/**
|
85
|
+
* Checks if `value` is a {@link FetchOneResult}.
|
86
|
+
*/
|
87
|
+
export declare function isFetchOneResult<DB, T extends keyof DB & string, R extends Partial<Selectable<DB[T]>>>(value: FetchOneResult<DB, T, R> | FetchOneXResult<DB, T, R>): value is typeof value;
|
88
|
+
export declare function isFetchOneResult(value: unknown): value is FetchOneResult<any, string, Selectable<any>>;
|
89
|
+
/**
|
90
|
+
* Checks if `value` is a {@link FetchOneXResult}.
|
91
|
+
*/
|
92
|
+
export declare function isFetchOneXResult<DB, T extends keyof DB & string, R extends Partial<Selectable<DB[T]>>>(value: FetchOneResult<DB, T, R>): value is FetchOneXResult<DB, T, R>;
|
93
|
+
export declare function isFetchOneXResult<DB, T extends keyof DB & string, R extends Partial<Selectable<DB[T]>>>(value: FetchOneXResult<DB, T, R>): value is typeof value;
|
94
|
+
export declare function isFetchOneXResult(value: unknown): value is FetchOneXResult<any, string, Selectable<any>>;
|
95
|
+
/**
|
96
|
+
* Checks if `value` is a {@link FetchSomeResult}.
|
97
|
+
*/
|
98
|
+
export declare function isFetchSomeResult<DB, T extends keyof DB & string, R extends Partial<Selectable<DB[T]>>>(value: FetchSomeResult<DB, T, R>): value is typeof value;
|
99
|
+
export declare function isFetchSomeResult(value: unknown): value is FetchSomeResult<any, string, Selectable<any>>;
|
100
|
+
/**
|
101
|
+
* Asserts that `value` is a {@link FetchOneResult}.
|
102
|
+
*/
|
103
|
+
export declare function assertIsFetchOneResult(value: unknown): asserts value is FetchOneResult<any, string, Selectable<any>>;
|
104
|
+
/**
|
105
|
+
* Asserts that `value` is a {@link FetchOneXResult}.
|
106
|
+
*/
|
107
|
+
export declare function assertIsFetchOneXResult(value: unknown): asserts value is FetchOneXResult<any, string, Selectable<any>>;
|
108
|
+
/**
|
109
|
+
* Asserts that `value` is a {@link FetchSomeResult}.
|
110
|
+
*/
|
111
|
+
export declare function assertIsFetchSomeResult(value: unknown): asserts value is FetchSomeResult<any, string, Selectable<any>>;
|
@@ -0,0 +1,117 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.newFetchOneResult = newFetchOneResult;
|
4
|
+
exports.newFetchOneXResult = newFetchOneXResult;
|
5
|
+
exports.newFetchSomeResult = newFetchSomeResult;
|
6
|
+
exports.isFetchResult = isFetchResult;
|
7
|
+
exports.isFetchOneResult = isFetchOneResult;
|
8
|
+
exports.isFetchOneXResult = isFetchOneXResult;
|
9
|
+
exports.isFetchSomeResult = isFetchSomeResult;
|
10
|
+
exports.assertIsFetchOneResult = assertIsFetchOneResult;
|
11
|
+
exports.assertIsFetchOneXResult = assertIsFetchOneXResult;
|
12
|
+
exports.assertIsFetchSomeResult = assertIsFetchSomeResult;
|
13
|
+
/**
|
14
|
+
* Creates a new {@link FetchOneResult} instance.
|
15
|
+
*/
|
16
|
+
function newFetchOneResult(table, result, models) {
|
17
|
+
const ref = { value: null };
|
18
|
+
const me = {
|
19
|
+
fetchType: 'fetchOne',
|
20
|
+
table,
|
21
|
+
result,
|
22
|
+
models,
|
23
|
+
asFetchOneX() {
|
24
|
+
if (!me.result) {
|
25
|
+
throw new Error('Expected a fetchOneX result');
|
26
|
+
}
|
27
|
+
return ref.value;
|
28
|
+
}
|
29
|
+
};
|
30
|
+
ref.value = me;
|
31
|
+
return me;
|
32
|
+
}
|
33
|
+
/**
|
34
|
+
* Creates a new {@link FetchOneXResult} instance.
|
35
|
+
*
|
36
|
+
* Note: it may be counterintuitive, but this function accepts `undefined` as
|
37
|
+
* input. I found it is way more convenient to assert the type once in this
|
38
|
+
* funciton rather than in every caller.
|
39
|
+
*/
|
40
|
+
function newFetchOneXResult(table, result, models) {
|
41
|
+
if (!result) {
|
42
|
+
throw new Error('Expected a fetchOneX result');
|
43
|
+
}
|
44
|
+
const ref = { value: null };
|
45
|
+
const me = {
|
46
|
+
fetchType: 'fetchOne',
|
47
|
+
table,
|
48
|
+
result,
|
49
|
+
models,
|
50
|
+
asFetchOneX() {
|
51
|
+
return ref.value;
|
52
|
+
}
|
53
|
+
};
|
54
|
+
ref.value = me;
|
55
|
+
return me;
|
56
|
+
}
|
57
|
+
/**
|
58
|
+
* Creates a new {@link FetchSomeResult} instance.
|
59
|
+
*/
|
60
|
+
function newFetchSomeResult(table, result, models) {
|
61
|
+
return {
|
62
|
+
fetchType: 'fetchSome',
|
63
|
+
table,
|
64
|
+
result,
|
65
|
+
models
|
66
|
+
};
|
67
|
+
}
|
68
|
+
function isFetchResult(result) {
|
69
|
+
return (!!result &&
|
70
|
+
typeof result === 'object' &&
|
71
|
+
'fetchType' in result &&
|
72
|
+
!!result.fetchType &&
|
73
|
+
typeof result.fetchType === 'string' &&
|
74
|
+
'table' in result &&
|
75
|
+
!!result.table &&
|
76
|
+
typeof result.table === 'string' &&
|
77
|
+
'result' in result &&
|
78
|
+
(result.result === undefined ||
|
79
|
+
typeof result.result === 'object' ||
|
80
|
+
(Array.isArray(result.result) && result.result.every((r) => !!r && typeof r === 'object'))));
|
81
|
+
}
|
82
|
+
function isFetchOneResult(value) {
|
83
|
+
return isFetchResult(value) && value.fetchType === 'fetchOne' && !Array.isArray(value.result);
|
84
|
+
}
|
85
|
+
function isFetchOneXResult(value) {
|
86
|
+
return (isFetchResult(value) &&
|
87
|
+
value.fetchType === 'fetchOne' &&
|
88
|
+
!Array.isArray(value.result) &&
|
89
|
+
!!value.result);
|
90
|
+
}
|
91
|
+
function isFetchSomeResult(value) {
|
92
|
+
return isFetchResult(value) && value.fetchType === 'fetchSome' && Array.isArray(value.result);
|
93
|
+
}
|
94
|
+
/**
|
95
|
+
* Asserts that `value` is a {@link FetchOneResult}.
|
96
|
+
*/
|
97
|
+
function assertIsFetchOneResult(value) {
|
98
|
+
if (!isFetchOneResult(value)) {
|
99
|
+
throw new Error('Expected a fetchOne result');
|
100
|
+
}
|
101
|
+
}
|
102
|
+
/**
|
103
|
+
* Asserts that `value` is a {@link FetchOneXResult}.
|
104
|
+
*/
|
105
|
+
function assertIsFetchOneXResult(value) {
|
106
|
+
if (!isFetchOneXResult(value)) {
|
107
|
+
throw new Error('Expected a fetchOne result with a non-null, non undefined result');
|
108
|
+
}
|
109
|
+
}
|
110
|
+
/**
|
111
|
+
* Asserts that `value` is a {@link FetchSomeResult}.
|
112
|
+
*/
|
113
|
+
function assertIsFetchSomeResult(value) {
|
114
|
+
if (!isFetchSomeResult(value)) {
|
115
|
+
throw new Error('Expected a fetchSome result');
|
116
|
+
}
|
117
|
+
}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
export { KyselyRizzolver } from './kysely-rizzolver.js';
|
2
|
+
export type { AllTableFields, AnyTableField, KyselyRizzolverBuilderForSchema, KyselyRizzolverBuilderNoSchema, KyDB as RizzolverDB, TableName } from './kysely-rizzolver.js';
|
3
|
+
export { assertIsFetchOneResult, assertIsFetchOneXResult, assertIsFetchSomeResult, isFetchOneResult, isFetchOneXResult, isFetchSomeResult, newFetchOneResult, newFetchOneXResult, newFetchSomeResult } from './fetch-result.js';
|
4
|
+
export type { AsFetchOneResult, AsFetchOneXResult, AsFetchSomeResult, FetchOneResult, FetchOneXResult, FetchResult, FetchSomeResult } from './fetch-result.js';
|
5
|
+
export { newSelector } from './selector.js';
|
6
|
+
export type { Selector } from './selector.js';
|
7
|
+
export { newQueryBuilder } from './query-builder.js';
|
8
|
+
export type { QueryBuilder } from './query-builder.js';
|
9
|
+
export { newModelCollection } from './model-collection.js';
|
10
|
+
export type { ModelCollection } from './model-collection.js';
|
@@ -0,0 +1,21 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.newModelCollection = exports.newQueryBuilder = exports.newSelector = exports.newFetchSomeResult = exports.newFetchOneXResult = exports.newFetchOneResult = exports.isFetchSomeResult = exports.isFetchOneXResult = exports.isFetchOneResult = exports.assertIsFetchSomeResult = exports.assertIsFetchOneXResult = exports.assertIsFetchOneResult = exports.KyselyRizzolver = void 0;
|
4
|
+
var kysely_rizzolver_js_1 = require("./kysely-rizzolver.js");
|
5
|
+
Object.defineProperty(exports, "KyselyRizzolver", { enumerable: true, get: function () { return kysely_rizzolver_js_1.KyselyRizzolver; } });
|
6
|
+
var fetch_result_js_1 = require("./fetch-result.js");
|
7
|
+
Object.defineProperty(exports, "assertIsFetchOneResult", { enumerable: true, get: function () { return fetch_result_js_1.assertIsFetchOneResult; } });
|
8
|
+
Object.defineProperty(exports, "assertIsFetchOneXResult", { enumerable: true, get: function () { return fetch_result_js_1.assertIsFetchOneXResult; } });
|
9
|
+
Object.defineProperty(exports, "assertIsFetchSomeResult", { enumerable: true, get: function () { return fetch_result_js_1.assertIsFetchSomeResult; } });
|
10
|
+
Object.defineProperty(exports, "isFetchOneResult", { enumerable: true, get: function () { return fetch_result_js_1.isFetchOneResult; } });
|
11
|
+
Object.defineProperty(exports, "isFetchOneXResult", { enumerable: true, get: function () { return fetch_result_js_1.isFetchOneXResult; } });
|
12
|
+
Object.defineProperty(exports, "isFetchSomeResult", { enumerable: true, get: function () { return fetch_result_js_1.isFetchSomeResult; } });
|
13
|
+
Object.defineProperty(exports, "newFetchOneResult", { enumerable: true, get: function () { return fetch_result_js_1.newFetchOneResult; } });
|
14
|
+
Object.defineProperty(exports, "newFetchOneXResult", { enumerable: true, get: function () { return fetch_result_js_1.newFetchOneXResult; } });
|
15
|
+
Object.defineProperty(exports, "newFetchSomeResult", { enumerable: true, get: function () { return fetch_result_js_1.newFetchSomeResult; } });
|
16
|
+
var selector_js_1 = require("./selector.js");
|
17
|
+
Object.defineProperty(exports, "newSelector", { enumerable: true, get: function () { return selector_js_1.newSelector; } });
|
18
|
+
var query_builder_js_1 = require("./query-builder.js");
|
19
|
+
Object.defineProperty(exports, "newQueryBuilder", { enumerable: true, get: function () { return query_builder_js_1.newQueryBuilder; } });
|
20
|
+
var model_collection_js_1 = require("./model-collection.js");
|
21
|
+
Object.defineProperty(exports, "newModelCollection", { enumerable: true, get: function () { return model_collection_js_1.newModelCollection; } });
|