forj 0.1.5 → 0.1.7
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/package.json +5 -5
- package/src/clause-builder.ts +27 -28
- package/src/d1/model.ts +6 -5
- package/src/dynamodb/schema.ts +45 -17
- package/src/model.ts +270 -14
- package/src/query-builder.ts +250 -48
- package/src/types.ts +49 -58
- package/src/utils.ts +137 -41
package/src/types.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import z from 'zod'
|
|
2
2
|
import QueryBuilder from './query-builder'
|
|
3
|
+
import { types } from './utils'
|
|
3
4
|
|
|
4
5
|
export type text = string
|
|
5
6
|
export type real = number
|
|
@@ -15,18 +16,26 @@ export type Values = Value[]
|
|
|
15
16
|
// export type WriteType = Primitive | ArrayBuffer | ArrayBufferView | undefined
|
|
16
17
|
// export type ReadType = Primitive | any[]
|
|
17
18
|
|
|
19
|
+
export type QueryType = typeof types[keyof typeof types]
|
|
20
|
+
export type TableOpts = {
|
|
21
|
+
timestamps?: boolean,
|
|
22
|
+
createdAt?: boolean,
|
|
23
|
+
updatedAt?: boolean,
|
|
24
|
+
}
|
|
25
|
+
|
|
18
26
|
export type Operator = '=' | '!=' | '<' | '>' | '<=' | '>=' | 'LIKE' // | 'IN' | 'NOT IN' | 'BETWEEN' | 'IS NULL' | 'IS NOT NULL'
|
|
19
27
|
export type OrderDirection = 'ASC' | 'DESC' | 'asc' | 'desc'
|
|
20
28
|
|
|
21
29
|
export type JoinType = 'INNER' | 'LEFT' | 'RIGHT' | 'CROSS'
|
|
22
30
|
|
|
23
|
-
export type DBSchema = z.ZodObject<
|
|
31
|
+
export type DBSchema = z.ZodObject<z.ZodRawShape>
|
|
32
|
+
|
|
33
|
+
export type SchemaObject = z.ZodRawShape
|
|
24
34
|
|
|
25
|
-
export type
|
|
26
|
-
|
|
27
|
-
TSchema extends z.ZodObject<infer TShape>
|
|
35
|
+
export type SchemaKeys<TSchema extends DBSchema | SchemaObject> =
|
|
36
|
+
TSchema extends z.ZodObject<infer TShape extends z.ZodRawShape>
|
|
28
37
|
? keyof TShape
|
|
29
|
-
: TSchema extends
|
|
38
|
+
: TSchema extends z.ZodRawShape
|
|
30
39
|
? keyof TSchema
|
|
31
40
|
: never
|
|
32
41
|
|
|
@@ -53,65 +62,57 @@ export type Item<B, S extends keyof B, T = Pick<B, S>> = { [K in keyof T]: T[K]
|
|
|
53
62
|
|
|
54
63
|
export type ClauseOperator = 'AND' | 'OR'
|
|
55
64
|
|
|
56
|
-
export type WhereFn<T
|
|
57
|
-
export type WhereArgs<T, C extends keyof T = keyof T> = [WhereFn<T
|
|
65
|
+
export type WhereFn<T> = (q: IClauseBuilder<T>) => void
|
|
66
|
+
export type WhereArgs<T, C extends keyof T = keyof T> = [WhereFn<T>] | [C, T[C]] | [C, Operator, T[C]]
|
|
58
67
|
|
|
59
|
-
export interface IClauseBuilder<T
|
|
60
|
-
where(
|
|
61
|
-
where(column:
|
|
62
|
-
where(column: C, operator: Operator, value: T[C]): this
|
|
63
|
-
where(...args: WhereArgs<T>): this
|
|
68
|
+
export interface IClauseBuilder<T> {
|
|
69
|
+
where<K extends keyof T>(column: K, value: T[K]): this
|
|
70
|
+
where<K extends keyof T>(column: K, operator: Operator, value: T[K]): this
|
|
64
71
|
|
|
65
|
-
on(
|
|
66
|
-
on(column:
|
|
67
|
-
on(column: C, operator: Operator, value: T[C]): this
|
|
68
|
-
on(...args: WhereArgs<T>): this
|
|
72
|
+
on<K extends keyof T>(column: K, value: T[K]): this
|
|
73
|
+
on<K extends keyof T>(column: K, operator: Operator, value: T[K]): this
|
|
69
74
|
|
|
70
|
-
orWhere(
|
|
71
|
-
orWhere(column:
|
|
72
|
-
orWhere(column: C, operator: Operator, value: T[C]): this
|
|
73
|
-
orWhere(...args: WhereArgs<T>): this
|
|
75
|
+
orWhere<K extends keyof T>(column: K, value: T[K]): this
|
|
76
|
+
orWhere<K extends keyof T>(column: K, operator: Operator, value: T[K]): this
|
|
74
77
|
|
|
75
|
-
orOn(
|
|
76
|
-
orOn(column:
|
|
77
|
-
orOn(column: C, operator: Operator, value: T[C]): this
|
|
78
|
-
orOn(...args: WhereArgs<T>): this
|
|
78
|
+
orOn<K extends keyof T>(column: K, value: T[K]): this
|
|
79
|
+
orOn<K extends keyof T>(column: K, operator: Operator, value: T[K]): this
|
|
79
80
|
|
|
80
|
-
whereIn(column:
|
|
81
|
-
in(column:
|
|
81
|
+
whereIn<K extends keyof T>(column: K, values: T[K][]): this
|
|
82
|
+
in<K extends keyof T>(column: K, values: T[K][]): this
|
|
82
83
|
|
|
83
|
-
whereNotIn(column:
|
|
84
|
-
notIn(column:
|
|
84
|
+
whereNotIn<K extends keyof T>(column: K, values: T[K][]): this
|
|
85
|
+
notIn<K extends keyof T>(column: K, values: T[K][]): this
|
|
85
86
|
|
|
86
|
-
orWhereIn(column:
|
|
87
|
-
orIn(column:
|
|
87
|
+
orWhereIn<K extends keyof T>(column: K, values: T[K][]): this
|
|
88
|
+
orIn<K extends keyof T>(column: K, values: T[K][]): this
|
|
88
89
|
|
|
89
|
-
orWhereNotIn(column:
|
|
90
|
-
orNotIn(column:
|
|
90
|
+
orWhereNotIn<K extends keyof T>(column: K, values: T[K][]): this
|
|
91
|
+
orNotIn<K extends keyof T>(column: K, values: T[K][]): this
|
|
91
92
|
|
|
92
|
-
whereBetween(column:
|
|
93
|
-
between(column:
|
|
93
|
+
whereBetween<K extends keyof T>(column: K, one: T[K], two: T[K]): this
|
|
94
|
+
between<K extends keyof T>(column: K, one: T[K], two: T[K]): this
|
|
94
95
|
|
|
95
|
-
orWhereBetween(column:
|
|
96
|
-
orBetween(column:
|
|
96
|
+
orWhereBetween<K extends keyof T>(column: K, one: T[K], two: T[K]): this
|
|
97
|
+
orBetween<K extends keyof T>(column: K, one: T[K], two: T[K]): this
|
|
97
98
|
|
|
98
|
-
whereNotBetween(column:
|
|
99
|
-
notBetween(column:
|
|
99
|
+
whereNotBetween<K extends keyof T>(column: K, one: T[K], two: T[K]): this
|
|
100
|
+
notBetween<K extends keyof T>(column: K, one: T[K], two: T[K]): this
|
|
100
101
|
|
|
101
|
-
orWhereNotBetween(column:
|
|
102
|
-
orNotBetween(column:
|
|
102
|
+
orWhereNotBetween<K extends keyof T>(column: K, one: T[K], two: T[K]): this
|
|
103
|
+
orNotBetween<K extends keyof T>(column: K, one: T[K], two: T[K]): this
|
|
103
104
|
|
|
104
|
-
whereNull(column:
|
|
105
|
-
onNull(column:
|
|
105
|
+
whereNull<K extends keyof T>(column: K): this
|
|
106
|
+
onNull<K extends keyof T>(column: K): this
|
|
106
107
|
|
|
107
|
-
orWhereNull(column:
|
|
108
|
-
orOnNull(column:
|
|
108
|
+
orWhereNull<K extends keyof T>(column: K): this
|
|
109
|
+
orOnNull<K extends keyof T>(column: K): this
|
|
109
110
|
|
|
110
|
-
whereNotNull(column:
|
|
111
|
-
onNotNull(column:
|
|
111
|
+
whereNotNull<K extends keyof T>(column: K): this
|
|
112
|
+
onNotNull<K extends keyof T>(column: K): this
|
|
112
113
|
|
|
113
|
-
orWhereNotNull(column:
|
|
114
|
-
orNotNull(column:
|
|
114
|
+
orWhereNotNull<K extends keyof T>(column: K): this
|
|
115
|
+
orNotNull<K extends keyof T>(column: K): this
|
|
115
116
|
}
|
|
116
117
|
|
|
117
118
|
export type JoinArgs<S, J extends keyof S> =
|
|
@@ -123,7 +124,6 @@ export type JoinArgs<S, J extends keyof S> =
|
|
|
123
124
|
| [keyof S[J], Operator, keyof S, keyof S[keyof S]]
|
|
124
125
|
|
|
125
126
|
export interface IJoinBuilder<S> {
|
|
126
|
-
join<J extends keyof S>(table: J, fn: WhereFn<S[J]>): this
|
|
127
127
|
join<
|
|
128
128
|
J extends keyof S,
|
|
129
129
|
T extends S[J],
|
|
@@ -148,9 +148,7 @@ export interface IJoinBuilder<S> {
|
|
|
148
148
|
J2 extends keyof S,
|
|
149
149
|
C2 extends keyof S[J2],
|
|
150
150
|
>(table: J, column: C, operator: Operator, table2: J2, column2: C2): this
|
|
151
|
-
join<J extends keyof S>(table: J, ...args: JoinArgs<S, J>): this
|
|
152
151
|
|
|
153
|
-
innerJoin<J extends keyof S>(table: J, fn: WhereFn<S[J]>): this
|
|
154
152
|
innerJoin<
|
|
155
153
|
J extends keyof S,
|
|
156
154
|
T extends S[J],
|
|
@@ -175,9 +173,7 @@ export interface IJoinBuilder<S> {
|
|
|
175
173
|
J2 extends keyof S,
|
|
176
174
|
C2 extends keyof S[J2],
|
|
177
175
|
>(table: J, column: C, operator: Operator, table2: J2, column2: C2): this
|
|
178
|
-
innerJoin<J extends keyof S>(table: J, ...args: JoinArgs<S, J>): this
|
|
179
176
|
|
|
180
|
-
leftJoin<J extends keyof S>(table: J, fn: WhereFn<S[J]>): this
|
|
181
177
|
leftJoin<
|
|
182
178
|
J extends keyof S,
|
|
183
179
|
T extends S[J],
|
|
@@ -202,9 +198,7 @@ export interface IJoinBuilder<S> {
|
|
|
202
198
|
J2 extends keyof S,
|
|
203
199
|
C2 extends keyof S[J2],
|
|
204
200
|
>(table: J, column: C, operator: Operator, table2: J2, column2: C2): this
|
|
205
|
-
leftJoin<J extends keyof S>(table: J, ...args: JoinArgs<S, J>): this
|
|
206
201
|
|
|
207
|
-
rightJoin<J extends keyof S>(table: J, fn: WhereFn<S[J]>): this
|
|
208
202
|
rightJoin<
|
|
209
203
|
J extends keyof S,
|
|
210
204
|
T extends S[J],
|
|
@@ -229,9 +223,7 @@ export interface IJoinBuilder<S> {
|
|
|
229
223
|
J2 extends keyof S,
|
|
230
224
|
C2 extends keyof S[J2],
|
|
231
225
|
>(table: J, column: C, operator: Operator, table2: J2, column2: C2): this
|
|
232
|
-
rightJoin<J extends keyof S>(table: J, ...args: JoinArgs<S, J>): this
|
|
233
226
|
|
|
234
|
-
crossJoin<J extends keyof S>(table: J, fn: WhereFn<S[J]>): this
|
|
235
227
|
crossJoin<
|
|
236
228
|
J extends keyof S,
|
|
237
229
|
T extends S[J],
|
|
@@ -256,5 +248,4 @@ export interface IJoinBuilder<S> {
|
|
|
256
248
|
J2 extends keyof S,
|
|
257
249
|
C2 extends keyof S[J2],
|
|
258
250
|
>(table: J, column: C, operator: Operator, table2: J2, column2: C2): this
|
|
259
|
-
crossJoin<J extends keyof S>(table: J, ...args: JoinArgs<S, J>): this
|
|
260
251
|
}
|
package/src/utils.ts
CHANGED
|
@@ -2,6 +2,13 @@ import pluralize from 'pluralize'
|
|
|
2
2
|
import type { ZodTypeAny } from 'zod'
|
|
3
3
|
import type { DBSchema } from './types'
|
|
4
4
|
|
|
5
|
+
export const types = {
|
|
6
|
+
SELECT: 1,
|
|
7
|
+
INSERT: 2,
|
|
8
|
+
UPDATE: 3,
|
|
9
|
+
DELETE: 4,
|
|
10
|
+
} as const
|
|
11
|
+
|
|
5
12
|
const operators = ['=', '!=', '>', '<', '>=', '<=', 'LIKE', 'IN', 'NOT IN', 'IS', 'IS NOT', 'BETWEEN']
|
|
6
13
|
|
|
7
14
|
export function isOperator(o: any) {
|
|
@@ -21,11 +28,15 @@ export function parseSelectColumn(
|
|
|
21
28
|
return col
|
|
22
29
|
|
|
23
30
|
const [table, column] = explicit ? col.split('.') : [baseTable, col]
|
|
31
|
+
if (column == '*') return col
|
|
32
|
+
|
|
24
33
|
return `${table}.${column} AS ${pluralize(table, 1)}_${column}`
|
|
25
34
|
}
|
|
26
35
|
|
|
27
36
|
export function parseColumn(name: string, table: string, hasJoin: boolean = true) {
|
|
28
|
-
return !hasJoin || name.includes('.')
|
|
37
|
+
return !hasJoin || name.includes('.')
|
|
38
|
+
? name.split('.').map(col => sqlName(col)).join('.')
|
|
39
|
+
: sqlName(table) + '.' + sqlName(name)
|
|
29
40
|
}
|
|
30
41
|
|
|
31
42
|
export function formatValue(value: any): string {
|
|
@@ -46,33 +57,109 @@ export function formatValue(value: any): string {
|
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
const zodTypeMap: Record<string, string> = {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
ZodString: 'string',
|
|
61
|
+
ZodNumber: 'number',
|
|
62
|
+
ZodBoolean: 'boolean',
|
|
63
|
+
ZodObject: 'object',
|
|
64
|
+
ZodArray: 'array',
|
|
65
|
+
ZodDate: 'object',
|
|
66
|
+
ZodNull: 'object',
|
|
67
|
+
ZodUndefined: 'undefined',
|
|
68
|
+
ZodSymbol: 'symbol',
|
|
69
|
+
ZodBigInt: 'bigint',
|
|
70
|
+
ZodFunction: 'function',
|
|
60
71
|
}
|
|
61
72
|
|
|
62
73
|
export const isZod = (obj: any): obj is ZodTypeAny => obj && typeof obj == 'object' && '_def' in obj
|
|
63
74
|
|
|
64
|
-
|
|
75
|
+
const getDef = (schema: any) => schema?._def ?? {}
|
|
76
|
+
|
|
77
|
+
const getTypeName = (def: any): string => {
|
|
78
|
+
if (!def) return ''
|
|
79
|
+
if (def.typeName) return def.typeName // zod v3
|
|
80
|
+
if (def.type) { // zod v4
|
|
81
|
+
if (typeof def.type == 'string') {
|
|
82
|
+
if (def.type.startsWith('Zod')) return def.type
|
|
83
|
+
return 'Zod'+ def.type[0].toUpperCase() + def.type.slice(1)
|
|
84
|
+
// return zodTypeMap[def.type] || def.type
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (def.type?.name) return def.type.name
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return ''
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const unwrap = (schema: any): any => {
|
|
94
|
+
let current = schema
|
|
95
|
+
let allowNull = false
|
|
96
|
+
let allowUndefined = false
|
|
97
|
+
|
|
98
|
+
while (current?._def) {
|
|
99
|
+
const def = current._def
|
|
100
|
+
const type = getTypeName(def)
|
|
101
|
+
|
|
102
|
+
if (type == 'ZodNullable')
|
|
103
|
+
allowNull = true
|
|
104
|
+
|
|
105
|
+
if (type == 'ZodOptional' || type == 'ZodDefault')
|
|
106
|
+
allowUndefined = true
|
|
107
|
+
|
|
108
|
+
if (['ZodOptional', 'ZodNullable', 'ZodDefault', 'ZodReadonly'].includes(type)) {
|
|
109
|
+
current = def.innerType
|
|
110
|
+
continue
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (type == 'ZodEffects' || type == 'ZodPipeline') {
|
|
114
|
+
current = def.schema || def.innerType || def.out
|
|
115
|
+
continue
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
break
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return { schema: current, allowNull, allowUndefined }
|
|
122
|
+
// return current
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export const zHas = (key: string, schema?: any): boolean => {
|
|
126
|
+
if (!schema || typeof schema != 'object' || Array.isArray(schema))
|
|
127
|
+
return false
|
|
128
|
+
|
|
129
|
+
const keys = key.split('.')
|
|
130
|
+
|
|
131
|
+
for (const k of keys) {
|
|
132
|
+
schema = unwrap(schema).schema
|
|
133
|
+
|
|
134
|
+
if (!schema || typeof schema != 'object')
|
|
135
|
+
return false
|
|
136
|
+
|
|
137
|
+
if (schema.shape && k in schema.shape) {
|
|
138
|
+
schema = schema.shape[k]
|
|
139
|
+
} else if (k in schema) {
|
|
140
|
+
schema = schema[k]
|
|
141
|
+
} else {
|
|
142
|
+
return false
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return true
|
|
147
|
+
}
|
|
65
148
|
|
|
66
149
|
export const zGet = (key: string, schema?: any): [string, ZodTypeAny] | false => {
|
|
67
150
|
const keys = key.split('.')
|
|
68
|
-
|
|
151
|
+
|
|
152
|
+
for (const k of keys) {
|
|
153
|
+
schema = unwrap(schema).schema
|
|
154
|
+
|
|
69
155
|
if (typeof schema != 'object') return false
|
|
70
156
|
|
|
71
|
-
|
|
72
|
-
if ('shape' in schema && k in schema.shape) {
|
|
157
|
+
if (schema?.shape && k in schema.shape) {
|
|
73
158
|
schema = schema.shape[k]
|
|
74
159
|
continue
|
|
75
|
-
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (k in schema) {
|
|
76
163
|
schema = schema[k]
|
|
77
164
|
continue
|
|
78
165
|
}
|
|
@@ -84,54 +171,63 @@ export const zGet = (key: string, schema?: any): [string, ZodTypeAny] | false =>
|
|
|
84
171
|
}
|
|
85
172
|
|
|
86
173
|
export const zType = (key: string, schema?: any): string => {
|
|
87
|
-
const
|
|
88
|
-
if (!
|
|
174
|
+
const result = zGet(key, schema)
|
|
175
|
+
if (!result)
|
|
89
176
|
return 'unknown'
|
|
90
|
-
key = _[0]
|
|
91
|
-
schema = _[1]
|
|
92
177
|
|
|
93
|
-
|
|
178
|
+
const type = getTypeName(getDef(unwrap(result[1]).schema))
|
|
179
|
+
if (!type)
|
|
180
|
+
return 'unknown'
|
|
181
|
+
|
|
182
|
+
return type.replace('Zod', '').toLowerCase()
|
|
94
183
|
}
|
|
95
184
|
|
|
96
185
|
export const zSame = (key: string, val: any, schema?: any, deep: boolean = false): boolean => {
|
|
97
186
|
if (!deep) {
|
|
98
|
-
const
|
|
99
|
-
if (!
|
|
100
|
-
|
|
101
|
-
schema = _[1]
|
|
187
|
+
const result = zGet(key, schema)
|
|
188
|
+
if (!result) return false
|
|
189
|
+
schema = result[1]
|
|
102
190
|
}
|
|
103
191
|
|
|
104
|
-
|
|
105
|
-
|
|
192
|
+
const _schema = unwrap(schema)
|
|
193
|
+
|
|
194
|
+
if (val === undefined) return _schema.allowUndefined
|
|
195
|
+
if (val === null) return _schema.allowNull
|
|
106
196
|
|
|
107
|
-
|
|
108
|
-
if (schema?._def?.typeName == 'ZodOptional')
|
|
109
|
-
def = def?.innerType?._def || {}
|
|
197
|
+
if (!_schema.schema?._def) return false
|
|
110
198
|
|
|
111
|
-
const
|
|
199
|
+
const def = _schema.schema._def
|
|
200
|
+
const type = getTypeName(def)
|
|
112
201
|
|
|
113
|
-
if (!
|
|
202
|
+
if (!type) return false
|
|
114
203
|
|
|
115
|
-
if (
|
|
116
|
-
return def
|
|
204
|
+
if (type == 'ZodUnion' && def.options)
|
|
205
|
+
return def.options.some((z: any) => zSame(key, val, z, true))
|
|
117
206
|
|
|
118
|
-
|
|
207
|
+
if (type == 'ZodArray')
|
|
119
208
|
return Array.isArray(val)
|
|
120
209
|
|
|
121
|
-
|
|
210
|
+
if (type == 'ZodObject')
|
|
211
|
+
return typeof val == 'object' && val != null && !Array.isArray(val)
|
|
212
|
+
|
|
213
|
+
if (type == 'ZodDate')
|
|
122
214
|
return val instanceof Date
|
|
123
215
|
|
|
124
|
-
return typeof val == zodTypeMap[
|
|
216
|
+
return typeof val == zodTypeMap[type]
|
|
125
217
|
}
|
|
126
218
|
|
|
127
219
|
export function isJoinCompare(val: any, schema?: DBSchema) {
|
|
128
|
-
|
|
129
|
-
if (!schema || typeof val != 'string' || !val?.includes('.'))
|
|
220
|
+
if (typeof val != 'string' || !val?.includes('.'))
|
|
130
221
|
return false
|
|
131
222
|
|
|
132
|
-
|
|
223
|
+
if (!schema)
|
|
224
|
+
return true
|
|
225
|
+
|
|
226
|
+
const keys = zGet(val.replace(/"/g, ''), schema)
|
|
227
|
+
// const keys = zGet(val, schema)
|
|
133
228
|
return keys && keys?.length
|
|
134
229
|
}
|
|
230
|
+
|
|
135
231
|
// List taken from `aKeywordTable` in https://github.com/sqlite/sqlite/blob/378bf82e2bc09734b8c5869f9b148efe37d29527/tool/mkkeywordhash.c#L172
|
|
136
232
|
// prettier-ignore
|
|
137
233
|
export const SQLITE_KEYWORDS = new Set([
|