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/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<any>
31
+ export type DBSchema = z.ZodObject<z.ZodRawShape>
32
+
33
+ export type SchemaObject = z.ZodRawShape
24
34
 
25
- export type SchemaObject = Record<string, z.ZodTypeAny>
26
- export type SchemaKeys<TSchema extends DBSchema> =
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 SchemaObject
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, C extends keyof T = keyof T> = (q: IClauseBuilder<T, C>) => void
57
- export type WhereArgs<T, C extends keyof T = keyof T> = [WhereFn<T, C>] | [C, T[C]] | [C, Operator, T[C]]
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, C extends keyof T = keyof T> {
60
- where(fn: WhereFn<T, C>): this
61
- where(column: C, value: T[C]): this
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(fn: WhereFn<T, C>): this
66
- on(column: C, value: T[C]): this
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(fn: WhereFn<T, C>): this
71
- orWhere(column: C, value: T[C]): this
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(fn: WhereFn<T, C>): this
76
- orOn(column: C, value: T[C]): this
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: C, values: T[C][]): this
81
- in(column: C, values: T[C][]): this
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: C, values: T[C][]): this
84
- notIn(column: C, values: T[C][]): this
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: C, values: T[C][]): this
87
- orIn(column: C, values: T[C][]): this
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: C, values: T[C][]): this
90
- orNotIn(column: C, values: T[C][]): this
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: C, one: T[C], two: T[C]): this
93
- between(column: C, one: T[C], two: T[C]): this
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: C, one: T[C], two: T[C]): this
96
- orBetween(column: C, one: T[C], two: T[C]): this
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: C, one: T[C], two: T[C]): this
99
- notBetween(column: C, one: T[C], two: T[C]): this
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: C, one: T[C], two: T[C]): this
102
- orNotBetween(column: C, one: T[C], two: T[C]): this
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: C): this
105
- onNull(column: C): this
105
+ whereNull<K extends keyof T>(column: K): this
106
+ onNull<K extends keyof T>(column: K): this
106
107
 
107
- orWhereNull(column: C): this
108
- orOnNull(column: C): this
108
+ orWhereNull<K extends keyof T>(column: K): this
109
+ orOnNull<K extends keyof T>(column: K): this
109
110
 
110
- whereNotNull(column: C): this
111
- onNotNull(column: C): this
111
+ whereNotNull<K extends keyof T>(column: K): this
112
+ onNotNull<K extends keyof T>(column: K): this
112
113
 
113
- orWhereNotNull(column: C): this
114
- orNotNull(column: C): this
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('.') ? name : table +'.'+ name
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
- 'ZodString': 'string',
50
- 'ZodNumber': 'number',
51
- 'ZodBoolean': 'boolean',
52
- 'ZodObject': 'object',
53
- 'ZodArray': 'array',
54
- 'ZodDate': 'object',
55
- 'ZodNull': 'object',
56
- 'ZodUndefined': 'undefined',
57
- 'ZodSymbol': 'symbol',
58
- 'ZodBigInt': 'bigint',
59
- 'ZodFunction': 'function',
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
- export const zHas = (key: string, schema?: any) => schema != null && typeof schema == 'object' && !Array.isArray(schema) && (key in schema || 'shape' in schema && key in (schema.shape as Record<string, ZodTypeAny>))
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
- for (const i in keys) {
151
+
152
+ for (const k of keys) {
153
+ schema = unwrap(schema).schema
154
+
69
155
  if (typeof schema != 'object') return false
70
156
 
71
- const k = keys[i]
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
- } else if (k in schema) {
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 _ = zGet(key, schema)
88
- if (!_ || !('_def' in _[1]))
174
+ const result = zGet(key, schema)
175
+ if (!result)
89
176
  return 'unknown'
90
- key = _[0]
91
- schema = _[1]
92
177
 
93
- return ((schema?._def?.innerType?._def || schema?._def)?.typeName || '').split('Zod').pop().toLowerCase()
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 _ = zGet(key, schema)
99
- if (!_) return _
100
- key = _[0]
101
- schema = _[1]
187
+ const result = zGet(key, schema)
188
+ if (!result) return false
189
+ schema = result[1]
102
190
  }
103
191
 
104
- if (!('_def' in schema))
105
- return false // typeof val == typeof schema[key] // TODO: improv it
192
+ const _schema = unwrap(schema)
193
+
194
+ if (val === undefined) return _schema.allowUndefined
195
+ if (val === null) return _schema.allowNull
106
196
 
107
- let def = schema?._def || {}
108
- if (schema?._def?.typeName == 'ZodOptional')
109
- def = def?.innerType?._def || {}
197
+ if (!_schema.schema?._def) return false
110
198
 
111
- const zType = def?.typeName || ''
199
+ const def = _schema.schema._def
200
+ const type = getTypeName(def)
112
201
 
113
- if (!zType) return false
202
+ if (!type) return false
114
203
 
115
- if (zType == 'ZodUnion' && def?.options?.length)
116
- return def?.options?.some((z: any) => zSame(key, val, z, true))
204
+ if (type == 'ZodUnion' && def.options)
205
+ return def.options.some((z: any) => zSame(key, val, z, true))
117
206
 
118
- else if (zType == 'ZodArray')
207
+ if (type == 'ZodArray')
119
208
  return Array.isArray(val)
120
209
 
121
- else if (zType == 'ZodDate')
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[zType]
216
+ return typeof val == zodTypeMap[type]
125
217
  }
126
218
 
127
219
  export function isJoinCompare(val: any, schema?: DBSchema) {
128
- // if (!schema) return typeof val == 'string' && val?.includes('.')
129
- if (!schema || typeof val != 'string' || !val?.includes('.'))
220
+ if (typeof val != 'string' || !val?.includes('.'))
130
221
  return false
131
222
 
132
- const keys = zGet(val, schema)
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([