forj 0.0.0 → 0.0.2
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/LICENSE +21 -0
- package/README.md +15 -8
- package/package.json +75 -2
- package/src/clause-builder.ts +216 -0
- package/src/d1/index.ts +4 -0
- package/src/d1/model.ts +79 -0
- package/src/index.ts +1 -0
- package/src/model.ts +258 -0
- package/src/query-builder.ts +375 -0
- package/src/types.ts +260 -0
- package/src/utils.ts +134 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-present, ZUNQ.com
|
|
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
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
# `forj`
|
|
2
|
+
|
|
3
|
+
SQLite ORM and Query Builder whitout dependencies.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
To install the package, run:
|
|
2
8
|
|
|
3
9
|
```bash
|
|
4
|
-
|
|
10
|
+
# bun
|
|
11
|
+
bun i forj
|
|
5
12
|
```
|
|
6
13
|
|
|
7
|
-
|
|
14
|
+
## Tests
|
|
15
|
+
|
|
16
|
+
To perform the tests, run:
|
|
8
17
|
|
|
9
18
|
```bash
|
|
10
|
-
bun
|
|
19
|
+
bun test
|
|
11
20
|
```
|
|
12
21
|
|
|
13
|
-
|
|
22
|
+
## License
|
|
14
23
|
|
|
15
|
-
|
|
16
|
-
bun publish
|
|
17
|
-
```
|
|
24
|
+
This package is licensed under the [MIT license](https://github.com/attla/forj/blob/main/LICENSE) © [Zunq](https://zunq.com)
|
package/package.json
CHANGED
|
@@ -1,4 +1,77 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "forj",
|
|
3
|
-
"
|
|
2
|
+
"name": "forj",
|
|
3
|
+
"description": "SQLite ORM and Query Builder whitout dependencies",
|
|
4
|
+
"version": "0.0.2",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.ts",
|
|
7
|
+
"files": ["src"],
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./src/index.ts",
|
|
10
|
+
"./d1": "./src/d1/index.ts"
|
|
11
|
+
},
|
|
12
|
+
"-exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./d1": {
|
|
18
|
+
"import": "./dist/d1.js",
|
|
19
|
+
"types": "./dist/d1.d.ts"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"bench": "tsx tests/benchmark/*.bench.ts",
|
|
24
|
+
"build": "tsup",
|
|
25
|
+
"-prepublishOnly": "bun run build"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@cloudflare/workers-types": "^4.20260113.0",
|
|
29
|
+
"pluralize": "^8.0",
|
|
30
|
+
"zod": "^3.19.1"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@types/pluralize": "^0.0.33",
|
|
34
|
+
"bun-types": "^1.2.13",
|
|
35
|
+
"terser": "^5.46.0",
|
|
36
|
+
"tiny-glob": "^0.2",
|
|
37
|
+
"tsup": "^8.5.1",
|
|
38
|
+
"tsx": "^4.19.4",
|
|
39
|
+
"typescript": "^5.8.3"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18.0.0"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"registry": "https://registry.npmjs.org"
|
|
46
|
+
},
|
|
47
|
+
"author": "Zunq <open-source@zunq.com>",
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"homepage": "https://zunq.dev",
|
|
50
|
+
"repository": "git://github.com/attla/forj",
|
|
51
|
+
"bugs": "https://github.com/attla/forj/issues",
|
|
52
|
+
"keywords": [
|
|
53
|
+
"forj",
|
|
54
|
+
"attla",
|
|
55
|
+
"resources",
|
|
56
|
+
"support",
|
|
57
|
+
"sqlite",
|
|
58
|
+
"orm",
|
|
59
|
+
"query",
|
|
60
|
+
"builder",
|
|
61
|
+
"query builder",
|
|
62
|
+
"query-builder",
|
|
63
|
+
"db",
|
|
64
|
+
"database",
|
|
65
|
+
"sql",
|
|
66
|
+
"mysql",
|
|
67
|
+
"postgres",
|
|
68
|
+
"postgresql",
|
|
69
|
+
"typescript",
|
|
70
|
+
"aws",
|
|
71
|
+
"lambda",
|
|
72
|
+
"llrt",
|
|
73
|
+
"deno",
|
|
74
|
+
"bun",
|
|
75
|
+
"nodejs"
|
|
76
|
+
]
|
|
4
77
|
}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { parseColumn, isJoinCompare, zSame, zType } from './utils'
|
|
2
|
+
import type {
|
|
3
|
+
IClauseBuilder,
|
|
4
|
+
ClauseOperator,
|
|
5
|
+
Value, Values,
|
|
6
|
+
WhereFn, WhereArgs,
|
|
7
|
+
DBSchema,
|
|
8
|
+
} from './types'
|
|
9
|
+
|
|
10
|
+
export default class ClauseBuilder<
|
|
11
|
+
T,
|
|
12
|
+
C extends keyof T = keyof T
|
|
13
|
+
> implements IClauseBuilder<T> {
|
|
14
|
+
#table: string
|
|
15
|
+
#schema?: DBSchema
|
|
16
|
+
#clauses: string[] = []
|
|
17
|
+
#args: Values = []
|
|
18
|
+
|
|
19
|
+
get clauses() {
|
|
20
|
+
return this.#clauses
|
|
21
|
+
}
|
|
22
|
+
set clauses(clauses: string[]) {
|
|
23
|
+
this.#clauses.push(...clauses)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get args() {
|
|
27
|
+
return this.#args
|
|
28
|
+
}
|
|
29
|
+
set args(args: Values) {
|
|
30
|
+
this.#args.push(...args)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
get length() {
|
|
34
|
+
return this.#clauses.length
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
constructor(table: string, schema?: DBSchema) {
|
|
38
|
+
this.#table = table
|
|
39
|
+
this.#schema = schema
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
#nested(fn: WhereFn<T, C>, operator: ClauseOperator = 'AND') {
|
|
43
|
+
const nested = new ClauseBuilder<T, C>(this.#table, this.#schema)
|
|
44
|
+
fn(nested)
|
|
45
|
+
|
|
46
|
+
if (nested.length) {
|
|
47
|
+
this.#clauses.push(`${this.length ? operator +' ' : ''}(${nested.clauses.join(' ')})`)
|
|
48
|
+
this.#args.push(...nested.args)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return this
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
#clause(sql: string, values: Values = [], bool: ClauseOperator = 'AND') {
|
|
55
|
+
if (this.length) sql = bool +' '+ sql
|
|
56
|
+
this.#clauses.push(sql)
|
|
57
|
+
|
|
58
|
+
if (values?.length) // TODO: https://developers.cloudflare.com/d1/worker-api/#type-conversion
|
|
59
|
+
this.#args.push(...values)
|
|
60
|
+
|
|
61
|
+
return this
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
#where(
|
|
65
|
+
logical: ClauseOperator,
|
|
66
|
+
...args: WhereArgs<T>
|
|
67
|
+
) {
|
|
68
|
+
if (typeof args[0] == 'function')
|
|
69
|
+
return this.#nested(args[0], logical)
|
|
70
|
+
|
|
71
|
+
const length = args.length
|
|
72
|
+
let [column, operator, value] = args
|
|
73
|
+
|
|
74
|
+
if (length == 2) { // @ts-ignore
|
|
75
|
+
value = operator
|
|
76
|
+
operator = '='
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// @ts-ignore
|
|
80
|
+
column = parseColumn(String(column), this.#table)
|
|
81
|
+
|
|
82
|
+
if (this.#schema && !zSame(column, value, this.#schema)) {
|
|
83
|
+
throw new Error(`Table column '${String(column)}' of type '${zType(column, this.#schema)}' is not assignable as type of '${typeof value}'.`)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return isJoinCompare(value, this.#schema) // @ts-ignore
|
|
87
|
+
? this.#clause(`${column} ${operator} ${value}`, [], logical) // @ts-ignore
|
|
88
|
+
: this.#clause(`${column} ${operator} ?`, [value], logical)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
where(...args: WhereArgs<T>) {
|
|
92
|
+
return this.#where('AND', ...args)
|
|
93
|
+
}
|
|
94
|
+
on(...args: WhereArgs<T>) {
|
|
95
|
+
return this.where(...args)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
orWhere(...args: WhereArgs<T>) {
|
|
99
|
+
return this.#where('OR', ...args)
|
|
100
|
+
}
|
|
101
|
+
orOn(...args: WhereArgs<T>) {
|
|
102
|
+
return this.orWhere(...args)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
#in(
|
|
106
|
+
column: string,
|
|
107
|
+
values: Values,
|
|
108
|
+
operator: 'IN' | 'NOT IN',
|
|
109
|
+
logical: ClauseOperator = 'AND'
|
|
110
|
+
) {
|
|
111
|
+
if (!values?.length) return this
|
|
112
|
+
return this.#clause(parseColumn(column, this.#table) + ` ${operator} (${values.map(() => '?').join(', ')})`, values, logical)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
whereIn(column: C, values: T[C][]) { // @ts-ignore
|
|
116
|
+
return this.#in(column, values, 'IN')
|
|
117
|
+
}
|
|
118
|
+
in(column: C, values: T[C][]) {
|
|
119
|
+
return this.whereIn(column, values)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
whereNotIn(column: C, values: T[C][]) { // @ts-ignore
|
|
123
|
+
return this.#in(column, values, 'NOT IN')
|
|
124
|
+
}
|
|
125
|
+
notIn(column: C, values: T[C][]) {
|
|
126
|
+
return this.whereNotIn(column, values)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
orWhereIn(column: C, values: T[C][]) { // @ts-ignore
|
|
130
|
+
return this.#in(column, values, 'IN', 'OR')
|
|
131
|
+
}
|
|
132
|
+
orIn(column: C, values: T[C][]) {
|
|
133
|
+
return this.orWhereIn(column, values)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
orWhereNotIn(column: C, values: T[C][]) { // @ts-ignore
|
|
137
|
+
return this.#in(column, values, 'NOT IN', 'OR')
|
|
138
|
+
}
|
|
139
|
+
orNotIn(column: C, values: T[C][]) {
|
|
140
|
+
return this.orWhereNotIn(column, values)
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
#between(
|
|
144
|
+
column: string,
|
|
145
|
+
one: Value,
|
|
146
|
+
two: Value,
|
|
147
|
+
operator: 'BETWEEN' | 'NOT BETWEEN',
|
|
148
|
+
logical: ClauseOperator = 'AND'
|
|
149
|
+
) {
|
|
150
|
+
return this.#clause(parseColumn(column, this.#table) + ` ${operator} ? AND ?`, [one, two], logical)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
whereBetween(column: C, one: T[C], two: T[C]) { // @ts-ignore
|
|
154
|
+
return this.#between(column, one, two, 'BETWEEN')
|
|
155
|
+
}
|
|
156
|
+
between(column: C, one: T[C], two: T[C]) {
|
|
157
|
+
return this.whereBetween(column, one, two)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
orWhereBetween(column: C, one: T[C], two: T[C]) { // @ts-ignore
|
|
161
|
+
return this.#between(column, one, two, 'BETWEEN', 'OR')
|
|
162
|
+
}
|
|
163
|
+
orBetween(column: C, one: T[C], two: T[C]) {
|
|
164
|
+
return this.orWhereBetween(column, one, two)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
whereNotBetween(column: C, one: T[C], two: T[C]) { // @ts-ignore
|
|
168
|
+
return this.#between(column, one, two, 'NOT BETWEEN')
|
|
169
|
+
}
|
|
170
|
+
notBetween(column: C, one: T[C], two: T[C]) {
|
|
171
|
+
return this.whereNotBetween(column, one, two)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
orWhereNotBetween(column: C, one: T[C], two: T[C]) { // @ts-ignore
|
|
175
|
+
return this.#between(column, one, two, 'NOT BETWEEN', 'OR')
|
|
176
|
+
}
|
|
177
|
+
orNotBetween(column: C, one: T[C], two: T[C]) {
|
|
178
|
+
return this.orWhereNotBetween(column, one, two)
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
#null(
|
|
182
|
+
column: string,
|
|
183
|
+
operator: 'IS' | 'IS NOT' = 'IS',
|
|
184
|
+
logical: ClauseOperator = 'AND'
|
|
185
|
+
) {
|
|
186
|
+
return this.#clause(parseColumn(column, this.#table) +` ${operator} NULL`, [], logical)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
whereNull(column: C) {
|
|
190
|
+
return this.#null(column as string)
|
|
191
|
+
}
|
|
192
|
+
onNull(column: C) {
|
|
193
|
+
return this.whereNull(column)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
orWhereNull(column: C) {
|
|
197
|
+
return this.#null(column as string, 'IS', 'OR')
|
|
198
|
+
}
|
|
199
|
+
orOnNull(column: C) {
|
|
200
|
+
return this.orWhereNull(column)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
whereNotNull(column: C) {
|
|
204
|
+
return this.#null(column as string, 'IS NOT')
|
|
205
|
+
}
|
|
206
|
+
onNotNull(column: C) {
|
|
207
|
+
return this.whereNotNull(column)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
orWhereNotNull(column: C) {
|
|
211
|
+
return this.#null(column as string, 'IS NOT', 'OR')
|
|
212
|
+
}
|
|
213
|
+
orNotNull(column: C) {
|
|
214
|
+
return this.orWhereNotNull(column)
|
|
215
|
+
}
|
|
216
|
+
}
|
package/src/d1/index.ts
ADDED
package/src/d1/model.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
D1Database,
|
|
3
|
+
D1PreparedStatement,
|
|
4
|
+
D1Result, D1ExecResult, D1Meta,
|
|
5
|
+
} from '@cloudflare/workers-types'
|
|
6
|
+
|
|
7
|
+
import z from 'zod'
|
|
8
|
+
|
|
9
|
+
import { QueryBuilder } from '../query-builder'
|
|
10
|
+
import { default as BaseModel } from '../model'
|
|
11
|
+
import type {
|
|
12
|
+
DBSchema, SchemaKeys,
|
|
13
|
+
Item,
|
|
14
|
+
Pipe, Result, RunFn,
|
|
15
|
+
} from '../types'
|
|
16
|
+
|
|
17
|
+
export function ModelBuilder<
|
|
18
|
+
TSchema extends DBSchema,
|
|
19
|
+
TBase extends SchemaKeys<TSchema>
|
|
20
|
+
>(schema: TSchema, base: TBase) {
|
|
21
|
+
type S = z.infer<typeof schema>
|
|
22
|
+
return class extends Model<TBase, S> {
|
|
23
|
+
static $table = String(base)
|
|
24
|
+
static $schema = schema
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default ModelBuilder
|
|
29
|
+
|
|
30
|
+
export abstract class Model<TB extends keyof DB, DB> extends BaseModel<TB, DB> {
|
|
31
|
+
static $db: string | D1Database = 'DB'
|
|
32
|
+
|
|
33
|
+
static pipe<S, T>(): Pipe<S, T> {
|
|
34
|
+
const db = this.DB()
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
run: this.run<S, T>(db)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static DB() {
|
|
42
|
+
if (typeof this.$db == 'string') { // TODO: improv compatibility without nodejs_compat
|
|
43
|
+
if (!(this.$db in process.env))
|
|
44
|
+
throw new Error(`Database '${this.$db}' instance not provided.`)
|
|
45
|
+
|
|
46
|
+
// @ts-ignore
|
|
47
|
+
return process.env[this.$db] as D1Database
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return this.$db
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static run<S, T>(db: D1Database): RunFn<S, T> {
|
|
54
|
+
return async <S, T, C extends keyof T = keyof T>(
|
|
55
|
+
qb: QueryBuilder<S, T, C>
|
|
56
|
+
): Promise<Result<T, C>> => {
|
|
57
|
+
let stmt = db.prepare(qb.query)
|
|
58
|
+
|
|
59
|
+
if (qb.args?.length)
|
|
60
|
+
stmt = stmt.bind(...qb.args)
|
|
61
|
+
|
|
62
|
+
const resp = await stmt.run<Item<T, C>>()
|
|
63
|
+
|
|
64
|
+
const meta = resp.meta as any
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
changes: meta?.changes,
|
|
68
|
+
duration: meta?.duration,
|
|
69
|
+
lastId: meta?.last_row_id,
|
|
70
|
+
// served_by: meta?.served_by,
|
|
71
|
+
rowsRead: meta?.rows_read,
|
|
72
|
+
rowsWritten: meta?.rows_written,
|
|
73
|
+
// meta: resp.meta,
|
|
74
|
+
success: resp.success,
|
|
75
|
+
results: resp.results,
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './query-builder'
|
package/src/model.ts
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import pluralize from 'pluralize'
|
|
2
|
+
import { QueryBuilder } from './query-builder'
|
|
3
|
+
import type {
|
|
4
|
+
Operator, OrderDirection,
|
|
5
|
+
WhereFn, WhereArgs,
|
|
6
|
+
DBSchema, Pipe,
|
|
7
|
+
} from './types'
|
|
8
|
+
|
|
9
|
+
export default abstract class Model<TB extends keyof DB, DB> {
|
|
10
|
+
// Property only for the compiler (does not exist at runtime)
|
|
11
|
+
readonly $DBShape!: DB
|
|
12
|
+
readonly $TShape!: DB[TB]
|
|
13
|
+
|
|
14
|
+
static $table: string = ''
|
|
15
|
+
static $schema?: DBSchema
|
|
16
|
+
|
|
17
|
+
static pipe<S, T>(): Pipe<S, T> {
|
|
18
|
+
throw new Error(`Database connection not provided.`) // improv this message
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static builder<S, T>() {
|
|
22
|
+
const table = this.$table || pluralize(this.name.toLowerCase())
|
|
23
|
+
|
|
24
|
+
return new QueryBuilder<S, T>(table, this.$schema, this.pipe<S, T>())
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static select< // @ts-ignore
|
|
28
|
+
M extends typeof Model<TB, DB>,
|
|
29
|
+
I extends InstanceType<M>,
|
|
30
|
+
T extends I['$TShape'],
|
|
31
|
+
C extends keyof T
|
|
32
|
+
>(this: M, ...columns: C[] | C[][]) {
|
|
33
|
+
return this.builder<I['$DBShape'], T>().select(...columns)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static distinct< // @ts-ignore
|
|
37
|
+
M extends typeof Model<TB, DB>,
|
|
38
|
+
I extends InstanceType<M>,
|
|
39
|
+
T extends I['$TShape']
|
|
40
|
+
>(this: M) {
|
|
41
|
+
return this.builder<I['$DBShape'], T>().distinct()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static where< // @ts-ignore
|
|
45
|
+
M extends typeof Model<TB, DB>,
|
|
46
|
+
I extends InstanceType<M>,
|
|
47
|
+
T extends I['$TShape'],
|
|
48
|
+
C extends keyof T
|
|
49
|
+
>(this: M, fn: WhereFn<T>): QueryBuilder<I['$DBShape'], T, C>
|
|
50
|
+
static where< // @ts-ignore
|
|
51
|
+
M extends typeof Model<TB, DB>,
|
|
52
|
+
I extends InstanceType<M>,
|
|
53
|
+
T extends I['$TShape'],
|
|
54
|
+
C extends keyof T
|
|
55
|
+
>(this: M, column: C, value: T[C]): QueryBuilder<I['$DBShape'], T, C>
|
|
56
|
+
static where< // @ts-ignore
|
|
57
|
+
M extends typeof Model<TB, DB>,
|
|
58
|
+
I extends InstanceType<M>,
|
|
59
|
+
T extends I['$TShape'],
|
|
60
|
+
C extends keyof T
|
|
61
|
+
>(this: M, column: C, operator: Operator, value: T[C]): QueryBuilder<I['$DBShape'], T, C>
|
|
62
|
+
static where< // @ts-ignore
|
|
63
|
+
M extends typeof Model<TB, DB>,
|
|
64
|
+
I extends InstanceType<M>,
|
|
65
|
+
T extends I['$TShape']
|
|
66
|
+
>(this: M, ...args: WhereArgs<T>) {
|
|
67
|
+
return this.builder<I['$DBShape'], T>().where(...args)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static on< // @ts-ignore
|
|
71
|
+
M extends typeof Model<TB, DB>,
|
|
72
|
+
I extends InstanceType<M>,
|
|
73
|
+
T extends I['$TShape'],
|
|
74
|
+
C extends keyof T
|
|
75
|
+
>(this: M, fn: WhereFn<T>): QueryBuilder<I['$DBShape'], T, C>
|
|
76
|
+
static on< // @ts-ignore
|
|
77
|
+
M extends typeof Model<TB, DB>,
|
|
78
|
+
I extends InstanceType<M>,
|
|
79
|
+
T extends I['$TShape'],
|
|
80
|
+
C extends keyof T
|
|
81
|
+
>(this: M, column: C, value: T[C]): QueryBuilder<I['$DBShape'], T, C>
|
|
82
|
+
static on< // @ts-ignore
|
|
83
|
+
M extends typeof Model<TB, DB>,
|
|
84
|
+
I extends InstanceType<M>,
|
|
85
|
+
T extends I['$TShape'],
|
|
86
|
+
C extends keyof T
|
|
87
|
+
>(this: M, column: C, operator: Operator, value: T[C]): QueryBuilder<I['$DBShape'], T, C>
|
|
88
|
+
static on< // @ts-ignore
|
|
89
|
+
M extends typeof Model<TB, DB>,
|
|
90
|
+
I extends InstanceType<M>,
|
|
91
|
+
T extends I['$TShape']
|
|
92
|
+
>(this: M, ...args: WhereArgs<T>) {
|
|
93
|
+
return this.builder<I['$DBShape'], T>().where(...args)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
static whereIn< // @ts-ignore
|
|
97
|
+
M extends typeof Model<TB, DB>,
|
|
98
|
+
I extends InstanceType<M>,
|
|
99
|
+
T extends I['$TShape'],
|
|
100
|
+
C extends keyof T
|
|
101
|
+
>(this: M, column: C, value: T[C][]) {
|
|
102
|
+
return this.builder<I['$DBShape'], T>().whereIn(column, value)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static in< // @ts-ignore
|
|
106
|
+
M extends typeof Model<TB, DB>,
|
|
107
|
+
I extends InstanceType<M>,
|
|
108
|
+
T extends I['$TShape'],
|
|
109
|
+
C extends keyof T
|
|
110
|
+
>(this: M, column: C, value: T[C][]) {
|
|
111
|
+
return this.builder<I['$DBShape'], T>().whereIn(column, value)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
static whereNotIn< // @ts-ignore
|
|
115
|
+
M extends typeof Model<TB, DB>,
|
|
116
|
+
I extends InstanceType<M>,
|
|
117
|
+
T extends I['$TShape'],
|
|
118
|
+
C extends keyof T
|
|
119
|
+
>(this: M, column: C, value: T[C][]) {
|
|
120
|
+
return this.builder<I['$DBShape'], T>().whereNotIn(column, value)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static notIn< // @ts-ignore
|
|
124
|
+
M extends typeof Model<TB, DB>,
|
|
125
|
+
I extends InstanceType<M>,
|
|
126
|
+
T extends I['$TShape'],
|
|
127
|
+
C extends keyof T
|
|
128
|
+
>(this: M, column: C, value: T[C][]) {
|
|
129
|
+
return this.builder<I['$DBShape'], T>().whereNotIn(column, value)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
static whereBetween< // @ts-ignore
|
|
133
|
+
M extends typeof Model<TB, DB>,
|
|
134
|
+
I extends InstanceType<M>,
|
|
135
|
+
T extends I['$TShape'],
|
|
136
|
+
C extends keyof T
|
|
137
|
+
>(this: M, column: C, one: T[C], two: T[C]) {
|
|
138
|
+
return this.builder<I['$DBShape'], T>().whereBetween(column, one, two)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
static between< // @ts-ignore
|
|
142
|
+
M extends typeof Model<TB, DB>,
|
|
143
|
+
I extends InstanceType<M>,
|
|
144
|
+
T extends I['$TShape'],
|
|
145
|
+
C extends keyof T
|
|
146
|
+
>(this: M, column: C, one: T[C], two: T[C]) {
|
|
147
|
+
return this.builder<I['$DBShape'], T>().whereBetween(column, one, two)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
static whereNotBetween< // @ts-ignore
|
|
151
|
+
M extends typeof Model<TB, DB>,
|
|
152
|
+
I extends InstanceType<M>,
|
|
153
|
+
T extends I['$TShape'],
|
|
154
|
+
C extends keyof T
|
|
155
|
+
>(this: M, column: C, one: T[C], two: T[C]) {
|
|
156
|
+
return this.builder<I['$DBShape'], T>().whereNotBetween(column, one, two)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static notBetween< // @ts-ignore
|
|
160
|
+
M extends typeof Model<TB, DB>,
|
|
161
|
+
I extends InstanceType<M>,
|
|
162
|
+
T extends I['$TShape'],
|
|
163
|
+
C extends keyof T
|
|
164
|
+
>(this: M, column: C, one: T[C], two: T[C]) {
|
|
165
|
+
return this.builder<I['$DBShape'], T>().whereNotBetween(column, one, two)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
static whereNull< // @ts-ignore
|
|
169
|
+
M extends typeof Model<TB, DB>,
|
|
170
|
+
I extends InstanceType<M>,
|
|
171
|
+
T extends I['$TShape'],
|
|
172
|
+
C extends keyof T
|
|
173
|
+
>(this: M, column: C) {
|
|
174
|
+
return this.builder<I['$DBShape'], T>().whereNull(column)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
static onNull< // @ts-ignore
|
|
178
|
+
M extends typeof Model<TB, DB>,
|
|
179
|
+
I extends InstanceType<M>,
|
|
180
|
+
T extends I['$TShape'],
|
|
181
|
+
C extends keyof T
|
|
182
|
+
>(this: M, column: C) {
|
|
183
|
+
return this.builder<I['$DBShape'], T>().whereNull(column)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
static whereNotNull< // @ts-ignore
|
|
187
|
+
M extends typeof Model<TB, DB>,
|
|
188
|
+
I extends InstanceType<M>,
|
|
189
|
+
T extends I['$TShape'],
|
|
190
|
+
C extends keyof T
|
|
191
|
+
>(this: M, column: C) {
|
|
192
|
+
return this.builder<I['$DBShape'], T>().whereNotNull(column)
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
static onNotNull< // @ts-ignore
|
|
196
|
+
M extends typeof Model<TB, DB>,
|
|
197
|
+
I extends InstanceType<M>,
|
|
198
|
+
T extends I['$TShape'],
|
|
199
|
+
C extends keyof T
|
|
200
|
+
>(this: M, column: C) {
|
|
201
|
+
return this.builder<I['$DBShape'], T>().whereNotNull(column)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// TODO: groupBy(...columns: string[])
|
|
205
|
+
|
|
206
|
+
static order< // @ts-ignore
|
|
207
|
+
M extends typeof Model<TB, DB>,
|
|
208
|
+
I extends InstanceType<M>,
|
|
209
|
+
T extends I['$TShape'],
|
|
210
|
+
C extends keyof T
|
|
211
|
+
>(this: M, column: C, direction: OrderDirection = 'ASC') {
|
|
212
|
+
return this.builder<I['$DBShape'], T>().order(column, direction)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
static orderBy< // @ts-ignore
|
|
216
|
+
M extends typeof Model<TB, DB>,
|
|
217
|
+
I extends InstanceType<M>,
|
|
218
|
+
T extends I['$TShape'],
|
|
219
|
+
C extends keyof T
|
|
220
|
+
>(this: M, column: C, direction: OrderDirection = 'ASC') {
|
|
221
|
+
return this.builder<I['$DBShape'], T>().order(column, direction)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
static asc< // @ts-ignore
|
|
225
|
+
M extends typeof Model<TB, DB>,
|
|
226
|
+
I extends InstanceType<M>,
|
|
227
|
+
T extends I['$TShape'],
|
|
228
|
+
C extends keyof T
|
|
229
|
+
>(this: M, column: C) {
|
|
230
|
+
return this.builder<I['$DBShape'], T>().asc(column)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
static desc< // @ts-ignore
|
|
234
|
+
M extends typeof Model<TB, DB>,
|
|
235
|
+
I extends InstanceType<M>,
|
|
236
|
+
T extends I['$TShape'],
|
|
237
|
+
C extends keyof T
|
|
238
|
+
>(this: M, column: C) {
|
|
239
|
+
return this.builder<I['$DBShape'], T>().desc(column)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
static limit< // @ts-ignore
|
|
243
|
+
M extends typeof Model<TB, DB>,
|
|
244
|
+
I extends InstanceType<M>,
|
|
245
|
+
T extends I['$TShape']
|
|
246
|
+
>(this: M, val: number | string) {
|
|
247
|
+
return this.builder<I['$DBShape'], T>().limit(val)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
static offset< // @ts-ignore
|
|
251
|
+
M extends typeof Model<TB, DB>,
|
|
252
|
+
I extends InstanceType<M>,
|
|
253
|
+
T extends I['$TShape']
|
|
254
|
+
>(this: M, val: number | string) {
|
|
255
|
+
return this.builder<I['$DBShape'], T>().offset(val)
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
}
|