forj 0.1.6 → 0.1.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "forj",
3
3
  "description": "SQLite ORM and Query Builder whitout dependencies",
4
- "version": "0.1.6",
4
+ "version": "0.1.8",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
7
7
  "files": ["src"],
@@ -13,38 +13,30 @@
13
13
  "./dynamodb/types": "./src/dynamodb/types.ts",
14
14
  "./migrate": "./src/migrations/index.ts"
15
15
  },
16
- "-exports": {
17
- ".": {
18
- "import": "./dist/index.js",
19
- "types": "./dist/index.d.ts"
20
- },
21
- "./d1": {
22
- "import": "./dist/d1.js",
23
- "types": "./dist/d1.d.ts"
24
- }
25
- },
26
16
  "scripts": {
27
17
  "bench": "tsx tests/benchmark/*.bench.ts",
28
18
  "build": "tsup",
29
19
  "-prepublishOnly": "bun run build"
30
20
  },
31
21
  "dependencies": {
32
- "@aws-sdk/client-dynamodb": "3.817.0",
33
- "@aws-sdk/lib-dynamodb": "3.817.0",
22
+ "@aws-sdk/client-dynamodb": "^3.1003.0",
23
+ "@aws-sdk/lib-dynamodb": "^3.1003.0",
34
24
  "pluralize": "^8.0",
35
- "t0n": "^0.1",
36
- "zod": "^3.19.1"
25
+ "t0n": "^0.1.12",
26
+ "zod": "^4.3.6"
37
27
  },
38
28
  "devDependencies": {
29
+ "@types/node": "^25.1.0",
39
30
  "@types/pluralize": "^0.0.33",
40
31
  "@cloudflare/workers-types": "^4.20260113.0",
41
- "bun-types": "^1.2.13",
32
+ "bun-types": "^1.3.8",
42
33
  "terser": "^5.46.0",
43
34
  "tiny-glob": "^0.2",
44
- "tsup": "^8.5.1",
35
+ "tsup": "^8.5.0",
45
36
  "tsx": "^4.19.4",
46
- "typescript": "^5.8.3"
37
+ "typescript": "^5.9.3"
47
38
  },
39
+ "packageManager": "bun@1.3.10",
48
40
  "engines": {
49
41
  "node": ">=18.0.0"
50
42
  },
@@ -39,7 +39,7 @@ export default class ClauseBuilder<
39
39
  this.#schema = schema
40
40
  }
41
41
 
