bun-query-builder 0.1.27 → 0.1.28

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 CHANGED
@@ -14728,17 +14728,15 @@ function createQueryBuilder(state) {
14728
14728
  addWhereText("WHERE", `${String(col)} IS ${onlyTrashed ? "NOT " : ""}NULL`);
14729
14729
  }
14730
14730
  }
14731
+ const cacheKey = useCache ? `${String(finalQuery)}\x00${JSON.stringify(whereParams)}` : "";
14731
14732
  if (useCache) {
14732
- const cacheKey = String(finalQuery);
14733
14733
  const cached = queryCache.get(cacheKey);
14734
14734
  if (cached)
14735
14735
  return cached;
14736
14736
  }
14737
14737
  const result = await runWithHooks(finalQuery, "select", { signal: abortSignal, timeoutMs });
14738
- if (useCache) {
14739
- const cacheKey = String(finalQuery);
14738
+ if (useCache)
14740
14739
  queryCache.set(cacheKey, result, cacheTtl);
14741
- }
14742
14740
  return hydratePivotRows(result);
14743
14741
  },
14744
14742
  async executeTakeFirst() {
@@ -23803,6 +23801,13 @@ function assertValidIdentifier(name, context) {
23803
23801
  if (!SAFE_SQL_IDENTIFIER.test(name))
23804
23802
  throw new TypeError(`[bun-query-builder] ${context}: identifier '${name}' contains characters outside [A-Za-z0-9_] \u2014 refusing to interpolate into SQL`);
23805
23803
  }
23804
+ function assertValidOrderByColumn(name, context) {
23805
+ if (typeof name !== "string" || name.length === 0)
23806
+ throw new TypeError(`[bun-query-builder] ${context}: identifier must be a non-empty string, got ${typeof name}`);
23807
+ const parts = name.split(".");
23808
+ if (parts.length > 2 || parts.some((p2) => p2.length === 0 || p2.length > 64 || !SAFE_SQL_IDENTIFIER.test(p2)))
23809
+ throw new TypeError(`[bun-query-builder] ${context}: invalid ORDER BY column '${name}' \u2014 expected 'column' or 'table.column' of [A-Za-z0-9_] \u2014 refusing to interpolate into SQL`);
23810
+ }
23806
23811
  function getModelFromRegistry(name) {
23807
23812
  if (!_getModel) {
23808
23813
  try {
@@ -24091,12 +24096,16 @@ class ModelInstance {
24091
24096
  for (const [key, value] of Object.entries(data)) {
24092
24097
  const attr = attrs[key];
24093
24098
  if (attr?.fillable && !attr?.guarded) {
24099
+ if (this._original === null)
24100
+ this._original = { ...this._attributes };
24094
24101
  this._attributes[key] = value;
24095
24102
  }
24096
24103
  }
24097
24104
  return this;
24098
24105
  }
24099
24106
  forceFill(data) {
24107
+ if (this._original === null)
24108
+ this._original = { ...this._attributes };
24100
24109
  Object.assign(this._attributes, data);
24101
24110
  return this;
24102
24111
  }
@@ -24492,7 +24501,7 @@ class BelongsToManyRelationBuilder {
24492
24501
  return this;
24493
24502
  }
24494
24503
  orderBy(column, direction = "asc") {
24495
- assertValidIdentifier(column, "orderBy(column)");
24504
+ assertValidOrderByColumn(column, "orderBy(column)");
24496
24505
  if (direction !== "asc" && direction !== "desc")
24497
24506
  throw new TypeError(`[bun-query-builder] orderBy(direction): expected 'asc' or 'desc', got '${direction}'`);
24498
24507
  this._orderBy.push(`${column} ${direction.toUpperCase()}`);
@@ -24833,7 +24842,7 @@ class ModelQueryBuilder {
24833
24842
  return this;
24834
24843
  }
24835
24844
  orderBy(column, direction = "asc") {
24836
- assertValidIdentifier(column, "orderBy(column)");
24845
+ assertValidOrderByColumn(column, "orderBy(column)");
24837
24846
  if (direction !== "asc" && direction !== "desc")
24838
24847
  throw new TypeError(`[bun-query-builder] orderBy(direction): expected 'asc' or 'desc', got '${direction}'`);
24839
24848
  this._orderBy.push({ column, direction });
@@ -29920,7 +29929,7 @@ function getPrefix() {
29920
29929
  }
29921
29930
  var prefix = getPrefix();
29922
29931
  // package.json
29923
- var version2 = "0.1.27";
29932
+ var version2 = "0.1.28";
29924
29933
 
29925
29934
  // bin/cli.ts
29926
29935
  init_actions();
package/dist/browser.d.ts CHANGED
@@ -201,9 +201,12 @@ declare type BrowserAttributeKeys<TDef extends BrowserModelDefinition> = keyof T
201
201
  declare type InferBrowserAttributeType<TAttr> = TAttr extends { type: infer T } ? InferType<T> :
202
202
  TAttr extends { factory: (faker: unknown) => infer R } ? R :
203
203
  unknown;
204
- // Build the full attributes type from definition
204
+ // Build the full attributes type from definition. Columns declared
205
+ // `nullable: true` admit null — mirrors InferAttributes in type-inference.ts.
205
206
  declare type InferBrowserModelAttributes<TDef extends BrowserModelDefinition> = {
206
- [K in BrowserAttributeKeys<TDef>]: InferBrowserAttributeType<TDef['attributes'][K]>
207
+ [K in BrowserAttributeKeys<TDef>]: TDef['attributes'][K] extends { nullable: true }
208
+ ? InferBrowserAttributeType<TDef['attributes'][K]> | null
209
+ : InferBrowserAttributeType<TDef['attributes'][K]>
207
210
  }
208
211
  // System fields added by traits
209
212
  declare type BrowserSystemFields<TDef extends BrowserModelDefinition> = { id: number } &
package/dist/client.d.ts CHANGED
@@ -413,22 +413,29 @@ declare type JoinColumn<DB extends DatabaseSchema<any>, TTables extends string>
413
413
  *
414
414
  * The relation names declared for a table, read from the type-level
415
415
  * `relations` map that `DatabaseSchema` carries. Falls back to `string`
416
- * for hand-written schema types that don't declare relation metadata, so
417
- * existing untyped schemas keep compiling.
416
+ * for hand-written schema types that don't declare relation metadata
417
+ * (inferred `R` is `unknown` when the property is absent), so existing
418
+ * untyped schemas keep compiling. A table that declares ZERO relations
419
+ * yields `never` — every relation name is rejected.
418
420
  */
419
421
  export type TableRelationName<DB extends DatabaseSchema<any>, TTable extends keyof DB & string> = DB[TTable] extends { relations?: infer R }
420
- ? [keyof NonNullable<R>] extends [never] ? string : keyof NonNullable<R> & string
422
+ ? unknown extends R ? string : keyof NonNullable<R> & string
421
423
  : string;
422
424
  /**
423
425
  * # `WithRelationArg<DB, TTable>`
424
426
  *
425
427
  * Argument accepted by `.with()`: a declared relation name, a dotted nested
426
428
  * path rooted at a declared relation (`'posts.comments'`), or a record
427
- * mapping relation names to constraint callbacks.
429
+ * mapping relation names to constraint callbacks. A table with zero declared
430
+ * relations accepts nothing (the bare `Partial<Record<never, ...>>` would be
431
+ * `{}`, which strings are assignable to — hence the explicit never guard).
428
432
  */
429
- export type WithRelationArg<DB extends DatabaseSchema<any>, TTable extends keyof DB & string> = | TableRelationName<DB, TTable>
430
- | `${TableRelationName<DB, TTable>}.${string}`
431
- | Partial<Record<TableRelationName<DB, TTable>, (qb: any) => any>>;
433
+ export type WithRelationArg<DB extends DatabaseSchema<any>, TTable extends keyof DB & string> = [TableRelationName<DB, TTable>] extends [never]
434
+ ? never
435
+ :
436
+ | TableRelationName<DB, TTable>
437
+ | `${TableRelationName<DB, TTable>}.${string}`
438
+ | Partial<Record<TableRelationName<DB, TTable>, (qb: any) => any>>;
432
439
  // Convert snake_case to PascalCase at the type level (e.g. created_at -> CreatedAt)
433
440
  declare type SnakeToPascal<S extends string> = S extends `${infer H}_${infer T}`
434
441
  ? `${Capitalize<H>}${SnakeToPascal<T>}`
package/dist/orm.d.ts CHANGED
@@ -196,12 +196,17 @@ declare type AttributeKeys<TDef extends ModelDefinition> = keyof TDef['attribute
196
196
  declare type InferAttributeType<TAttr> = TAttr extends { type: infer T } ? InferType<T> :
197
197
  TAttr extends { factory: (faker: Faker) => infer R } ? R :
198
198
  unknown;
199
- // Build the full attributes type from definition
199
+ // Build the full attributes type from definition. Columns declared
200
+ // `nullable: true` admit null — mirrors InferAttributes in type-inference.ts.
200
201
  declare type InferModelAttributes<TDef extends ModelDefinition> = {
201
- [K in AttributeKeys<TDef>]: InferAttributeType<TDef['attributes'][K]>
202
+ [K in AttributeKeys<TDef>]: TDef['attributes'][K] extends { nullable: true }
203
+ ? InferAttributeType<TDef['attributes'][K]> | null
204
+ : InferAttributeType<TDef['attributes'][K]>
202
205
  }
203
- // System fields added by traits
204
- declare type SystemFields<TDef extends ModelDefinition> = { id: number } &
206
+ // System fields added by traits. The primary-key column honors the model's
207
+ // declared `primaryKey` (default 'id') a custom-pk model exposes THAT
208
+ // column, not a phantom 'id'. Mirrors InferAttributes in type-inference.ts.
209
+ declare type SystemFields<TDef extends ModelDefinition> = { [K in TDef extends { primaryKey: infer PK extends string } ? PK : 'id']: number } &
205
210
  (TDef['traits'] extends { useUuid: true } ? { uuid: string } : {}) &
206
211
  (TDef['traits'] extends { useTimestamps: true } ? { created_at: string; updated_at: string | null } : {}) &
207
212
  (TDef['traits'] extends { timestampable: true | object } ? { created_at: string; updated_at: string | null } : {}) &
@@ -213,7 +218,7 @@ declare type SystemFields<TDef extends ModelDefinition> = { id: number } &
213
218
  declare type ModelAttributes<TDef extends ModelDefinition> = InferModelAttributes<TDef> & SystemFields<TDef>;
214
219
  // All valid column names
215
220
  declare type ColumnName<TDef extends ModelDefinition> = | AttributeKeys<TDef>
216
- | 'id'
221
+ | (TDef extends { primaryKey: infer PK extends string } ? PK : 'id')
217
222
  | (TDef['traits'] extends { useUuid: true } ? 'uuid' : never)
218
223
  | (TDef['traits'] extends { useTimestamps: true } ? 'created_at' | 'updated_at' : never)
219
224
  | (TDef['traits'] extends { timestampable: true | object } ? 'created_at' | 'updated_at' : never)
@@ -233,31 +238,26 @@ declare type FillableKeys<TDef extends ModelDefinition> = {
233
238
  declare type NumericColumns<TDef extends ModelDefinition> = {
234
239
  [K in AttributeKeys<TDef>]: TDef['attributes'][K] extends { type: 'number' } ? K : never
235
240
  }[AttributeKeys<TDef>];
236
- // Infer relation names from model definition (supports both array and object syntax)
237
- declare type InferBelongsToNames<TDef> = (TDef extends { belongsTo: readonly (infer R)[] }
238
- ? R extends string ? Lowercase<R> : never : never)
239
- | (TDef extends { belongsTo: Readonly<Record<infer K, unknown>> }
240
- ? K extends string ? K : never : never);
241
- declare type InferHasManyNames<TDef> = (TDef extends { hasMany: readonly (infer R)[] }
242
- ? R extends string ? Lowercase<R> : never : never)
243
- | (TDef extends { hasMany: Readonly<Record<infer K, unknown>> }
244
- ? K extends string ? K : never : never);
245
- declare type InferHasOneNames<TDef> = (TDef extends { hasOne: readonly (infer R)[] }
246
- ? R extends string ? Lowercase<R> : never : never)
247
- | (TDef extends { hasOne: Readonly<Record<infer K, unknown>> }
248
- ? K extends string ? K : never : never);
249
- declare type InferBelongsToManyNames<TDef> = (TDef extends { belongsToMany: readonly (infer R)[] }
250
- ? R extends string ? Lowercase<R> : R extends { model: infer M extends string } ? Lowercase<M> : never : never)
251
- | (TDef extends { belongsToMany: Readonly<Record<infer K, unknown>> }
252
- ? K extends string ? K : never : never);
253
- declare type InferHasOneThroughNames<TDef> = (TDef extends { hasOneThrough: readonly (infer R)[] }
254
- ? R extends string ? Lowercase<R> : R extends { model: infer M extends string } ? Lowercase<M> : never : never)
255
- | (TDef extends { hasOneThrough: Readonly<Record<infer K, unknown>> }
256
- ? K extends string ? K : never : never);
257
- declare type InferHasManyThroughNames<TDef> = (TDef extends { hasManyThrough: readonly (infer R)[] }
258
- ? R extends string ? Lowercase<R> : R extends { model: infer M extends string } ? Lowercase<M> : never : never)
259
- | (TDef extends { hasManyThrough: Readonly<Record<infer K, unknown>> }
260
- ? K extends string ? K : never : never);
241
+ /**
242
+ * Relation names of one relation declaration. Array form lowercases the
243
+ * (unwrapped) model name; record form uses the keys. The array case MUST be
244
+ * checked first: a tuple also structurally matches `Readonly<Record<...>>`
245
+ * and would otherwise leak its own keys ('length', indices, ...) into the
246
+ * relation-name union.
247
+ */
248
+ declare type RelationKeyOf<V> = V extends readonly (infer E)[]
249
+ ? E extends string ? Lowercase<E>
250
+ : E extends { model: infer M extends string } ? Lowercase<M>
251
+ : never
252
+ : V extends Readonly<Record<infer K, unknown>>
253
+ ? K & string
254
+ : never;
255
+ declare type InferBelongsToNames<TDef> = TDef extends { belongsTo: infer V } ? RelationKeyOf<V> : never;
256
+ declare type InferHasManyNames<TDef> = TDef extends { hasMany: infer V } ? RelationKeyOf<V> : never;
257
+ declare type InferHasOneNames<TDef> = TDef extends { hasOne: infer V } ? RelationKeyOf<V> : never;
258
+ declare type InferBelongsToManyNames<TDef> = TDef extends { belongsToMany: infer V } ? RelationKeyOf<V> : never;
259
+ declare type InferHasOneThroughNames<TDef> = TDef extends { hasOneThrough: infer V } ? RelationKeyOf<V> : never;
260
+ declare type InferHasManyThroughNames<TDef> = TDef extends { hasManyThrough: infer V } ? RelationKeyOf<V> : never;
261
261
  export type InferRelationNames<TDef> = | InferBelongsToNames<TDef>
262
262
  | InferHasManyNames<TDef>
263
263
  | InferHasOneNames<TDef>
package/dist/src/index.js CHANGED
@@ -14728,17 +14728,15 @@ function createQueryBuilder(state) {
14728
14728
  addWhereText("WHERE", `${String(col)} IS ${onlyTrashed ? "NOT " : ""}NULL`);
14729
14729
  }
14730
14730
  }
14731
+ const cacheKey = useCache ? `${String(finalQuery)}\x00${JSON.stringify(whereParams)}` : "";
14731
14732
  if (useCache) {
14732
- const cacheKey = String(finalQuery);
14733
14733
  const cached = queryCache.get(cacheKey);
14734
14734
  if (cached)
14735
14735
  return cached;
14736
14736
  }
14737
14737
  const result = await runWithHooks(finalQuery, "select", { signal: abortSignal, timeoutMs });
14738
- if (useCache) {
14739
- const cacheKey = String(finalQuery);
14738
+ if (useCache)
14740
14739
  queryCache.set(cacheKey, result, cacheTtl);
14741
- }
14742
14740
  return hydratePivotRows(result);
14743
14741
  },
14744
14742
  async executeTakeFirst() {
@@ -23803,6 +23801,13 @@ function assertValidIdentifier(name, context) {
23803
23801
  if (!SAFE_SQL_IDENTIFIER.test(name))
23804
23802
  throw new TypeError(`[bun-query-builder] ${context}: identifier '${name}' contains characters outside [A-Za-z0-9_] \u2014 refusing to interpolate into SQL`);
23805
23803
  }
23804
+ function assertValidOrderByColumn(name, context) {
23805
+ if (typeof name !== "string" || name.length === 0)
23806
+ throw new TypeError(`[bun-query-builder] ${context}: identifier must be a non-empty string, got ${typeof name}`);
23807
+ const parts = name.split(".");
23808
+ if (parts.length > 2 || parts.some((p2) => p2.length === 0 || p2.length > 64 || !SAFE_SQL_IDENTIFIER.test(p2)))
23809
+ throw new TypeError(`[bun-query-builder] ${context}: invalid ORDER BY column '${name}' \u2014 expected 'column' or 'table.column' of [A-Za-z0-9_] \u2014 refusing to interpolate into SQL`);
23810
+ }
23806
23811
  function getModelFromRegistry(name) {
23807
23812
  if (!_getModel) {
23808
23813
  try {
@@ -24091,12 +24096,16 @@ class ModelInstance {
24091
24096
  for (const [key, value] of Object.entries(data)) {
24092
24097
  const attr = attrs[key];
24093
24098
  if (attr?.fillable && !attr?.guarded) {
24099
+ if (this._original === null)
24100
+ this._original = { ...this._attributes };
24094
24101
  this._attributes[key] = value;
24095
24102
  }
24096
24103
  }
24097
24104
  return this;
24098
24105
  }
24099
24106
  forceFill(data) {
24107
+ if (this._original === null)
24108
+ this._original = { ...this._attributes };
24100
24109
  Object.assign(this._attributes, data);
24101
24110
  return this;
24102
24111
  }
@@ -24492,7 +24501,7 @@ class BelongsToManyRelationBuilder {
24492
24501
  return this;
24493
24502
  }
24494
24503
  orderBy(column, direction = "asc") {
24495
- assertValidIdentifier(column, "orderBy(column)");
24504
+ assertValidOrderByColumn(column, "orderBy(column)");
24496
24505
  if (direction !== "asc" && direction !== "desc")
24497
24506
  throw new TypeError(`[bun-query-builder] orderBy(direction): expected 'asc' or 'desc', got '${direction}'`);
24498
24507
  this._orderBy.push(`${column} ${direction.toUpperCase()}`);
@@ -24833,7 +24842,7 @@ class ModelQueryBuilder {
24833
24842
  return this;
24834
24843
  }
24835
24844
  orderBy(column, direction = "asc") {
24836
- assertValidIdentifier(column, "orderBy(column)");
24845
+ assertValidOrderByColumn(column, "orderBy(column)");
24837
24846
  if (direction !== "asc" && direction !== "desc")
24838
24847
  throw new TypeError(`[bun-query-builder] orderBy(direction): expected 'asc' or 'desc', got '${direction}'`);
24839
24848
  this._orderBy.push({ column, direction });
@@ -302,112 +302,42 @@ export type InferPivotColumns<TModel, R extends string> = ResolveDefinition<TMod
302
302
  : Record<string, unknown>
303
303
  : Record<string, unknown>
304
304
  : Record<string, unknown>;
305
- // ============================================================================
306
- // Internal relation name inference helpers
307
- // ============================================================================
308
- declare type InferBelongsToNames<TDef> = (TDef extends { belongsTo: readonly (infer R)[] }
309
- ? R extends string ? Lowercase<R> : never : never)
310
- | (TDef extends { belongsTo: Readonly<Record<infer K, unknown>> }
311
- ? K extends string ? K : never : never);
312
- declare type InferHasManyNames<TDef> = (TDef extends { hasMany: readonly (infer R)[] }
313
- ? R extends string ? Lowercase<R> : never : never)
314
- | (TDef extends { hasMany: Readonly<Record<infer K, unknown>> }
315
- ? K extends string ? K : never : never);
316
- declare type InferHasOneNames<TDef> = (TDef extends { hasOne: readonly (infer R)[] }
317
- ? R extends string ? Lowercase<R> : never : never)
318
- | (TDef extends { hasOne: Readonly<Record<infer K, unknown>> }
319
- ? K extends string ? K : never : never);
320
- declare type InferBelongsToManyNames<TDef> = (TDef extends { belongsToMany: readonly (infer R)[] }
321
- ? R extends string ? Lowercase<R> : R extends { model: infer M extends string } ? Lowercase<M> : never : never)
322
- | (TDef extends { belongsToMany: Readonly<Record<infer K, unknown>> }
323
- ? K extends string ? K : never : never);
324
- declare type InferHasOneThroughNames<TDef> = (TDef extends { hasOneThrough: readonly (infer R)[] }
325
- ? R extends string ? Lowercase<R> : R extends { model: infer M extends string } ? Lowercase<M> : never : never)
326
- | (TDef extends { hasOneThrough: Readonly<Record<infer K, unknown>> }
327
- ? K extends string ? K : never : never);
328
- declare type InferHasManyThroughNames<TDef> = (TDef extends { hasManyThrough: readonly (infer R)[] }
329
- ? R extends string ? Lowercase<R> : R extends { model: infer M extends string } ? Lowercase<M> : never : never)
330
- | (TDef extends { hasManyThrough: Readonly<Record<infer K, unknown>> }
331
- ? K extends string ? K : never : never);
305
+ /**
306
+ * Relation names of one relation declaration. Array form lowercases the
307
+ * (unwrapped) model name; record form uses the keys. The array case MUST be
308
+ * checked first: a tuple also structurally matches `Readonly<Record<...>>`
309
+ * and would otherwise leak its own keys ('length', indices, ...) into the
310
+ * relation-name union.
311
+ */
312
+ declare type RelationKeyOf<V> = V extends readonly (infer E)[]
313
+ ? E extends string ? Lowercase<E>
314
+ : E extends { model: infer M extends string } ? Lowercase<M>
315
+ : never
316
+ : V extends Readonly<Record<infer K, unknown>>
317
+ ? K & string
318
+ : never;
319
+ declare type InferBelongsToNames<TDef> = TDef extends { belongsTo: infer V } ? RelationKeyOf<V> : never;
320
+ declare type InferHasManyNames<TDef> = TDef extends { hasMany: infer V } ? RelationKeyOf<V> : never;
321
+ declare type InferHasOneNames<TDef> = TDef extends { hasOne: infer V } ? RelationKeyOf<V> : never;
322
+ declare type InferBelongsToManyNames<TDef> = TDef extends { belongsToMany: infer V } ? RelationKeyOf<V> : never;
323
+ declare type InferHasOneThroughNames<TDef> = TDef extends { hasOneThrough: infer V } ? RelationKeyOf<V> : never;
324
+ declare type InferHasManyThroughNames<TDef> = TDef extends { hasManyThrough: infer V } ? RelationKeyOf<V> : never;
332
325
  /**
333
326
  * Determine the cardinality of a relation on a model.
334
- * hasMany 'many', hasOne/belongsTo 'one'
327
+ * hasMany / belongsToMany / hasManyThrough / morphMany / morphToMany /
328
+ * morphedByMany → 'many'; hasOne / belongsTo / hasOneThrough / morphOne →
329
+ * 'one'. Both array and record declaration forms are supported via
330
+ * `RelationKeyOf` (array-first, so tuple keys never leak in).
335
331
  */
336
332
  export type RelationCardinality<TModel, R extends string> = ResolveDefinition<TModel> extends infer TDef
337
- ? // hasMany array syntax
338
- (TDef extends { hasMany: readonly (infer M)[] }
339
- ? Lowercase<M & string> extends R ? 'many' : never
340
- : never)
341
- // hasMany object syntax
342
- | (TDef extends { hasMany: Readonly<Record<infer K, unknown>> }
343
- ? K extends string ? K extends R ? 'many' : never : never
344
- : never)
345
- // hasOne array syntax
346
- | (TDef extends { hasOne: readonly (infer M)[] }
347
- ? Lowercase<M & string> extends R ? 'one' : never
348
- : never)
349
- // hasOne object syntax
350
- | (TDef extends { hasOne: Readonly<Record<infer K, unknown>> }
351
- ? K extends string ? K extends R ? 'one' : never : never
352
- : never)
353
- // belongsTo array syntax
354
- | (TDef extends { belongsTo: readonly (infer M)[] }
355
- ? Lowercase<M & string> extends R ? 'one' : never
356
- : never)
357
- // belongsTo object syntax
358
- | (TDef extends { belongsTo: Readonly<Record<infer K, unknown>> }
359
- ? K extends string ? K extends R ? 'one' : never : never
360
- : never)
361
- // belongsToMany array syntax
362
- | (TDef extends { belongsToMany: readonly (infer M)[] }
363
- ? M extends string
364
- ? Lowercase<M> extends R ? 'many' : never
365
- : M extends { model: infer N extends string }
366
- ? Lowercase<N> extends R ? 'many' : never
367
- : never
368
- : never)
369
- // belongsToMany object syntax
370
- | (TDef extends { belongsToMany: Readonly<Record<infer K, unknown>> }
371
- ? K extends string ? K extends R ? 'many' : never : never
372
- : never)
373
- // hasOneThrough array syntax ({ model } entries)
374
- | (TDef extends { hasOneThrough: readonly (infer M)[] }
375
- ? M extends string
376
- ? Lowercase<M> extends R ? 'one' : never
377
- : M extends { model: infer N extends string }
378
- ? Lowercase<N> extends R ? 'one' : never
379
- : never
380
- : never)
381
- // hasOneThrough object syntax
382
- | (TDef extends { hasOneThrough: Readonly<Record<infer K, unknown>> }
383
- ? K extends string ? K extends R ? 'one' : never : never
384
- : never)
385
- // hasManyThrough array syntax ({ model } entries)
386
- | (TDef extends { hasManyThrough: readonly (infer M)[] }
387
- ? M extends string
388
- ? Lowercase<M> extends R ? 'many' : never
389
- : M extends { model: infer N extends string }
390
- ? Lowercase<N> extends R ? 'many' : never
391
- : never
392
- : never)
393
- // hasManyThrough object syntax
394
- | (TDef extends { hasManyThrough: Readonly<Record<infer K, unknown>> }
395
- ? K extends string ? K extends R ? 'many' : never : never
396
- : never)
397
- // morphOne object syntax
398
- | (TDef extends { morphOne: Readonly<Record<infer K, unknown>> }
399
- ? K extends string ? K extends R ? 'one' : never : never
400
- : never)
401
- // morphMany object syntax
402
- | (TDef extends { morphMany: Readonly<Record<infer K, unknown>> }
403
- ? K extends string ? K extends R ? 'many' : never : never
404
- : never)
405
- // morphToMany object syntax
406
- | (TDef extends { morphToMany: Readonly<Record<infer K, unknown>> }
407
- ? K extends string ? K extends R ? 'many' : never : never
408
- : never)
409
- // morphedByMany object syntax
410
- | (TDef extends { morphedByMany: Readonly<Record<infer K, unknown>> }
411
- ? K extends string ? K extends R ? 'many' : never : never
412
- : never)
333
+ ? (TDef extends { hasMany: infer V } ? (R extends RelationKeyOf<V> ? 'many' : never) : never)
334
+ | (TDef extends { hasOne: infer V } ? (R extends RelationKeyOf<V> ? 'one' : never) : never)
335
+ | (TDef extends { belongsTo: infer V } ? (R extends RelationKeyOf<V> ? 'one' : never) : never)
336
+ | (TDef extends { belongsToMany: infer V } ? (R extends RelationKeyOf<V> ? 'many' : never) : never)
337
+ | (TDef extends { hasOneThrough: infer V } ? (R extends RelationKeyOf<V> ? 'one' : never) : never)
338
+ | (TDef extends { hasManyThrough: infer V } ? (R extends RelationKeyOf<V> ? 'many' : never) : never)
339
+ | (TDef extends { morphOne: infer V } ? (R extends RelationKeyOf<V> ? 'one' : never) : never)
340
+ | (TDef extends { morphMany: infer V } ? (R extends RelationKeyOf<V> ? 'many' : never) : never)
341
+ | (TDef extends { morphToMany: infer V } ? (R extends RelationKeyOf<V> ? 'many' : never) : never)
342
+ | (TDef extends { morphedByMany: infer V } ? (R extends RelationKeyOf<V> ? 'many' : never) : never)
413
343
  : never;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bun-query-builder",
3
3
  "type": "module",
4
- "version": "0.1.27",
4
+ "version": "0.1.28",
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",