bun-query-builder 0.1.58 → 0.1.60
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/dist/bin/cli.js +345 -220
- package/dist/db.d.ts +4 -0
- package/dist/index.d.ts +1 -0
- package/dist/inflect.d.ts +29 -0
- package/dist/orm.d.ts +67 -8
- package/dist/src/index.js +350 -222
- package/dist/type-inference.d.ts +112 -25
- package/dist/types.d.ts +1 -1
- package/package.json +2 -2
package/dist/type-inference.d.ts
CHANGED
|
@@ -32,7 +32,7 @@ declare interface InferableModelDefinition {
|
|
|
32
32
|
readonly useAuth?: boolean | object
|
|
33
33
|
readonly billable?: boolean | object
|
|
34
34
|
}
|
|
35
|
-
readonly belongsTo?: readonly string[] | Readonly<Record<string, string>>
|
|
35
|
+
readonly belongsTo?: readonly (string | object)[] | Readonly<Record<string, string | object>>
|
|
36
36
|
readonly hasMany?: readonly string[] | Readonly<Record<string, string>>
|
|
37
37
|
readonly hasOne?: readonly string[] | Readonly<Record<string, string>>
|
|
38
38
|
readonly belongsToMany?: readonly (string | object)[] | Readonly<Record<string, string | object>>
|
|
@@ -72,6 +72,41 @@ declare type ResolveDefinition<TModel> = TModel extends { getDefinition: () => i
|
|
|
72
72
|
never;
|
|
73
73
|
/** Extract user-defined attribute keys from a model definition */
|
|
74
74
|
declare type DefinitionAttributeKeys<TDef extends InferableModelDefinition> = keyof TDef['attributes'] & string;
|
|
75
|
+
/** The model's primary-key column name, defaulting to `id`. */
|
|
76
|
+
declare type PrimaryKeyOf<TDef> = TDef extends { primaryKey: infer PK extends string } ? PK : 'id';
|
|
77
|
+
/**
|
|
78
|
+
* A single `belongsTo` entry reduced to the FK column it puts on this table.
|
|
79
|
+
* Mirrors `normalizeRelationEntry` in relation-utils.ts and `BelongsToFkOf` in
|
|
80
|
+
* orm.ts: an explicit `foreignKey` wins, otherwise the name is derived from
|
|
81
|
+
* the model name.
|
|
82
|
+
*/
|
|
83
|
+
declare type BelongsToFkOf<E> = E extends string
|
|
84
|
+
? `${SnakeCase<Uncapitalize<E>>}_id`
|
|
85
|
+
: E extends { foreignKey: infer F extends string }
|
|
86
|
+
? F
|
|
87
|
+
: E extends { model: infer M extends string }
|
|
88
|
+
? `${SnakeCase<Uncapitalize<M>>}_id`
|
|
89
|
+
: never;
|
|
90
|
+
/**
|
|
91
|
+
* The foreign-key columns a `belongsTo` puts on THIS model's table — they are
|
|
92
|
+
* emitted by the migration generator, so they are as real as any declared
|
|
93
|
+
* attribute. The array case MUST be checked first: a tuple also structurally
|
|
94
|
+
* matches `Record`, and the record branch would otherwise read its numeric
|
|
95
|
+
* indices as entries.
|
|
96
|
+
*/
|
|
97
|
+
declare type BelongsToKeys<TDef> = TDef extends { belongsTo: infer R }
|
|
98
|
+
? R extends readonly (infer E)[]
|
|
99
|
+
? BelongsToFkOf<E>
|
|
100
|
+
: R extends Readonly<Record<string, infer W>>
|
|
101
|
+
? BelongsToFkOf<W>
|
|
102
|
+
: never
|
|
103
|
+
: never;
|
|
104
|
+
/** camelCase -> snake_case, matching the column names migrations emit. */
|
|
105
|
+
declare type SnakeCase<S extends string> = S extends `${infer C}${infer Rest}`
|
|
106
|
+
? C extends Lowercase<C>
|
|
107
|
+
? `${C}${SnakeCase<Rest>}`
|
|
108
|
+
: `_${Lowercase<C>}${SnakeCase<Rest>}`
|
|
109
|
+
: S;
|
|
75
110
|
// ============================================================================
|
|
76
111
|
// Single attribute type inference
|
|
77
112
|
// ============================================================================
|
|
@@ -93,14 +128,23 @@ export type InferAttributes<TModel> = ResolveDefinition<TModel> extends infer TD
|
|
|
93
128
|
[K in DefinitionAttributeKeys<TDef>]: TDef['attributes'][K] extends { nullable: true }
|
|
94
129
|
? InferSingleAttributeType<TDef['attributes'][K]> | null
|
|
95
130
|
: InferSingleAttributeType<TDef['attributes'][K]>
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
&
|
|
102
|
-
|
|
103
|
-
|
|
131
|
+
}
|
|
132
|
+
// A column the model spells out is the authority on its own type; the
|
|
133
|
+
// trait / FK default only fills the gap. Without the Omit, a model that
|
|
134
|
+
// declares `created_at: { type: 'date' }` alongside `useTimestamps`
|
|
135
|
+
// intersected the two into `Date & string` — an uninhabited type.
|
|
136
|
+
& Omit<
|
|
137
|
+
{ [K in PrimaryKeyOf<TDef>]: number }
|
|
138
|
+
& (TDef['traits'] extends { useUuid: true } ? { uuid: string } : {})
|
|
139
|
+
& (TDef['traits'] extends { useTimestamps: true } ? { created_at: string; updated_at: string | null } : {})
|
|
140
|
+
& (TDef['traits'] extends { timestampable: true | object } ? { created_at: string; updated_at: string | null } : {})
|
|
141
|
+
& (TDef['traits'] extends { useSoftDeletes: true } ? { deleted_at: string | null } : {})
|
|
142
|
+
& (TDef['traits'] extends { softDeletable: true | object } ? { deleted_at: string | null } : {})
|
|
143
|
+
& (TDef['traits'] extends { useAuth: true | object } ? { two_factor_secret: string | null; public_key: string | null } : {})
|
|
144
|
+
& (TDef['traits'] extends { billable: true | object } ? { stripe_id: string | null } : {})
|
|
145
|
+
& { [K in BelongsToKeys<TDef>]: number },
|
|
146
|
+
DefinitionAttributeKeys<TDef>
|
|
147
|
+
>
|
|
104
148
|
: never;
|
|
105
149
|
/**
|
|
106
150
|
* The full row type for a model, including an index signature for trait-added
|
|
@@ -144,6 +188,11 @@ export type ModelCreateDataLoose<TModel> = InferFillableAttributes<TModel> & { [
|
|
|
144
188
|
* Infer only the fillable fields from a model definition or wrapped model.
|
|
145
189
|
* This is the type accepted by `create()`, `update()`, and `fill()`.
|
|
146
190
|
*
|
|
191
|
+
* Mirrors `InferAttributes`: a column declared `nullable: true` admits `null`.
|
|
192
|
+
* Columns that are `nullable` or carry a `default` are also OPTIONAL — the
|
|
193
|
+
* database supplies a value when the caller omits one, so requiring them at
|
|
194
|
+
* the call site rejected perfectly valid inserts.
|
|
195
|
+
*
|
|
147
196
|
* @example
|
|
148
197
|
* ```ts
|
|
149
198
|
* type UserFillable = InferFillableAttributes<typeof UserModel>
|
|
@@ -151,11 +200,25 @@ export type ModelCreateDataLoose<TModel> = InferFillableAttributes<TModel> & { [
|
|
|
151
200
|
* ```
|
|
152
201
|
*/
|
|
153
202
|
export type InferFillableAttributes<TModel> = ResolveDefinition<TModel> extends infer TDef extends InferableModelDefinition
|
|
154
|
-
?
|
|
155
|
-
[K in DefinitionAttributeKeys<TDef> as TDef['attributes'][K] extends { fillable: true } ? K : never]:
|
|
156
|
-
InferSingleAttributeType<TDef['attributes'][K]>
|
|
157
|
-
}
|
|
203
|
+
? FillableRequired<TDef> & FillableOptional<TDef>
|
|
158
204
|
: never;
|
|
205
|
+
/** Fillable keys the caller MUST supply — no `nullable`, no `default`. */
|
|
206
|
+
declare type FillableRequired<TDef extends InferableModelDefinition> = {
|
|
207
|
+
[K in DefinitionAttributeKeys<TDef> as TDef['attributes'][K] extends { fillable: true }
|
|
208
|
+
? TDef['attributes'][K] extends { nullable: true } | { default: unknown } ? never : K
|
|
209
|
+
: never]:
|
|
210
|
+
InferFillableType<TDef['attributes'][K]>
|
|
211
|
+
}
|
|
212
|
+
/** Fillable keys the database can fill in — `nullable` or `default`. */
|
|
213
|
+
declare type FillableOptional<TDef extends InferableModelDefinition> = {
|
|
214
|
+
[K in DefinitionAttributeKeys<TDef> as TDef['attributes'][K] extends { fillable: true }
|
|
215
|
+
? TDef['attributes'][K] extends { nullable: true } | { default: unknown } ? K : never
|
|
216
|
+
: never]?:
|
|
217
|
+
InferFillableType<TDef['attributes'][K]>
|
|
218
|
+
}
|
|
219
|
+
declare type InferFillableType<TAttr> = TAttr extends { nullable: true }
|
|
220
|
+
? InferSingleAttributeType<TAttr> | null
|
|
221
|
+
: InferSingleAttributeType<TAttr>;
|
|
159
222
|
/**
|
|
160
223
|
* Infer the primary key type from a model definition or wrapped model.
|
|
161
224
|
* Returns the literal string type of the primary key column name.
|
|
@@ -183,7 +246,9 @@ export type InferTableName<TModel> = ResolveDefinition<TModel> extends infer TDe
|
|
|
183
246
|
: never;
|
|
184
247
|
/**
|
|
185
248
|
* Infer all valid relation names from a model definition or wrapped model.
|
|
186
|
-
*
|
|
249
|
+
* Covers every relation kind `RelationCardinality` knows about: belongsTo,
|
|
250
|
+
* hasMany, hasOne, belongsToMany, hasOneThrough, hasManyThrough, and the
|
|
251
|
+
* polymorphic morphOne / morphMany / morphToMany / morphedByMany.
|
|
187
252
|
*
|
|
188
253
|
* @example
|
|
189
254
|
* ```ts
|
|
@@ -198,6 +263,10 @@ export type InferRelationNames<TModel> = ResolveDefinition<TModel> extends infer
|
|
|
198
263
|
| InferBelongsToManyNames<TDef>
|
|
199
264
|
| InferHasOneThroughNames<TDef>
|
|
200
265
|
| InferHasManyThroughNames<TDef>
|
|
266
|
+
| InferMorphOneNames<TDef>
|
|
267
|
+
| InferMorphManyNames<TDef>
|
|
268
|
+
| InferMorphToManyNames<TDef>
|
|
269
|
+
| InferMorphedByManyNames<TDef>
|
|
201
270
|
: never;
|
|
202
271
|
/**
|
|
203
272
|
* Infer column names that have numeric types from a model definition or wrapped model.
|
|
@@ -223,10 +292,18 @@ export type InferNumericColumns<TModel> = ResolveDefinition<TModel> extends infe
|
|
|
223
292
|
* type UserCols = InferColumnNames<typeof UserModel>
|
|
224
293
|
* // 'name' | 'email' | 'age' | 'role' | 'id' | 'uuid' | 'created_at' | 'updated_at'
|
|
225
294
|
* ```
|
|
295
|
+
*
|
|
296
|
+
* Kept in parity with the ORM layer's `ColumnName`: the primary key honors a
|
|
297
|
+
* custom `primaryKey` (a custom-pk model exposes THAT column, not a phantom
|
|
298
|
+
* `id`), belongsTo-implied foreign keys are included because the migration
|
|
299
|
+
* generator emits them, and every declared attribute is also valid in its
|
|
300
|
+
* snake_case column form.
|
|
226
301
|
*/
|
|
227
302
|
export type InferColumnNames<TModel> = ResolveDefinition<TModel> extends infer TDef extends InferableModelDefinition
|
|
228
303
|
? DefinitionAttributeKeys<TDef>
|
|
229
|
-
|
|
|
304
|
+
| SnakeCase<DefinitionAttributeKeys<TDef>>
|
|
305
|
+
| PrimaryKeyOf<TDef>
|
|
306
|
+
| BelongsToKeys<TDef>
|
|
230
307
|
| (TDef['traits'] extends { useUuid: true } ? 'uuid' : never)
|
|
231
308
|
| (TDef['traits'] extends { useTimestamps: true } ? 'created_at' | 'updated_at' : never)
|
|
232
309
|
| (TDef['traits'] extends { timestampable: true | object } ? 'created_at' | 'updated_at' : never)
|
|
@@ -303,25 +380,35 @@ export type InferPivotColumns<TModel, R extends string> = ResolveDefinition<TMod
|
|
|
303
380
|
: Record<string, unknown>
|
|
304
381
|
: Record<string, unknown>;
|
|
305
382
|
/**
|
|
306
|
-
* Relation names of one relation declaration.
|
|
307
|
-
*
|
|
308
|
-
*
|
|
383
|
+
* Relation names of one relation declaration. A bare string (`morphOne:
|
|
384
|
+
* 'Image'`) lowercases the model name; array form lowercases the (unwrapped)
|
|
385
|
+
* model name; record form uses the keys.
|
|
386
|
+
*
|
|
387
|
+
* Order matters. The bare-string case must precede the record case (a string
|
|
388
|
+
* would otherwise fall through to `never`), and the array case MUST precede
|
|
389
|
+
* the record case: a tuple also structurally matches `Readonly<Record<...>>`
|
|
309
390
|
* and would otherwise leak its own keys ('length', indices, ...) into the
|
|
310
391
|
* relation-name union.
|
|
311
392
|
*/
|
|
312
|
-
declare type RelationKeyOf<V> = V extends
|
|
313
|
-
?
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
:
|
|
393
|
+
declare type RelationKeyOf<V> = V extends string
|
|
394
|
+
? Lowercase<V>
|
|
395
|
+
: V extends readonly (infer E)[]
|
|
396
|
+
? E extends string ? Lowercase<E>
|
|
397
|
+
: E extends { model: infer M extends string } ? Lowercase<M>
|
|
398
|
+
: never
|
|
399
|
+
: V extends Readonly<Record<infer K, unknown>>
|
|
400
|
+
? K & string
|
|
401
|
+
: never;
|
|
319
402
|
declare type InferBelongsToNames<TDef> = TDef extends { belongsTo: infer V } ? RelationKeyOf<V> : never;
|
|
320
403
|
declare type InferHasManyNames<TDef> = TDef extends { hasMany: infer V } ? RelationKeyOf<V> : never;
|
|
321
404
|
declare type InferHasOneNames<TDef> = TDef extends { hasOne: infer V } ? RelationKeyOf<V> : never;
|
|
322
405
|
declare type InferBelongsToManyNames<TDef> = TDef extends { belongsToMany: infer V } ? RelationKeyOf<V> : never;
|
|
323
406
|
declare type InferHasOneThroughNames<TDef> = TDef extends { hasOneThrough: infer V } ? RelationKeyOf<V> : never;
|
|
324
407
|
declare type InferHasManyThroughNames<TDef> = TDef extends { hasManyThrough: infer V } ? RelationKeyOf<V> : never;
|
|
408
|
+
declare type InferMorphOneNames<TDef> = TDef extends { morphOne: infer V } ? RelationKeyOf<V> : never;
|
|
409
|
+
declare type InferMorphManyNames<TDef> = TDef extends { morphMany: infer V } ? RelationKeyOf<V> : never;
|
|
410
|
+
declare type InferMorphToManyNames<TDef> = TDef extends { morphToMany: infer V } ? RelationKeyOf<V> : never;
|
|
411
|
+
declare type InferMorphedByManyNames<TDef> = TDef extends { morphedByMany: infer V } ? RelationKeyOf<V> : never;
|
|
325
412
|
/**
|
|
326
413
|
* Determine the cardinality of a relation on a model.
|
|
327
414
|
* hasMany / belongsToMany / hasManyThrough / morphMany / morphToMany /
|
package/dist/types.d.ts
CHANGED
|
@@ -90,7 +90,7 @@ export declare interface AliasingConfig {
|
|
|
90
90
|
*/
|
|
91
91
|
export declare interface RelationsConfig {
|
|
92
92
|
foreignKeyFormat: 'singularParent_id' | 'parentId'
|
|
93
|
-
singularizeStrategy?: 'stripTrailingS' | 'none'
|
|
93
|
+
singularizeStrategy?: 'stripTrailingS' | 'none' | 'inflect'
|
|
94
94
|
maxDepth?: number
|
|
95
95
|
maxEagerLoad?: number
|
|
96
96
|
detectCycles?: boolean
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bun-query-builder",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.60",
|
|
5
5
|
"description": "A simple yet performant query builder for TypeScript. Built with Bun.",
|
|
6
6
|
"author": "Chris Breuer <chris@stacksjs.org>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"@stacksjs/clapp": "^0.2.0",
|
|
81
81
|
"@stacksjs/ts-faker": "^0.1.8",
|
|
82
82
|
"@stacksjs/ts-validation": "^0.5.0",
|
|
83
|
-
"dynamodb-tooling": "^0.3.
|
|
83
|
+
"dynamodb-tooling": "^0.3.5"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"bunfig": "^0.15.6"
|