42
- #nested(fn: WhereFn<T, C>, operator: ClauseOperator = 'AND') {
42
+ #nested(fn: WhereFn<T>, operator: ClauseOperator = 'AND') {
43
43
  const nested = new ClauseBuilder<T, C>(this.#table, this.#schema)
44
44
  fn(nested)
45
45
 
@@ -80,7 +80,7 @@ export default class ClauseBuilder<
80
80
  column = parseColumn(String(column), this.#table)
81
81
 
82
82
  if (this.#schema && !zSame(column.replace(/"/g, ''), 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}'.`)
83
+ throw new Error(`Table column '${String(column.replace(/"/g, ''))}' of type '${zType(column.replace(/"/g, ''), this.#schema)}' is not assignable as type of '${typeof value}'.`)
84
84
 
85
85
  return isJoinCompare(value, this.#schema) // @ts-ignore
86
86
  ? this.#clause(`${column} ${operator} ${value}`, [], logical) // @ts-ignore
@@ -111,31 +111,31 @@ export default class ClauseBuilder<
111
111
  return this.#clause(parseColumn(column, this.#table) + ` ${operator} (${values.map(() => '?').join(', ')})`, values, logical)
112
112
  }
113
113
 
114
- whereIn(column: C, values: T[C][]) { // @ts-ignore
114
+ whereIn<K extends keyof T>(column: K, values: T[K][]) { // @ts-ignore
115
115
  return this.#in(column, values, 'IN')
116
116
  }
117
- in(column: C, values: T[C][]) {
117
+ in<K extends keyof T>(column: K, values: T[K][]) {
118
118
  return this.whereIn(column, values)
119
119
  }
120
120
 
121
- whereNotIn(column: C, values: T[C][]) { // @ts-ignore
121
+ whereNotIn<K extends keyof T>(column: K, values: T[K][]) { // @ts-ignore
122
122
  return this.#in(column, values, 'NOT IN')
123
123
  }
124
- notIn(column: C, values: T[C][]) {
124
+ notIn<K extends keyof T>(column: K, values: T[K][]) {
125
125
  return this.whereNotIn(column, values)
126
126
  }
127
127
 
128
- orWhereIn(column: C, values: T[C][]) { // @ts-ignore
128
+ orWhereIn<K extends keyof T>(column: K, values: T[K][]) { // @ts-ignore
129
129
  return this.#in(column, values, 'IN', 'OR')
130
130
  }
131
- orIn(column: C, values: T[C][]) {
131
+ orIn<K extends keyof T>(column: K, values: T[K][]) {
132
132
  return this.orWhereIn(column, values)
133
133
  }
134
134
 
135
- orWhereNotIn(column: C, values: T[C][]) { // @ts-ignore
135
+ orWhereNotIn<K extends keyof T>(column: K, values: T[K][]) { // @ts-ignore
136
136
  return this.#in(column, values, 'NOT IN', 'OR')
137
137
  }
138
- orNotIn(column: C, values: T[C][]) {
138
+ orNotIn<K extends keyof T>(column: K, values: T[K][]) {
139
139
  return this.orWhereNotIn(column, values)
140
140
  }
141
141
 
@@ -149,31 +149,31 @@ export default class ClauseBuilder<
149
149
  return this.#clause(parseColumn(column, this.#table) + ` ${operator} ? AND ?`, [one, two], logical)
150
150
  }
151
151
 
152
- whereBetween(column: C, one: T[C], two: T[C]) { // @ts-ignore
152
+ whereBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) { // @ts-ignore
153
153
  return this.#between(column, one, two, 'BETWEEN')
154
154
  }
155
- between(column: C, one: T[C], two: T[C]) {
155
+ between<K extends keyof T>(column: K, one: T[K], two: T[K]) {
156
156
  return this.whereBetween(column, one, two)
157
157
  }
158
158
 
159
- orWhereBetween(column: C, one: T[C], two: T[C]) { // @ts-ignore
159
+ orWhereBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) { // @ts-ignore
160
160
  return this.#between(column, one, two, 'BETWEEN', 'OR')
161
161
  }
162
- orBetween(column: C, one: T[C], two: T[C]) {
162
+ orBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) {
163
163
  return this.orWhereBetween(column, one, two)
164
164
  }
165
165
 
166
- whereNotBetween(column: C, one: T[C], two: T[C]) { // @ts-ignore
166
+ whereNotBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) { // @ts-ignore
167
167
  return this.#between(column, one, two, 'NOT BETWEEN')
168
168
  }
169
- notBetween(column: C, one: T[C], two: T[C]) {
169
+ notBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) {
170
170
  return this.whereNotBetween(column, one, two)
171
171
  }
172
172
 
173
- orWhereNotBetween(column: C, one: T[C], two: T[C]) { // @ts-ignore
173
+ orWhereNotBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) { // @ts-ignore
174
174
  return this.#between(column, one, two, 'NOT BETWEEN', 'OR')
175
175
  }
176
- orNotBetween(column: C, one: T[C], two: T[C]) {
176
+ orNotBetween<K extends keyof T>(column: K, one: T[K], two: T[K]) {
177
177
  return this.orWhereNotBetween(column, one, two)
178
178
  }
179
179
 
@@ -185,31 +185,31 @@ export default class ClauseBuilder<
185
185
  return this.#clause(parseColumn(column, this.#table) +` ${operator} NULL`, [], logical)
186
186
  }
187
187
 
188
- whereNull(column: C) {
188
+ whereNull<K extends keyof T>(column: K) {
189
189
  return this.#null(column as string)
190
190
  }
191
- onNull(column: C) {
191
+ onNull<K extends keyof T>(column: K) {
192
192
  return this.whereNull(column)
193
193
  }
194
194
 
195
- orWhereNull(column: C) {
195
+ orWhereNull<K extends keyof T>(column: K) {
196
196
  return this.#null(column as string, 'IS', 'OR')
197
197
  }
198
- orOnNull(column: C) {
198
+ orOnNull<K extends keyof T>(column: K) {
199
199
  return this.orWhereNull(column)
200
200
  }
201
201
 
202
- whereNotNull(column: C) {
202
+ whereNotNull<K extends keyof T>(column: K) {
203
203
  return this.#null(column as string, 'IS NOT')
204
204
  }
205
- onNotNull(column: C) {
205
+ onNotNull<K extends keyof T>(column: K) {
206
206
  return this.whereNotNull(column)
207
207
  }
208
208
 
209
- orWhereNotNull(column: C) {
209
+ orWhereNotNull<K extends keyof T>(column: K) {
210
210
  return this.#null(column as string, 'IS NOT', 'OR')
211
211
  }
212
- orNotNull(column: C) {
212
+ orNotNull<K extends keyof T>(column: K) {
213
213
  return this.orWhereNotNull(column)
214
214
  }
215
215
  }
package/src/d1/model.ts CHANGED
@@ -4,22 +4,22 @@ import type {
4
4
  // D1Result, D1ExecResult, D1Meta,
5
5
  } from './types'
6
6
 
7
- import z from 'zod'
7
+ import type * as z from 'zod'
8
8
  import { Envir } from 't0n'
9
9
 
10
10
  import QueryBuilder from '../query-builder'
11
11
  import BModel from '../model'
12
12
  import type {
13
- DBSchema, SchemaKeys,
13
+ DBSchema,
14
14
  Item,
15
15
  Pipe, Result, RunFn,
16
16
  } from '../types'
17
17
 
18
18
  export function Model<
19
19
  TSchema extends DBSchema,
20
- TBase extends SchemaKeys<TSchema>
20
+ TBase extends keyof z.infer<TSchema>
21
21
  >(schema: TSchema, base: TBase) {
22
- type S = z.infer<typeof schema>
22
+ type S = z.infer<TSchema>
23
23
  return class extends BaseModel<TBase, S> {
24
24
  static $table = String(base)
25
25
  static $schema = schema
@@ -55,8 +55,9 @@ export abstract class BaseModel<TB extends keyof DB, DB> extends BModel<TB, DB>
55
55
  ): Promise<Result<T, C>> => {
56
56
  let stmt = db.prepare(qb.query)
57
57
 
58
- if (qb.args?.length)
59
- stmt = stmt.bind(...qb.args)
58
+ const args = qb.args
59
+ if (args?.length)
60
+ stmt = stmt.bind(...args)
60
61
 
61
62
  const resp = await stmt.run<Item<T, C>>()
62
63
 
@@ -1,11 +1,11 @@
1
- import { z, ZodTypeAny } from 'zod'
1
+ import type * as z from 'zod'
2
2
  import { Dynamodb } from './client'
3
3
  import { Schema } from './schema'
4
4
  import { _model } from './decorators'
5
5
  import type { ModelOpts } from './types'
6
6
 
7
7
  export function Repository<
8
- S extends ZodTypeAny,
8
+ S extends z.ZodTypeAny,
9
9
  B extends new (...args: any[]) => any
10
10
  >(
11
11
  schema: S,
@@ -1,4 +1,4 @@
1
- import { z, ZodTypeAny } from 'zod'
1
+ import * as z from 'zod'
2
2
  import type { SchemaStructure } from './types'
3
3
 
4
4
  const m = Symbol('a')
@@ -12,17 +12,26 @@ export function arraySchema(v: any): any {
12
12
  return v
13
13
  }
14
14
 
15
- export function extractZodKeys(schema: ZodTypeAny): SchemaStructure {
15
+ function getArrayItem(schema: z.ZodArray<any>): z.ZodTypeAny {
16
+ const def: any = schema._def
17
+ return (def.element ?? def.type ?? def.innerType) as z.ZodTypeAny
18
+ }
19
+
20
+ export function extractZodKeys(schema: z.ZodTypeAny): SchemaStructure {
16
21
  if (schema instanceof z.ZodObject) {
17
- return Object.entries(schema.shape).map(([key, value]) => {
18
- const inner = unwrap(value as ZodTypeAny)
22
+ const shape = schema.shape
23
+
24
+ return Object.entries(shape).map(([key, value]) => {
25
+ const inner = unwrap(value as z.ZodTypeAny)
19
26
 
20
27
  if (inner instanceof z.ZodObject)
21
28
  return notEmpty(key, extractZodKeys(inner))
22
29
 
23
30
  if (inner instanceof z.ZodArray) {
24
- const item = unwrap(inner._def.type as ZodTypeAny)
25
- return item instanceof z.ZodObject ? notEmpty(key, extractZodKeys(item)) : key
31
+ const item = unwrap(getArrayItem(inner))
32
+ return item instanceof z.ZodObject
33
+ ? notEmpty(key, extractZodKeys(item))
34
+ : key
26
35
  }
27
36
 
28
37
  return key
@@ -30,7 +39,8 @@ export function extractZodKeys(schema: ZodTypeAny): SchemaStructure {
30
39
  }
31
40
 
32
41
  if (schema instanceof z.ZodArray) {
33
- const item = unwrap(schema._def.type as ZodTypeAny)
42
+ const item = unwrap(getArrayItem(schema))
43
+
34
44
  if (item instanceof z.ZodObject)
35
45
  return arraySchema(extractZodKeys(item))
36
46
 
@@ -40,24 +50,42 @@ export function extractZodKeys(schema: ZodTypeAny): SchemaStructure {
40
50
  return []
41
51
  }
42
52
 
43
- export function unwrap(schema: ZodTypeAny): ZodTypeAny {
44
- if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable)
45
- return unwrap(schema._def.innerType)
53
+ export function unwrap(schema: z.ZodTypeAny): z.ZodTypeAny {
54
+ while (true) {
55
+ if (schema instanceof z.ZodOptional || schema instanceof z.ZodNullable) {
56
+ schema = (schema._def as any).innerType
57
+ continue
58
+ }
46
59
 
47
- if (schema instanceof z.ZodDefault)
48
- return unwrap(schema._def.innerType)
60
+ if (schema instanceof z.ZodDefault) {
61
+ schema = (schema._def as any).innerType
62
+ continue
63
+ }
49
64
 
50
- // if (schema instanceof z.ZodUnion)
51
- // return unwrap(schema._def.options[0] as ZodTypeAny)
65
+ if (schema instanceof z.ZodUnion) {
66
+ const options = (schema._def as any).options as z.ZodTypeAny[]
67
+ const nonEmpty = options.find(
68
+ opt => !(opt instanceof z.ZodUndefined) && !(opt instanceof z.ZodNull)
69
+ )
70
+ schema = nonEmpty ?? options[0]
71
+ continue
72
+ }
52
73
 
53
- if (schema instanceof z.ZodUnion) {
54
- const options = schema._def.options as ZodTypeAny[]
55
- const nonEmptyOption = options.find(opt => !(opt instanceof z.ZodUndefined) && !(opt instanceof z.ZodNull))
56
- return nonEmptyOption ? unwrap(nonEmptyOption) : options[0]
57
- }
74
+ const def: any = schema._def
75
+
76
+ // unwrap transforms / pipes do v4
77
+ if (def?.schema) {
78
+ schema = def.schema
79
+ continue
80
+ }
58
81
 
59
- if (schema instanceof z.ZodEffects)
60
- return unwrap(schema._def.schema)
82
+ if (def?.innerType) {
83
+ schema = def.innerType
84
+ continue
85
+ }
86
+
87
+ break
88
+ }
61
89
 
62
90
  return schema
63
91
  }
@@ -67,7 +95,7 @@ function notEmpty(key: string, schema: SchemaStructure): string | Record<string,
67
95
  }
68
96
 
69
97
  export function Schema<
70
- T extends ZodTypeAny,
98
+ T extends z.ZodTypeAny,
71
99
  B extends object
72
100
  >(
73
101
  schema: T,