@hono-crud/drizzle 0.1.4 → 0.1.6

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/index.d.ts CHANGED
@@ -1,50 +1,84 @@
1
- import { Table, SQL, Column } from 'drizzle-orm';
2
1
  import { MetaInput, IncludeOptions, FilterCondition, RelationConfig, CreateEndpoint, ModelObject, ReadEndpoint, UpdateEndpoint, NestedUpdateInput, NestedWriteResult, DeleteEndpoint, ListEndpoint, ListFilters, PaginatedResult, RestoreEndpoint, BatchCreateEndpoint, BatchDeleteEndpoint, BatchRestoreEndpoint, BatchUpdateEndpoint, BatchUpdateItem, AggregateEndpoint, AggregateOptions, AggregateResult, BatchUpsertEndpoint, CloneEndpoint, UpsertEndpoint, SearchEndpoint, SearchOptions, SearchResult, ExportEndpoint, ImportEndpoint, VersionCompareEndpoint, VersionHistoryEndpoint, VersionReadEndpoint, VersionRollbackEndpoint, AdapterBundle } from 'hono-crud/internal';
3
2
  import { Env } from 'hono';
4
3
  import { z } from 'zod';
5
4
 
6
5
  /**
7
- * Internal query builder interface used for type-safe method calls.
8
- * All Drizzle query builders satisfy this interface at runtime.
9
- */
10
- interface QueryBuilder extends PromiseLike<unknown[]> {
11
- where(condition: unknown): QueryBuilder;
12
- limit(n: number): QueryBuilder;
13
- offset(n: number): QueryBuilder;
14
- orderBy(...columns: unknown[]): QueryBuilder;
15
- set(data: Record<string, unknown>): QueryBuilder;
16
- values(data: Record<string, unknown> | Record<string, unknown>[]): QueryBuilder;
17
- returning(): QueryBuilder;
6
+ * Local stand-in for a drizzle-orm `Table`. Real drizzle tables (and any
7
+ * duck-typed table carrying `_.name`/`_.columns`) satisfy this shape. Shared
8
+ * with `schema-utils.ts`.
9
+ */
10
+ interface DrizzleTable {
11
+ _: {
12
+ name: string;
13
+ columns: Record<string, unknown>;
14
+ };
15
+ }
16
+ /**
17
+ * Local stand-in for a drizzle-orm `Column`.
18
+ *
19
+ * Declares `getSQL()` so a column value is structurally a drizzle `SQLWrapper`,
20
+ * which every operator (`eq`, `isNull`, `inArray`, `asc`, ...) accepts — so
21
+ * columns pass straight into operators with no cast at the call site. The
22
+ * `never` return keeps it opaque.
23
+ */
24
+ interface DrizzleColumn {
25
+ getSQL(): never;
26
+ }
27
+ /**
28
+ * Local stand-in for a drizzle-orm `SQL` expression. A supertype of the real
29
+ * `SQL`, so operator results widen into it for free; the {@link and}/{@link or}
30
+ * helpers below let condition arrays round-trip without naming a drizzle type.
31
+ */
32
+ interface DrizzleSql {
33
+ getSQL(): unknown;
34
+ }
35
+ /**
36
+ * Internal query builder interface used for type-safe method calls, generic
37
+ * over the resolved row type `Row`. All Drizzle query builders satisfy this
38
+ * interface at runtime; awaiting one resolves to `Row[]`.
39
+ */
40
+ interface QueryBuilder<Row = unknown> extends PromiseLike<Row[]> {
41
+ where(condition: unknown): QueryBuilder<Row>;
42
+ limit(n: number): QueryBuilder<Row>;
43
+ offset(n: number): QueryBuilder<Row>;
44
+ orderBy(...columns: unknown[]): QueryBuilder<Row>;
45
+ set(data: Record<string, unknown>): QueryBuilder<Row>;
46
+ values(data: Record<string, unknown> | Record<string, unknown>[]): QueryBuilder<Row>;
47
+ returning(): QueryBuilder<Row>;
18
48
  onConflictDoUpdate(config: {
19
49
  target: unknown[];
20
50
  set: Record<string, unknown>;
21
51
  where?: unknown;
22
- }): QueryBuilder;
52
+ }): QueryBuilder<Row>;
23
53
  onConflictDoNothing(config?: {
24
54
  target?: unknown[];
25
- }): QueryBuilder;
55
+ }): QueryBuilder<Row>;
26
56
  onDuplicateKeyUpdate(config: {
27
57
  set: Record<string, unknown>;
28
- }): QueryBuilder;
58
+ }): QueryBuilder<Row>;
29
59
  }
30
60
  /**
31
- * Internal database interface used for type-safe method calls.
32
- * All Drizzle databases (PostgreSQL, MySQL, SQLite) satisfy this interface at runtime.
61
+ * Internal database interface used for type-safe method calls, generic over the
62
+ * resolved row type `Row`. All Drizzle databases (PostgreSQL, MySQL, SQLite)
63
+ * satisfy this interface at runtime.
33
64
  */
34
- interface Database {
65
+ interface Database<Row = unknown> {
35
66
  select(fields?: Record<string, unknown>): {
36
- from(table: Table): QueryBuilder;
67
+ from(table: DrizzleTable): QueryBuilder<Row>;
37
68
  };
38
- insert(table: Table): QueryBuilder;
39
- update(table: Table): QueryBuilder;
40
- delete(table: Table): QueryBuilder;
41
- transaction<T>(fn: (tx: Database) => Promise<T>): Promise<T>;
69
+ insert(table: DrizzleTable): QueryBuilder<Row>;
70
+ update(table: DrizzleTable): QueryBuilder<Row>;
71
+ delete(table: DrizzleTable): QueryBuilder<Row>;
72
+ transaction<T>(fn: (tx: Database<Row>) => Promise<T>): Promise<T>;
42
73
  }
43
74
  /**
44
- * Casts a database to the internal Database interface for method calls.
45
- * This is safe because all Drizzle databases have these methods at runtime.
75
+ * Casts a database handle to the internal {@link Database} interface for method
76
+ * calls, parametrized over the row type `Row` that queries resolve to. This is
77
+ * the single sanctioned boundary `as`: all Drizzle databases expose these
78
+ * methods at runtime, and the row type derives from the consumer's Zod schema
79
+ * (`ModelObject<M['model']>`), never from a drizzle-orm type.
46
80
  */
47
- declare function cast<T>(instance: T): Database;
81
+ declare function cast<Row = unknown>(instance: unknown): Database<Row>;
48
82
  /**
49
83
  * Base constraint for Drizzle database types.
50
84
  * Your database type must have select, insert, update, delete, and transaction methods.
@@ -69,14 +103,6 @@ interface DrizzleDatabaseConstraint {
69
103
  delete: unknown;
70
104
  transaction: unknown;
71
105
  }
72
- /**
73
- * @deprecated Pass your database type as a generic parameter instead
74
- */
75
- type DrizzleDatabase = DrizzleDatabaseConstraint;
76
- /**
77
- * @deprecated Pass your database type as a generic parameter instead
78
- */
79
- type DrizzleDB = DrizzleDatabaseConstraint;
80
106
  /**
81
107
  * Drizzle SQL dialect identifier used to branch dialect-specific behavior
82
108
  * (e.g. native upsert syntax: `ON CONFLICT DO UPDATE` for sqlite/pg vs
@@ -86,7 +112,8 @@ type DrizzleDB = DrizzleDatabaseConstraint;
86
112
  * pre-existing portable behavior). Set explicitly when targeting PostgreSQL
87
113
  * or MySQL to enable the appropriate code paths.
88
114
  */
89
- type DrizzleDialect = 'sqlite' | 'pg' | 'mysql';
115
+ declare const DRIZZLE_DIALECTS: readonly ["sqlite", "pg", "mysql"];
116
+ type DrizzleDialect = (typeof DRIZZLE_DIALECTS)[number];
90
117
  /**
91
118
  * Type helper for defining Hono Env with database in Variables.
92
119
  * Use this when injecting the database via middleware.
@@ -119,7 +146,7 @@ type DrizzleEnv<DB = DrizzleDatabaseConstraint> = {
119
146
  /**
120
147
  * Gets the Drizzle table from the model.
121
148
  */
122
- declare function getTable<M extends MetaInput>(meta: M): Table;
149
+ declare function getTable<M extends MetaInput>(meta: M): DrizzleTable;
123
150
  /**
124
151
  * Gets a column from the table with proper type safety.
125
152
  * Uses drizzle-orm's getTableColumns for type-safe column access.
@@ -129,25 +156,40 @@ declare function getTable<M extends MetaInput>(meta: M): Table;
129
156
  * @returns The column
130
157
  * @throws Error if the column is not found in the table
131
158
  */
132
- declare function getColumn(table: Table, field: string): Column;
159
+ declare function getColumn(table: DrizzleTable, field: string): DrizzleColumn;
133
160
  /**
134
161
  * Loads related records for a given item using Drizzle queries.
135
162
  */
136
- declare function loadDrizzleRelation<T extends Record<string, unknown>>(db: DrizzleDatabase, item: T, relationName: string, relationConfig: RelationConfig<Table>): Promise<T>;
163
+ declare function loadDrizzleRelation<T extends Record<string, unknown>>(db: DrizzleDatabaseConstraint, item: T, relationName: string, relationConfig: RelationConfig<DrizzleTable>): Promise<T>;
137
164
  /**
138
165
  * Loads all requested relations for an item.
139
166
  * Note: For multiple items, use `batchLoadDrizzleRelations` to avoid N+1 queries.
140
167
  */
141
- declare function loadDrizzleRelations<T extends Record<string, unknown>, M extends MetaInput>(db: DrizzleDatabase, item: T, meta: M, includeOptions?: IncludeOptions): Promise<T>;
168
+ declare function loadDrizzleRelations<T extends Record<string, unknown>, M extends MetaInput>(db: DrizzleDatabaseConstraint, item: T, meta: M, includeOptions?: IncludeOptions): Promise<T>;
142
169
  /**
143
170
  * Batch loads relations for multiple items to avoid N+1 queries.
144
171
  * Instead of N queries per relation, this uses 1 query per relation using inArray().
145
172
  */
146
- declare function batchLoadDrizzleRelations<T extends Record<string, unknown>, M extends MetaInput>(db: DrizzleDatabase, items: T[], meta: M, includeOptions?: IncludeOptions): Promise<T[]>;
173
+ declare function batchLoadDrizzleRelations<T extends Record<string, unknown>, M extends MetaInput>(db: DrizzleDatabaseConstraint, items: T[], meta: M, includeOptions?: IncludeOptions): Promise<T[]>;
147
174
  /**
148
175
  * Builds a where condition from filter conditions.
149
176
  */
150
- declare function buildWhereCondition(table: Table, filter: FilterCondition): SQL | undefined;
177
+ declare function buildWhereCondition(table: DrizzleTable, filter: FilterCondition): DrizzleSql | undefined;
178
+ /**
179
+ * Shape of a `SELECT count(*) AS count` row produced by the Drizzle query
180
+ * builder. The builder returns rows as `unknown`, so this names the one row
181
+ * shape the count queries rely on.
182
+ */
183
+ interface CountRow {
184
+ count: number;
185
+ }
186
+ /**
187
+ * Read the scalar total from a `SELECT count(*) AS count` result, coercing the
188
+ * driver's value to a number and defaulting to `0` when the result is empty.
189
+ * Centralizes the `as CountRow[]` cast that the count/exists/pagination paths
190
+ * would otherwise repeat at every call site.
191
+ */
192
+ declare function readCount(result: unknown): number;
151
193
 
152
194
  /**
153
195
  * Drizzle Create endpoint.
@@ -179,12 +221,12 @@ declare function buildWhereCondition(table: Table, filter: FilterCondition): SQL
179
221
  * }
180
222
  * ```
181
223
  */
182
- declare abstract class DrizzleCreateEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends CreateEndpoint<E, M> {
224
+ declare abstract class DrizzleCreateEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends CreateEndpoint<E, M> {
183
225
  /**
184
226
  * Drizzle database instance.
185
227
  * Can be undefined if using context-based injection via middleware.
186
228
  */
187
- db?: DrizzleDatabase;
229
+ db?: DB;
188
230
  /**
189
231
  * Whether to wrap create and nested operations in a transaction.
190
232
  * When true, the entire create operation (including nested writes) will be atomic.
@@ -192,19 +234,19 @@ declare abstract class DrizzleCreateEndpoint<E extends Env = Env, M extends Meta
192
234
  */
193
235
  protected useTransaction: boolean;
194
236
  /** Current transaction context (set during transaction execution) */
195
- protected _tx?: DrizzleDatabase;
237
+ protected _tx?: DrizzleDatabaseConstraint;
196
238
  /**
197
239
  * Gets the database instance to use. Checks in order:
198
240
  * 1. Transaction context (if in transaction)
199
241
  * 2. Direct property
200
242
  * 3. Context variables (if middleware injected)
201
243
  */
202
- protected getDb(): DrizzleDatabase;
203
- protected getTable(): Table;
244
+ protected getDb(): DB;
245
+ protected getTable(): DrizzleTable;
204
246
  /**
205
247
  * Gets a related table from the relation config.
206
248
  */
207
- protected getRelatedTable(relationConfig: RelationConfig): Table | undefined;
249
+ protected getRelatedTable(relationConfig: RelationConfig): DrizzleTable | undefined;
208
250
  create(data: ModelObject<M['model']>, tx?: unknown): Promise<ModelObject<M['model']>>;
209
251
  /**
210
252
  * Creates nested related records.
@@ -224,13 +266,13 @@ declare abstract class DrizzleCreateEndpoint<E extends Env = Env, M extends Meta
224
266
  *
225
267
  * Supports relation includes via `?include=relation1,relation2`.
226
268
  */
227
- declare abstract class DrizzleReadEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends ReadEndpoint<E, M> {
269
+ declare abstract class DrizzleReadEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends ReadEndpoint<E, M> {
228
270
  /** Drizzle database instance */
229
- db?: DrizzleDatabase;
271
+ db?: DB;
230
272
  /** Gets the database instance from property or context */
231
- protected getDb(): DrizzleDatabase;
232
- protected getTable(): Table;
233
- protected getColumn(field: string): Column;
273
+ protected getDb(): DB;
274
+ protected getTable(): DrizzleTable;
275
+ protected getColumn(field: string): DrizzleColumn;
234
276
  read(lookupValue: string, additionalFilters?: Record<string, string>, includeOptions?: IncludeOptions): Promise<ModelObject<M['model']> | null>;
235
277
  }
236
278
  /**
@@ -240,9 +282,9 @@ declare abstract class DrizzleReadEndpoint<E extends Env = Env, M extends MetaIn
240
282
  * Supports soft delete filtering when the model has `softDelete` configured.
241
283
  * Soft-deleted records cannot be updated.
242
284
  */
243
- declare abstract class DrizzleUpdateEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends UpdateEndpoint<E, M> {
285
+ declare abstract class DrizzleUpdateEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends UpdateEndpoint<E, M> {
244
286
  /** Drizzle database instance */
245
- db?: DrizzleDatabase;
287
+ db?: DB;
246
288
  /**
247
289
  * Whether to wrap update and nested operations in a transaction.
248
290
  * When true, the entire update operation (including nested writes) will be atomic.
@@ -250,15 +292,15 @@ declare abstract class DrizzleUpdateEndpoint<E extends Env = Env, M extends Meta
250
292
  */
251
293
  protected useTransaction: boolean;
252
294
  /** Current transaction context (set during transaction execution) */
253
- protected _tx?: DrizzleDatabase;
295
+ protected _tx?: DrizzleDatabaseConstraint;
254
296
  /** Gets the database instance from property, transaction, or context */
255
- protected getDb(): DrizzleDatabase;
256
- protected getTable(): Table;
257
- protected getColumn(field: string): Column;
297
+ protected getDb(): DB;
298
+ protected getTable(): DrizzleTable;
299
+ protected getColumn(field: string): DrizzleColumn;
258
300
  /**
259
301
  * Gets a related table from the relation config.
260
302
  */
261
- protected getRelatedTable(relationConfig: RelationConfig): Table | undefined;
303
+ protected getRelatedTable(relationConfig: RelationConfig): DrizzleTable | undefined;
262
304
  /**
263
305
  * Finds an existing record for audit logging.
264
306
  */
@@ -280,9 +322,9 @@ declare abstract class DrizzleUpdateEndpoint<E extends Env = Env, M extends Meta
280
322
  * Supports soft delete when the model has `softDelete` configured.
281
323
  * When soft delete is enabled, sets the deletion timestamp instead of removing the record.
282
324
  */
283
- declare abstract class DrizzleDeleteEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends DeleteEndpoint<E, M> {
325
+ declare abstract class DrizzleDeleteEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends DeleteEndpoint<E, M> {
284
326
  /** Drizzle database instance */
285
- db?: DrizzleDatabase;
327
+ db?: DB;
286
328
  /**
287
329
  * Whether to wrap delete and cascade operations in a transaction.
288
330
  * When true, the entire delete operation (including cascade deletes) will be atomic.
@@ -290,15 +332,15 @@ declare abstract class DrizzleDeleteEndpoint<E extends Env = Env, M extends Meta
290
332
  */
291
333
  protected useTransaction: boolean;
292
334
  /** Current transaction context (set during transaction execution) */
293
- protected _tx?: DrizzleDatabase;
335
+ protected _tx?: DrizzleDatabaseConstraint;
294
336
  /** Gets the database instance from property, transaction, or context */
295
- protected getDb(): DrizzleDatabase;
296
- protected getTable(): Table;
297
- protected getColumn(field: string): Column;
337
+ protected getDb(): DB;
338
+ protected getTable(): DrizzleTable;
339
+ protected getColumn(field: string): DrizzleColumn;
298
340
  /**
299
341
  * Gets a related table from the relation config.
300
342
  */
301
- protected getRelatedTable(relationConfig: RelationConfig): Table | undefined;
343
+ protected getRelatedTable(relationConfig: RelationConfig): DrizzleTable | undefined;
302
344
  /**
303
345
  * Finds a record without deleting it (for constraint checks).
304
346
  */
@@ -330,9 +372,9 @@ declare abstract class DrizzleDeleteEndpoint<E extends Env = Env, M extends Meta
330
372
  * - Use `?withDeleted=true` to include deleted records
331
373
  * - Use `?onlyDeleted=true` to show only deleted records
332
374
  */
333
- declare abstract class DrizzleListEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends ListEndpoint<E, M> {
375
+ declare abstract class DrizzleListEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends ListEndpoint<E, M> {
334
376
  /** Drizzle database instance */
335
- db?: DrizzleDatabase;
377
+ db?: DB;
336
378
  /**
337
379
  * SQL dialect of the underlying Drizzle database.
338
380
  *
@@ -348,9 +390,9 @@ declare abstract class DrizzleListEndpoint<E extends Env = Env, M extends MetaIn
348
390
  */
349
391
  protected dialect: DrizzleDialect;
350
392
  /** Gets the database instance from property or context */
351
- protected getDb(): DrizzleDatabase;
352
- protected getTable(): Table;
353
- protected getColumn(field: string): Column;
393
+ protected getDb(): DB;
394
+ protected getTable(): DrizzleTable;
395
+ protected getColumn(field: string): DrizzleColumn;
354
396
  list(filters: ListFilters): Promise<PaginatedResult<ModelObject<M['model']>>>;
355
397
  }
356
398
  /**
@@ -360,9 +402,9 @@ declare abstract class DrizzleListEndpoint<E extends Env = Env, M extends MetaIn
360
402
  * Only works with models that have `softDelete` enabled.
361
403
  * Sets the deletion timestamp back to null.
362
404
  */
363
- declare abstract class DrizzleRestoreEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends RestoreEndpoint<E, M> {
405
+ declare abstract class DrizzleRestoreEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends RestoreEndpoint<E, M> {
364
406
  /** Drizzle database instance */
365
- db?: DrizzleDatabase;
407
+ db?: DB;
366
408
  /**
367
409
  * Whether to wrap restore operation in a transaction.
368
410
  * Useful when combined with hooks that perform additional operations.
@@ -370,11 +412,11 @@ declare abstract class DrizzleRestoreEndpoint<E extends Env = Env, M extends Met
370
412
  */
371
413
  protected useTransaction: boolean;
372
414
  /** Current transaction context (set during transaction execution) */
373
- protected _tx?: DrizzleDatabase;
415
+ protected _tx?: DrizzleDatabaseConstraint;
374
416
  /** Gets the database instance from property, transaction, or context */
375
- protected getDb(): DrizzleDatabase;
376
- protected getTable(): Table;
377
- protected getColumn(field: string): Column;
417
+ protected getDb(): DB;
418
+ protected getTable(): DrizzleTable;
419
+ protected getColumn(field: string): DrizzleColumn;
378
420
  restore(lookupValue: string, additionalFilters?: Record<string, string>, tx?: unknown): Promise<ModelObject<M['model']> | null>;
379
421
  /**
380
422
  * Override handle to wrap in transaction when useTransaction is true.
@@ -386,12 +428,12 @@ declare abstract class DrizzleRestoreEndpoint<E extends Env = Env, M extends Met
386
428
  * Drizzle Batch Create endpoint.
387
429
  * Works with any Drizzle dialect (PostgreSQL, MySQL, SQLite).
388
430
  */
389
- declare abstract class DrizzleBatchCreateEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends BatchCreateEndpoint<E, M> {
431
+ declare abstract class DrizzleBatchCreateEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends BatchCreateEndpoint<E, M> {
390
432
  /** Drizzle database instance */
391
- db?: DrizzleDatabase;
433
+ db?: DB;
392
434
  /** Gets the database instance from property or context */
393
- protected getDb(): DrizzleDatabase;
394
- protected getTable(): Table;
435
+ protected getDb(): DB;
436
+ protected getTable(): DrizzleTable;
395
437
  batchCreate(items: Partial<ModelObject<M['model']>>[]): Promise<ModelObject<M['model']>[]>;
396
438
  }
397
439
  /**
@@ -400,13 +442,13 @@ declare abstract class DrizzleBatchCreateEndpoint<E extends Env = Env, M extends
400
442
  *
401
443
  * Supports soft delete filtering (cannot update deleted records).
402
444
  */
403
- declare abstract class DrizzleBatchUpdateEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends BatchUpdateEndpoint<E, M> {
445
+ declare abstract class DrizzleBatchUpdateEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends BatchUpdateEndpoint<E, M> {
404
446
  /** Drizzle database instance */
405
- db?: DrizzleDatabase;
447
+ db?: DB;
406
448
  /** Gets the database instance from property or context */
407
- protected getDb(): DrizzleDatabase;
408
- protected getTable(): Table;
409
- protected getColumn(field: string): Column;
449
+ protected getDb(): DB;
450
+ protected getTable(): DrizzleTable;
451
+ protected getColumn(field: string): DrizzleColumn;
410
452
  batchUpdate(items: BatchUpdateItem<ModelObject<M['model']>>[]): Promise<{
411
453
  updated: ModelObject<M['model']>[];
412
454
  notFound: string[];
@@ -418,13 +460,13 @@ declare abstract class DrizzleBatchUpdateEndpoint<E extends Env = Env, M extends
418
460
  *
419
461
  * Supports soft delete when the model has `softDelete` configured.
420
462
  */
421
- declare abstract class DrizzleBatchDeleteEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends BatchDeleteEndpoint<E, M> {
463
+ declare abstract class DrizzleBatchDeleteEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends BatchDeleteEndpoint<E, M> {
422
464
  /** Drizzle database instance. Can be undefined if using context injection. */
423
- db?: DrizzleDatabase;
465
+ db?: DB;
424
466
  /** Gets the database instance from property or context. */
425
- protected getDb(): DrizzleDatabase;
426
- protected getTable(): Table;
427
- protected getColumn(field: string): Column;
467
+ protected getDb(): DB;
468
+ protected getTable(): DrizzleTable;
469
+ protected getColumn(field: string): DrizzleColumn;
428
470
  batchDelete(ids: string[]): Promise<{
429
471
  deleted: ModelObject<M['model']>[];
430
472
  notFound: string[];
@@ -436,13 +478,13 @@ declare abstract class DrizzleBatchDeleteEndpoint<E extends Env = Env, M extends
436
478
  *
437
479
  * Only works with models that have `softDelete` enabled.
438
480
  */
439
- declare abstract class DrizzleBatchRestoreEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends BatchRestoreEndpoint<E, M> {
481
+ declare abstract class DrizzleBatchRestoreEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends BatchRestoreEndpoint<E, M> {
440
482
  /** Drizzle database instance. Can be undefined if using context injection. */
441
- db?: DrizzleDatabase;
483
+ db?: DB;
442
484
  /** Gets the database instance from property or context. */
443
- protected getDb(): DrizzleDatabase;
444
- protected getTable(): Table;
445
- protected getColumn(field: string): Column;
485
+ protected getDb(): DB;
486
+ protected getTable(): DrizzleTable;
487
+ protected getColumn(field: string): DrizzleColumn;
446
488
  batchRestore(ids: string[]): Promise<{
447
489
  restored: ModelObject<M['model']>[];
448
490
  notFound: string[];
@@ -468,14 +510,14 @@ declare abstract class DrizzleBatchRestoreEndpoint<E extends Env = Env, M extend
468
510
  * `> 0` is the dialect-agnostic predicate that means "needle is a
469
511
  * substring of col".
470
512
  */
471
- declare function substringMatch(col: Column | SQL, needle: string, dialect: DrizzleDialect): SQL;
513
+ declare function substringMatch(col: DrizzleColumn | DrizzleSql, needle: string, dialect: DrizzleDialect): DrizzleSql;
472
514
  /**
473
515
  * Drizzle Upsert endpoint.
474
516
  * Creates a record if it doesn't exist, updates it if it does.
475
517
  */
476
- declare abstract class DrizzleUpsertEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends UpsertEndpoint<E, M> {
518
+ declare abstract class DrizzleUpsertEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends UpsertEndpoint<E, M> {
477
519
  /** Drizzle database instance. Can be undefined if using context injection. */
478
- db?: DrizzleDatabase;
520
+ db?: DB;
479
521
  /**
480
522
  * SQL dialect of the underlying Drizzle database.
481
523
  *
@@ -487,9 +529,9 @@ declare abstract class DrizzleUpsertEndpoint<E extends Env = Env, M extends Meta
487
529
  */
488
530
  protected dialect: DrizzleDialect;
489
531
  /** Gets the database instance from property or context. */
490
- protected getDb(): DrizzleDatabase;
491
- protected getTable(): Table;
492
- protected getColumn(field: string): Column;
532
+ protected getDb(): DB;
533
+ protected getTable(): DrizzleTable;
534
+ protected getColumn(field: string): DrizzleColumn;
493
535
  findExisting(data: Partial<ModelObject<M['model']>>): Promise<ModelObject<M['model']> | null>;
494
536
  create(data: Partial<ModelObject<M['model']>>): Promise<ModelObject<M['model']>>;
495
537
  update(existing: ModelObject<M['model']>, data: Partial<ModelObject<M['model']>>): Promise<ModelObject<M['model']>>;
@@ -509,18 +551,18 @@ declare abstract class DrizzleUpsertEndpoint<E extends Env = Env, M extends Meta
509
551
  /**
510
552
  * Drizzle Batch Upsert endpoint.
511
553
  */
512
- declare abstract class DrizzleBatchUpsertEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends BatchUpsertEndpoint<E, M> {
554
+ declare abstract class DrizzleBatchUpsertEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends BatchUpsertEndpoint<E, M> {
513
555
  /** Drizzle database instance. Can be undefined if using context injection. */
514
- db?: DrizzleDatabase;
556
+ db?: DB;
515
557
  /**
516
558
  * SQL dialect of the underlying Drizzle database. See
517
559
  * {@link DrizzleUpsertEndpoint.dialect} for full semantics.
518
560
  */
519
561
  protected dialect: DrizzleDialect;
520
562
  /** Gets the database instance from property or context. */
521
- protected getDb(): DrizzleDatabase;
522
- protected getTable(): Table;
523
- protected getColumn(field: string): Column;
563
+ protected getDb(): DB;
564
+ protected getTable(): DrizzleTable;
565
+ protected getColumn(field: string): DrizzleColumn;
524
566
  findExisting(data: Partial<ModelObject<M['model']>>): Promise<ModelObject<M['model']> | null>;
525
567
  create(data: Partial<ModelObject<M['model']>>): Promise<ModelObject<M['model']>>;
526
568
  update(existing: ModelObject<M['model']>, data: Partial<ModelObject<M['model']>>): Promise<ModelObject<M['model']>>;
@@ -551,24 +593,31 @@ declare abstract class DrizzleBatchUpsertEndpoint<E extends Env = Env, M extends
551
593
  * Drizzle Version History endpoint.
552
594
  * Lists all versions for a record.
553
595
  */
554
- declare abstract class DrizzleVersionHistoryEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends VersionHistoryEndpoint<E, M> {
596
+ declare abstract class DrizzleVersionHistoryEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends VersionHistoryEndpoint<E, M> {
555
597
  /** Drizzle database instance. Can be undefined if using context injection. */
556
- db?: DrizzleDatabase;
598
+ db?: DB;
557
599
  /** Gets the database instance from property or context. */
558
- protected getDb(): DrizzleDatabase;
559
- protected getTable(): Table;
560
- protected getColumn(field: string): Column;
600
+ protected getDb(): DB;
601
+ protected getTable(): DrizzleTable;
602
+ protected getColumn(field: string): DrizzleColumn;
561
603
  protected recordExists(lookupValue: string): Promise<boolean>;
562
604
  }
563
605
  /**
564
606
  * Drizzle Version Read endpoint.
565
607
  * Gets a specific version of a record.
608
+ *
609
+ * Unlike the db-touching endpoints, this is a pure pass-through to the core
610
+ * base class and performs no Drizzle queries, so it intentionally takes only
611
+ * `<E, M>` — there is no third `DB` generic to parametrize.
566
612
  */
567
613
  declare abstract class DrizzleVersionReadEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends VersionReadEndpoint<E, M> {
568
614
  }
569
615
  /**
570
616
  * Drizzle Version Compare endpoint.
571
617
  * Compares two versions of a record.
618
+ *
619
+ * Like {@link DrizzleVersionReadEndpoint}, this is a pure pass-through with no
620
+ * Drizzle queries, so it intentionally takes only `<E, M>` (no `DB` generic).
572
621
  */
573
622
  declare abstract class DrizzleVersionCompareEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends VersionCompareEndpoint<E, M> {
574
623
  }
@@ -576,26 +625,26 @@ declare abstract class DrizzleVersionCompareEndpoint<E extends Env = Env, M exte
576
625
  * Drizzle Version Rollback endpoint.
577
626
  * Rolls back a record to a previous version.
578
627
  */
579
- declare abstract class DrizzleVersionRollbackEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends VersionRollbackEndpoint<E, M> {
628
+ declare abstract class DrizzleVersionRollbackEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends VersionRollbackEndpoint<E, M> {
580
629
  /** Drizzle database instance. Can be undefined if using context injection. */
581
- db?: DrizzleDatabase;
630
+ db?: DB;
582
631
  /** Gets the database instance from property or context. */
583
- protected getDb(): DrizzleDatabase;
584
- protected getTable(): Table;
585
- protected getColumn(field: string): Column;
632
+ protected getDb(): DB;
633
+ protected getTable(): DrizzleTable;
634
+ protected getColumn(field: string): DrizzleColumn;
586
635
  rollback(lookupValue: string, versionData: Record<string, unknown>, newVersion: number): Promise<ModelObject<M['model']>>;
587
636
  }
588
637
  /**
589
638
  * Drizzle Aggregate endpoint.
590
639
  * Computes aggregations (COUNT, SUM, AVG, MIN, MAX) with GROUP BY support.
591
640
  */
592
- declare abstract class DrizzleAggregateEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends AggregateEndpoint<E, M> {
641
+ declare abstract class DrizzleAggregateEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends AggregateEndpoint<E, M> {
593
642
  /** Drizzle database instance. Can be undefined if using context injection. */
594
- db?: DrizzleDatabase;
643
+ db?: DB;
595
644
  /** Gets the database instance from property or context. */
596
- protected getDb(): DrizzleDatabase;
597
- protected getTable(): Table;
598
- protected getColumn(field: string): Column;
645
+ protected getDb(): DB;
646
+ protected getTable(): DrizzleTable;
647
+ protected getColumn(field: string): DrizzleColumn;
599
648
  aggregate(options: AggregateOptions): Promise<AggregateResult>;
600
649
  }
601
650
  /**
@@ -627,9 +676,9 @@ declare abstract class DrizzleAggregateEndpoint<E extends Env = Env, M extends M
627
676
  * }
628
677
  * ```
629
678
  */
630
- declare abstract class DrizzleSearchEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends SearchEndpoint<E, M> {
679
+ declare abstract class DrizzleSearchEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends SearchEndpoint<E, M> {
631
680
  /** Drizzle database instance. Can be undefined if using context injection. */
632
- db?: DrizzleDatabase;
681
+ db?: DB;
633
682
  /**
634
683
  * SQL dialect of the underlying Drizzle database.
635
684
  *
@@ -643,7 +692,7 @@ declare abstract class DrizzleSearchEndpoint<E extends Env = Env, M extends Meta
643
692
  */
644
693
  protected dialect: DrizzleDialect;
645
694
  /** Gets the database instance from property or context. */
646
- protected getDb(): DrizzleDatabase;
695
+ protected getDb(): DB;
647
696
  /**
648
697
  * Enable PostgreSQL native full-text search.
649
698
  * When true and vectorColumn is set, uses tsvector/tsquery.
@@ -659,8 +708,8 @@ declare abstract class DrizzleSearchEndpoint<E extends Env = Env, M extends Meta
659
708
  * PostgreSQL text search configuration (e.g., 'english', 'simple').
660
709
  */
661
710
  protected vectorConfig: string;
662
- protected getTable(): Table;
663
- protected getColumn(field: string): Column;
711
+ protected getTable(): DrizzleTable;
712
+ protected getColumn(field: string): DrizzleColumn;
664
713
  /**
665
714
  * Performs search on database.
666
715
  */
@@ -670,9 +719,9 @@ declare abstract class DrizzleSearchEndpoint<E extends Env = Env, M extends Meta
670
719
  * Drizzle Export endpoint.
671
720
  * Exports data in CSV or JSON format with support for filtering and field selection.
672
721
  */
673
- declare abstract class DrizzleExportEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends ExportEndpoint<E, M> {
722
+ declare abstract class DrizzleExportEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends ExportEndpoint<E, M> {
674
723
  /** Drizzle database instance. Can be undefined if using context injection. */
675
- db?: DrizzleDatabase;
724
+ db?: DB;
676
725
  /**
677
726
  * SQL dialect of the underlying Drizzle database. Drives the
678
727
  * substring-match function emitted on the `?search=` path. See
@@ -680,22 +729,22 @@ declare abstract class DrizzleExportEndpoint<E extends Env = Env, M extends Meta
680
729
  */
681
730
  protected dialect: DrizzleDialect;
682
731
  /** Gets the database instance from property or context. */
683
- protected getDb(): DrizzleDatabase;
684
- protected getTable(): Table;
685
- protected getColumn(field: string): Column;
732
+ protected getDb(): DB;
733
+ protected getTable(): DrizzleTable;
734
+ protected getColumn(field: string): DrizzleColumn;
686
735
  list(filters: ListFilters): Promise<PaginatedResult<ModelObject<M['model']>>>;
687
736
  }
688
737
  /**
689
738
  * Drizzle Import endpoint.
690
739
  * Imports data from CSV or JSON with support for create and upsert modes.
691
740
  */
692
- declare abstract class DrizzleImportEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends ImportEndpoint<E, M> {
741
+ declare abstract class DrizzleImportEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends ImportEndpoint<E, M> {
693
742
  /** Drizzle database instance. Can be undefined if using context injection. */
694
- db?: DrizzleDatabase;
743
+ db?: DB;
695
744
  /** Gets the database instance from property or context. */
696
- protected getDb(): DrizzleDatabase;
697
- protected getTable(): Table;
698
- protected getColumn(field: string): Column;
745
+ protected getDb(): DB;
746
+ protected getTable(): DrizzleTable;
747
+ protected getColumn(field: string): DrizzleColumn;
699
748
  /**
700
749
  * Finds an existing record by upsert keys.
701
750
  */
@@ -727,13 +776,13 @@ declare abstract class DrizzleImportEndpoint<E extends Env = Env, M extends Meta
727
776
  *
728
777
  * Override `generateId()` to swap UUIDv4 for ULID/snowflake/etc.
729
778
  */
730
- declare abstract class DrizzleCloneEndpoint<E extends Env = Env, M extends MetaInput = MetaInput> extends CloneEndpoint<E, M> {
779
+ declare abstract class DrizzleCloneEndpoint<E extends Env = Env, M extends MetaInput = MetaInput, DB extends DrizzleDatabaseConstraint = DrizzleDatabaseConstraint> extends CloneEndpoint<E, M> {
731
780
  /** Drizzle database instance. Can be undefined if using context injection. */
732
- db?: DrizzleDatabase;
781
+ db?: DB;
733
782
  /** Gets the database instance from property or context. */
734
- protected getDb(): DrizzleDatabase;
735
- protected getTable(): Table;
736
- protected getColumn(field: string): Column;
783
+ protected getDb(): DB;
784
+ protected getTable(): DrizzleTable;
785
+ protected getColumn(field: string): DrizzleColumn;
737
786
  /** Generates the primary-key value for the cloned row. Defaults to UUIDv4. */
738
787
  protected generateId(): string;
739
788
  findSource(lookupValue: string, additionalFilters?: Record<string, string>): Promise<ModelObject<M['model']> | null>;
@@ -836,16 +885,6 @@ declare function createDrizzleCrud<M extends MetaInput, E extends Env = Env>(db:
836
885
  * ```
837
886
  */
838
887
 
839
- /**
840
- * Duck-typed interface for Drizzle tables.
841
- * This allows compatibility across different drizzle-orm versions and package installations.
842
- */
843
- type DrizzleTable = {
844
- _: {
845
- name: string;
846
- columns: Record<string, unknown>;
847
- };
848
- };
849
888
  /**
850
889
  * Re-export createSelectSchema from drizzle-zod.
851
890
  * Creates a Zod schema for SELECT queries (all columns as required/optional based on table definition).
@@ -988,4 +1027,4 @@ declare function isDrizzleZodAvailable(): boolean;
988
1027
  */
989
1028
  declare const DrizzleAdapters: AdapterBundle;
990
1029
 
991
- export { type CreateDrizzleCrudOptions, type Database, DrizzleAdapters, DrizzleAggregateEndpoint, DrizzleBatchCreateEndpoint, DrizzleBatchDeleteEndpoint, DrizzleBatchRestoreEndpoint, DrizzleBatchUpdateEndpoint, DrizzleBatchUpsertEndpoint, DrizzleCloneEndpoint, DrizzleCreateEndpoint, type DrizzleCrudClasses, type DrizzleDB, type DrizzleDatabase, type DrizzleDatabaseConstraint, DrizzleDeleteEndpoint, type DrizzleDialect, type DrizzleEnv, DrizzleExportEndpoint, DrizzleImportEndpoint, DrizzleListEndpoint, DrizzleReadEndpoint, DrizzleRestoreEndpoint, type DrizzleSchemas, DrizzleSearchEndpoint, DrizzleUpdateEndpoint, DrizzleUpsertEndpoint, DrizzleVersionCompareEndpoint, DrizzleVersionHistoryEndpoint, DrizzleVersionReadEndpoint, DrizzleVersionRollbackEndpoint, type QueryBuilder, batchLoadDrizzleRelations, buildWhereCondition, cast, createDrizzleCrud, createDrizzleSchemas, createInsertSchema, createSelectSchema, createUpdateSchema, getColumn, getTable, isDrizzleZodAvailable, loadDrizzleRelation, loadDrizzleRelations, substringMatch };
1030
+ export { type CountRow, type CreateDrizzleCrudOptions, DRIZZLE_DIALECTS, type Database, DrizzleAdapters, DrizzleAggregateEndpoint, DrizzleBatchCreateEndpoint, DrizzleBatchDeleteEndpoint, DrizzleBatchRestoreEndpoint, DrizzleBatchUpdateEndpoint, DrizzleBatchUpsertEndpoint, DrizzleCloneEndpoint, type DrizzleColumn, DrizzleCreateEndpoint, type DrizzleCrudClasses, type DrizzleDatabaseConstraint, DrizzleDeleteEndpoint, type DrizzleDialect, type DrizzleEnv, DrizzleExportEndpoint, DrizzleImportEndpoint, DrizzleListEndpoint, DrizzleReadEndpoint, DrizzleRestoreEndpoint, type DrizzleSchemas, DrizzleSearchEndpoint, type DrizzleSql, type DrizzleTable, DrizzleUpdateEndpoint, DrizzleUpsertEndpoint, DrizzleVersionCompareEndpoint, DrizzleVersionHistoryEndpoint, DrizzleVersionReadEndpoint, DrizzleVersionRollbackEndpoint, type QueryBuilder, batchLoadDrizzleRelations, buildWhereCondition, cast, createDrizzleCrud, createDrizzleSchemas, createInsertSchema, createSelectSchema, createUpdateSchema, getColumn, getTable, isDrizzleZodAvailable, loadDrizzleRelation, loadDrizzleRelations, readCount, substringMatch };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import {getTableColumns,eq,inArray,between,isNull,isNotNull,ilike,like,notInArray,lte,lt,gte,gt,ne as ne$1,sql,and,or,desc,asc}from'drizzle-orm';import {UpsertEndpoint,BatchUpsertEndpoint,VersionHistoryEndpoint,VersionReadEndpoint,VersionCompareEndpoint,VersionRollbackEndpoint,AggregateEndpoint,computeAggregations,SearchEndpoint,searchInMemory,ExportEndpoint,ImportEndpoint,CloneEndpoint,CreateEndpoint,getLogger,ReadEndpoint,UpdateEndpoint,DeleteEndpoint,ListEndpoint,RestoreEndpoint,BatchCreateEndpoint,BatchUpdateEndpoint,BatchDeleteEndpoint,BatchRestoreEndpoint}from'hono-crud/internal';import {z}from'zod';function X(a){return a}function f(a){if(!a.model.table)throw new Error(`Model ${a.model.tableName} does not have a table reference`);return a.model.table}function b(a,e){let t=getTableColumns(a),o=t[e];if(!o)throw new Error(`Column '${e}' not found in table. Available columns: ${Object.keys(t).join(", ")}`);return o}async function pe(a,e,t,o){if(!o.table)return e;let n=o.table;switch(o.type){case "hasOne":{let r=o.localKey||"id",s=e[r];if(s==null)return e;let i=b(n,o.foreignKey),l=await a.select().from(n).where(eq(i,s)).limit(1);return {...e,[t]:l[0]||null}}case "hasMany":{let r=o.localKey||"id",s=e[r];if(s==null)return {...e,[t]:[]};let i=b(n,o.foreignKey),l=await a.select().from(n).where(eq(i,s));return {...e,[t]:l}}case "belongsTo":{let r=e[o.foreignKey];if(r==null)return {...e,[t]:null};let s=b(n,o.localKey||"id"),i=await a.select().from(n).where(eq(s,r)).limit(1);return {...e,[t]:i[0]||null}}default:return e}}async function de(a,e,t,o){if(!o?.relations?.length||!t.model.relations)return e;let n={...e};for(let r of o.relations){let s=t.model.relations[r];s&&(n=await pe(a,n,r,s));}return n}async function S(a,e,t,o){if(!e.length||!o?.relations?.length||!t.model.relations)return e;let n=e.map(r=>({...r}));for(let r of o.relations){let s=t.model.relations[r];if(!s||!s.table)continue;let i=s.table;switch(s.type){case "hasOne":case "hasMany":{let l=s.localKey||"id",d=[...new Set(n.map(p=>p[l]).filter(p=>p!=null))];if(d.length===0){n=n.map(p=>({...p,[r]:s.type==="hasMany"?[]:null}));continue}let u=b(i,s.foreignKey),c=await a.select().from(i).where(inArray(u,d)),m=new Map;for(let p of c){let g=p[s.foreignKey];m.has(g)||m.set(g,[]),m.get(g).push(p);}n=n.map(p=>{let g=p[l],h=m.get(g)||[];return {...p,[r]:s.type==="hasMany"?h:h[0]||null}});break}case "belongsTo":{let l=s.localKey||"id",d=[...new Set(n.map(p=>p[s.foreignKey]).filter(p=>p!=null))];if(d.length===0){n=n.map(p=>({...p,[r]:null}));continue}let u=b(i,l),c=await a.select().from(i).where(inArray(u,d)),m=new Map;for(let p of c){let g=p[l];m.set(g,p);}n=n.map(p=>{let g=p[s.foreignKey];return {...p,[r]:m.get(g)||null}});break}}}return n}function O(a,e){let t=b(a,e.field);switch(e.operator){case "eq":return eq(t,e.value);case "ne":return ne$1(t,e.value);case "gt":return gt(t,e.value);case "gte":return gte(t,e.value);case "lt":return lt(t,e.value);case "lte":return lte(t,e.value);case "in":return inArray(t,e.value);case "nin":return notInArray(t,e.value);case "like":return like(t,e.value);case "ilike":return ilike(t,e.value);case "null":return e.value?isNull(t):isNotNull(t);case "between":{let[o,n]=e.value;return between(t,o,n)}default:return}}function D(a){let e=a;if(e._tx)return e._tx;if(e.db)return e.db;let t=e.context?.get?.("db");if(t)return t;throw new Error(`Database not configured. Either:
1
+ import {getTableColumns,eq,inArray,between,isNull,isNotNull,ilike,like,notInArray,lte,lt,gte,gt,ne as ne$1,sql,desc,asc,and,or}from'drizzle-orm';import {assertNever,UpsertEndpoint,BatchUpsertEndpoint,VersionHistoryEndpoint,VersionReadEndpoint,VersionCompareEndpoint,VersionRollbackEndpoint,AggregateEndpoint,computeAggregations,SearchEndpoint,searchInMemory,ExportEndpoint,ImportEndpoint,CloneEndpoint,CreateEndpoint,getLogger,ReadEndpoint,UpdateEndpoint,DeleteEndpoint,ListEndpoint,RestoreEndpoint,BatchCreateEndpoint,BatchUpdateEndpoint,BatchDeleteEndpoint,BatchRestoreEndpoint}from'hono-crud/internal';import {z as z$1}from'zod';function G(a){return a}function z(...a){return and(...a)}function B(...a){return or(...a)}var Ke=["sqlite","pg","mysql"];function D(a){if(!a.model.table)throw new Error(`Model ${a.model.tableName} does not have a table reference`);return a.model.table}function h(a,e){let t=getTableColumns(a),r=t[e];if(!r)throw new Error(`Column '${e}' not found in table. Available columns: ${Object.keys(t).join(", ")}`);return r}async function ue(a,e,t,r){if(!r.table)return e;let n=r.table;switch(r.type){case "hasOne":{let o=r.localKey||"id",s=e[o];if(s==null)return e;let i=h(n,r.foreignKey),l=await a.select().from(n).where(eq(i,s)).limit(1);return {...e,[t]:l[0]||null}}case "hasMany":{let o=r.localKey||"id",s=e[o];if(s==null)return {...e,[t]:[]};let i=h(n,r.foreignKey),l=await a.select().from(n).where(eq(i,s));return {...e,[t]:l}}case "belongsTo":{let o=e[r.foreignKey];if(o==null)return {...e,[t]:null};let s=h(n,r.localKey||"id"),i=await a.select().from(n).where(eq(s,o)).limit(1);return {...e,[t]:i[0]||null}}default:return e}}async function de(a,e,t,r){if(!r?.relations?.length||!t.model.relations)return e;let n={...e};for(let o of r.relations){let s=t.model.relations[o];s&&(n=await ue(a,n,o,s));}return n}async function S(a,e,t,r){if(!e.length||!r?.relations?.length||!t.model.relations)return e;let n=e.map(o=>({...o}));for(let o of r.relations){let s=t.model.relations[o];if(!s||!s.table)continue;let i=s.table;switch(s.type){case "hasOne":case "hasMany":{let l=s.localKey||"id",d=[...new Set(n.map(p=>p[l]).filter(p=>p!=null))];if(d.length===0){n=n.map(p=>({...p,[o]:s.type==="hasMany"?[]:null}));continue}let u=h(i,s.foreignKey),c=await a.select().from(i).where(inArray(u,d)),m=new Map;for(let p of c){let g=p[s.foreignKey];m.has(g)||m.set(g,[]),m.get(g).push(p);}n=n.map(p=>{let g=p[l],b=m.get(g)||[];return {...p,[o]:s.type==="hasMany"?b:b[0]||null}});break}case "belongsTo":{let l=s.localKey||"id",d=[...new Set(n.map(p=>p[s.foreignKey]).filter(p=>p!=null))];if(d.length===0){n=n.map(p=>({...p,[o]:null}));continue}let u=h(i,l),c=await a.select().from(i).where(inArray(u,d)),m=new Map;for(let p of c){let g=p[l];m.set(g,p);}n=n.map(p=>{let g=p[s.foreignKey];return {...p,[o]:m.get(g)||null}});break}}}return n}function O(a,e){let t=h(a,e.field);switch(e.operator){case "eq":return eq(t,e.value);case "ne":return ne$1(t,e.value);case "gt":return gt(t,e.value);case "gte":return gte(t,e.value);case "lt":return lt(t,e.value);case "lte":return lte(t,e.value);case "in":return inArray(t,e.value);case "nin":return notInArray(t,e.value);case "like":return like(t,e.value);case "ilike":return ilike(t,e.value);case "null":return e.value?isNull(t):isNotNull(t);case "between":{let[r,n]=e.value;return between(t,r,n)}default:return assertNever(e.operator)}}function k(a){return Number(a[0]?.count)||0}function y(a){let e=a;if(e._tx)return e._tx;if(e.db)return e.db;let t=e.context?.get?.("db");if(t)return t;throw new Error(`Database not configured. Either:
2
2
  1. Set db property: db = myDb;
3
3
  2. Use middleware: c.set("db", myDb);
4
- 3. Use factory: createDrizzleCrud(db, meta)`)}function ee(a,e,t){switch(t){case "pg":return sql`POSITION(LOWER(${e}) IN LOWER(${a})) > 0`;case "mysql":return sql`LOCATE(LOWER(${e}), LOWER(${a})) > 0`;default:return sql`INSTR(LOWER(${a}), LOWER(${e})) > 0`}}function Je(a){return a.split(/\s+/).filter(e=>e.length>0)}var j=class extends UpsertEndpoint{db;dialect="sqlite";getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async findExisting(e){let t=this.getTable(),o=this.getUpsertKeys(),n=this.getSoftDeleteConfig(),r=[];for(let i of o){let l=e[i];l!==void 0&&r.push(eq(this.getColumn(i),l));}return n.enabled&&r.push(isNull(this.getColumn(n.field))),r.length===0?null:(await this.getDb().select().from(t).where(and(...r)).limit(1))[0]||null}async create(e){let t=this.getTable(),o=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(o).returning())[0]}async update(e,t){let o=this.getTable(),n=this._meta.model.primaryKeys[0],r=e[n];return (await this.getDb().update(o).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(n),r)).returning())[0]}async nativeUpsert(e,t){let o=this.getTable(),n=this.getUpsertKeys(),r=this._meta.model.primaryKeys[0],s=this.getSoftDeleteConfig(),i=this.getTimestampsConfig(),l=this.applyManagedInsertFields(e,"drizzle"),d={};for(let[h,y]of Object.entries(e))!n.includes(h)&&h!==r&&(this.createOnlyFields?.includes(h)||(d[h]=y));i.enabled&&(d[i.updatedAt]=Date.now());let u=n.map(h=>this.getColumn(h)),c;s.enabled&&(c=isNull(this.getColumn(s.field)));let m=Object.keys(d).length>0?d:{[r]:sql`${this.getColumn(r)}`},p=this.getDb().insert(o).values(l);return this.dialect==="mysql"?{data:(await p.onDuplicateKeyUpdate({set:m}).returning())[0],created:false}:{data:(await p.onConflictDoUpdate({target:u,set:m,where:c}).returning())[0],created:false}}},_=class extends BatchUpsertEndpoint{db;dialect="sqlite";getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async findExisting(e){let t=this.getTable(),o=this.getUpsertKeys(),n=[];for(let s of o){let i=e[s];i!==void 0&&n.push(eq(this.getColumn(s),i));}return n.length===0?null:(await this.getDb().select().from(t).where(and(...n)).limit(1))[0]||null}async create(e){let t=this.getTable(),o=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(o).returning())[0]}async update(e,t){let o=this.getTable(),n=this._meta.model.primaryKeys[0],r=e[n];return (await this.getDb().update(o).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(n),r)).returning())[0]}async nativeBatchUpsert(e,t){if(e.length===0)return {items:[],createdCount:0,updatedCount:0,totalCount:0};let o=this.getTable(),n=this.getUpsertKeys(),r=this._meta.model.primaryKeys[0],s=this.getTimestampsConfig(),i=e.map(g=>this.applyManagedInsertFields(g,"drizzle")),l={},d=e[0];for(let g of Object.keys(d))!n.includes(g)&&g!==r&&(this.createOnlyFields?.includes(g)||(l[g]=sql`excluded.${sql.identifier(g)}`));s.enabled&&(l[s.updatedAt]=Date.now());let u=n.map(g=>this.getColumn(g)),c=Object.keys(l).length>0?l:{[r]:sql`${this.getColumn(r)}`},m=this.getDb().insert(o).values(i),p=await(this.dialect==="mysql"?m.onDuplicateKeyUpdate({set:c}):m.onConflictDoUpdate({target:u,set:c})).returning();return {items:p.map((g,h)=>({data:g,created:false,index:h})),createdCount:0,updatedCount:p.length,totalCount:p.length}}},ge=class extends VersionHistoryEndpoint{db;getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async recordExists(e){let t=this.getTable(),o=await this.getDb().select({count:sql`count(*)`}).from(t).where(eq(this.getColumn("id"),e));return Number(o[0]?.count)>0}},me=class extends VersionReadEndpoint{},be=class extends VersionCompareEndpoint{},he=class extends VersionRollbackEndpoint{db;getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async rollback(e,t,o){let n=this.getTable(),r=this.getVersioningConfig().field;return (await this.getDb().update(n).set({...t,[r]:o}).where(eq(this.getColumn("id"),e)).returning())[0]}},G=class extends AggregateEndpoint{db;getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async aggregate(e){let t=this.getTable(),o=[],n=this.getSoftDeleteConfig();if(n.enabled){let{query:i}=await this.getValidatedData();i?.withDeleted===true||i?.withDeleted==="true"||o.push(isNull(this.getColumn(n.field)));}if(e.filters)for(let[i,l]of Object.entries(e.filters))if(typeof l=="object"&&l!==null)for(let[d,u]of Object.entries(l)){let c=O(t,{field:i,operator:d,value:u});c&&o.push(c);}else o.push(eq(this.getColumn(i),l));let r=o.length>0?and(...o):void 0,s=await this.getDb().select().from(t).where(r);return computeAggregations(s,e)}},I=class extends SearchEndpoint{db;dialect="sqlite";getDb(){return D(this)}useNativeSearch=false;vectorColumn;vectorConfig="english";getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async search(e,t){let o=this.getTable(),n=[],r=this.getSoftDeleteConfig();r.enabled&&(t.options.onlyDeleted?n.push(isNotNull(this.getColumn(r.field))):t.options.withDeleted||n.push(isNull(this.getColumn(r.field))));for(let w of t.filters){let M=O(o,w);M&&n.push(M);}let s=this.getSearchableFields(),i=e.fields||Object.keys(s);if(this.useNativeSearch&&this.vectorColumn){let w=this.getColumn(this.vectorColumn),M=e.mode==="phrase"?sql`phraseto_tsquery(${this.vectorConfig}, ${e.query})`:e.mode==="all"?sql`plainto_tsquery(${this.vectorConfig}, ${e.query})`:sql`to_tsquery(${this.vectorConfig}, ${e.query.split(/\s+/).join(" | ")})`;n.push(sql`${w} @@ ${M}`);}else {let w=(M,x)=>{try{let ie=this.getColumn(M);return ee(sql`CAST(${ie} AS TEXT)`,x,this.dialect)}catch{return}};if(e.mode==="all"){let M=Je(e.query);if(M.length>0){let x=[];for(let ie of M){let ue=i.map(ae=>w(ae,ie)).filter(ae=>ae!==void 0);ue.length>0&&x.push(or(...ue));}x.length>0&&n.push(and(...x));}}else {let M=i.map(x=>w(x,e.query)).filter(x=>x!==void 0);M.length>0&&n.push(or(...M));}}let l=n.length>0?and(...n):void 0,d=await this.getDb().select({count:sql`count(*)`}).from(o).where(l),u=Number(d[0]?.count)||0,c=this.getDb().select().from(o).where(l);if(t.options.order_by){let w=this.getColumn(t.options.order_by),M=t.options.order_by_direction==="desc"?desc:asc;c=c.orderBy(M(w));}let m=t.options.page||1,p=t.options.per_page||this.defaultPerPage;c=c.limit(p).offset((m-1)*p);let g=await c,h=e.mode==="all"?{...e,mode:"any"}:e,y=searchInMemory(g,h,s),R={relations:t.options.include||[]},$=y.map(w=>w.item),se=await S(this.getDb(),$,this._meta,R);return {items:y.map((w,M)=>({...w,item:se[M]})),totalCount:u}}},H=class extends ExportEndpoint{db;dialect="sqlite";getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async list(e){let t=this.getTable(),o=[],n=this.getSoftDeleteConfig();if(n.enabled){let h=this.getColumn(n.field);e.options.onlyDeleted?o.push(isNotNull(h)):e.options.withDeleted||o.push(isNull(h));}for(let h of e.filters){let y=O(t,h);y&&o.push(y);}if(e.options.search&&this.searchFields.length>0){let h=e.options.search,y=this.searchFields.map(R=>{let $=this.getColumn(R);return ee($,h,this.dialect)});o.push(or(...y));}let r=o.length>0?and(...o):void 0,s=await this.getDb().select({count:sql`count(*)`}).from(t).where(r),i=Number(s[0]?.count)||0,l=this.getDb().select().from(t).where(r);if(e.options.order_by){let h=this.getColumn(e.options.order_by),y=e.options.order_by_direction==="desc"?desc:asc;l=l.orderBy(y(h));}let d=e.options.page||1,u=e.options.per_page||this.defaultPerPage;l=l.limit(u).offset((d-1)*u);let c=await l,m={relations:e.options.include||[]},p=await S(this.getDb(),c,this._meta,m),g=Math.ceil(i/u);return {result:p,result_info:{page:d,per_page:u,total_count:i,total_pages:g,has_next_page:d<g,has_prev_page:d>1}}}},J=class extends ImportEndpoint{db;getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async findExisting(e){let t=this.getTable(),o=this.getUpsertKeys(),n=this.getSoftDeleteConfig(),r=[];for(let i of o){let l=e[i];l!==void 0&&r.push(eq(this.getColumn(i),l));}return n.enabled&&r.push(isNull(this.getColumn(n.field))),r.length===0?null:(await this.getDb().select().from(t).where(and(...r)).limit(1))[0]||null}async create(e){let t=this.getTable(),o=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(o).returning())[0]}async update(e,t){let o=this.getTable(),n=this._meta.model.primaryKeys[0],r=e[n];return (await this.getDb().update(o).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(n),r)).returning())[0]}},Y=class extends CloneEndpoint{db;getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}generateId(){return crypto.randomUUID()}async findSource(e,t){let o=this.getTable(),n=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),s=[eq(n,e)];if(t)for(let[l,d]of Object.entries(t))s.push(eq(this.getColumn(l),d));r.enabled&&s.push(isNull(this.getColumn(r.field)));let i=await this.getDb().select().from(o).where(and(...s)).limit(1);return i[0]?i[0]:null}async createClone(e){let t=this.getTable(),o=this.applyManagedInsertFields(e,"drizzle",()=>this.generateId());return (await this.getDb().insert(t).values(o).returning())[0]}};var U=class extends CreateEndpoint{db;useTransaction=false;getDb(){return D(this)}getTable(){return f(this._meta)}getRelatedTable(e){return e.table}async create(e,t){let o=t??this.getDb(),n=this.getTable(),r=this.applyManagedInsertFields(e,"drizzle");return (await o.insert(n).values(r).returning())[0]}async createNested(e,t,o,n,r){let s=r??this.getDb(),i=this.getRelatedTable(o);if(!i)return getLogger().warn(`Related table not found for ${t}. Add 'table' to the relation config.`),[];let l=Array.isArray(n)?n:[n],d=[];for(let u of l){if(typeof u!="object"||u===null)continue;let c={...u,id:crypto.randomUUID(),[o.foreignKey]:e},m=await s.insert(i).values(c).returning();m[0]&&d.push(m[0]);}return d}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}},B=class extends ReadEndpoint{db;getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async read(e,t,o){let n=this.getTable(),r=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),i=[eq(r,e)];if(t)for(let[u,c]of Object.entries(t))i.push(eq(this.getColumn(u),c));s.enabled&&i.push(isNull(this.getColumn(s.field)));let l=await this.getDb().select().from(n).where(and(...i)).limit(1);return l[0]?await de(this.getDb(),l[0],this._meta,o):null}},A=class extends UpdateEndpoint{db;useTransaction=false;getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}getRelatedTable(e){return e.table}async findExisting(e,t,o){let n=o??this.getDb(),r=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return i.enabled&&l.push(isNull(this.getColumn(i.field))),(await n.select().from(r).where(and(...l)).limit(1))[0]||null}async update(e,t,o,n){let r=n??this.getDb(),s=this.getTable(),i=this.getColumn(this.lookupField),l=this.getSoftDeleteConfig(),d=[eq(i,e)];if(o)for(let[c,m]of Object.entries(o))d.push(eq(this.getColumn(c),m));return l.enabled&&d.push(isNull(this.getColumn(l.field))),(await r.update(s).set(this.applyManagedUpdateFields(t)).where(and(...d)).returning())[0]||null}async processNestedWrites(e,t,o,n,r){let s=r??this.getDb(),i=this.getRelatedTable(o);if(!i)return getLogger().warn(`Related table not found for ${t}. Add 'table' to the relation config.`),{created:[],updated:[],deleted:[],connected:[],disconnected:[]};let l={created:[],updated:[],deleted:[],connected:[],disconnected:[]},d=b(i,o.foreignKey),u=b(i,"id");if(n.create){let c=Array.isArray(n.create)?n.create:[n.create];for(let m of c){if(typeof m!="object"||m===null)continue;let p={...m,id:crypto.randomUUID(),[o.foreignKey]:e},g=await s.insert(i).values(p).returning();g[0]&&l.created.push(g[0]);}}if(n.update)for(let c of n.update){if(!c.id||!(await s.select().from(i).where(and(eq(u,c.id),eq(d,e))).limit(1))[0])continue;let{id:p,...g}=c,h=await s.update(i).set(g).where(eq(u,p)).returning();h[0]&&l.updated.push(h[0]);}if(n.delete)for(let c of n.delete)(await s.delete(i).where(and(eq(u,c),eq(d,e))).returning())[0]&&l.deleted.push(c);if(n.connect)for(let c of n.connect)(await s.update(i).set({[o.foreignKey]:e}).where(eq(u,c)).returning())[0]&&l.connected.push(c);if(n.disconnect)for(let c of n.disconnect)(await s.update(i).set({[o.foreignKey]:null}).where(and(eq(u,c),eq(d,e))).returning())[0]&&l.disconnected.push(c);return l}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}},L=class extends DeleteEndpoint{db;useTransaction=false;getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}getRelatedTable(e){return e.table}async findForDelete(e,t,o){let n=o??this.getDb(),r=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return i.enabled&&l.push(isNull(this.getColumn(i.field))),(await n.select().from(r).where(and(...l)).limit(1))[0]||null}async delete(e,t,o){let n=o??this.getDb(),r=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[d,u]of Object.entries(t))l.push(eq(this.getColumn(d),u));return i.enabled&&l.push(isNull(this.getColumn(i.field))),i.enabled?(await n.update(r).set({[i.field]:new Date}).where(and(...l)).returning())[0]||null:(await n.delete(r).where(and(...l)).returning())[0]||null}async countRelated(e,t,o,n){let r=n??this.getDb(),s=this.getRelatedTable(o);if(!s)return 0;let i=b(s,o.foreignKey),l=await r.select({count:sql`count(*)`}).from(s).where(eq(i,e));return Number(l[0]?.count)||0}async deleteRelated(e,t,o,n){let r=n??this.getDb(),s=this.getRelatedTable(o);if(!s)return 0;let i=b(s,o.foreignKey);return (await r.delete(s).where(eq(i,e)).returning()).length}async nullifyRelated(e,t,o,n){let r=n??this.getDb(),s=this.getRelatedTable(o);if(!s)return 0;let i=b(s,o.foreignKey);return (await r.update(s).set({[o.foreignKey]:null}).where(eq(i,e)).returning()).length}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}},K=class extends ListEndpoint{db;dialect="sqlite";getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async list(e){let t=this.getTable(),o=[],n=this.getSoftDeleteConfig();if(n.enabled){let y=this.getColumn(n.field);e.options.onlyDeleted?o.push(isNotNull(y)):e.options.withDeleted||o.push(isNull(y));}for(let y of e.filters){let R=O(t,y);R&&o.push(R);}if(e.options.search&&this.searchFields.length>0){let y=e.options.search,R=this.searchFields.map($=>{let se=this.getColumn($);return ee(se,y,this.dialect)});o.push(or(...R));}let r=o.length>0?and(...o):void 0,s=this.getDb(),i=await s.select({count:sql`count(*)`}).from(t).where(r),l=Number(i[0]?.count)||0,d=s.select().from(t).where(r);if(e.options.order_by){let y=this.getColumn(e.options.order_by),R=e.options.order_by_direction==="desc"?desc:asc;d=d.orderBy(R(y));}let u=e.options.page||1,c=e.options.per_page||this.defaultPerPage;d=d.limit(c).offset((u-1)*c);let m=await d,p={relations:e.options.include||[]},g=await S(this.getDb(),m,this._meta,p),h=Math.ceil(l/c);return {result:g,result_info:{page:u,per_page:c,total_count:l,total_pages:h,has_next_page:u<h,has_prev_page:u>1}}}},Z=class extends RestoreEndpoint{db;useTransaction=false;getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async restore(e,t,o){let n=o??this.getDb(),r=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return l.push(isNotNull(this.getColumn(i.field))),(await n.update(r).set({[i.field]:null}).where(and(...l)).returning())[0]||null}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}};var F=class extends BatchCreateEndpoint{db;getDb(){return D(this)}getTable(){return f(this._meta)}async batchCreate(e){let t=this.getTable(),o=e.map(r=>this.applyManagedInsertFields(r,"drizzle"));return await this.getDb().insert(t).values(o).returning()}},Q=class extends BatchUpdateEndpoint{db;getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async batchUpdate(e){let t=this.getTable(),o=this.getColumn(this.lookupField),n=this.getSoftDeleteConfig(),r=[],s=[];for(let i of e){let l=[eq(o,i.id)];n.enabled&&l.push(isNull(this.getColumn(n.field)));let d=await this.getDb().update(t).set(this.applyManagedUpdateFields(i.data)).where(and(...l)).returning();d[0]?r.push(d[0]):s.push(i.id);}return {updated:r,notFound:s}}},N=class extends BatchDeleteEndpoint{db;getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async batchDelete(e){let t=this.getTable(),o=this.getColumn(this.lookupField),n=this.getSoftDeleteConfig(),r=[inArray(o,e)];n.enabled&&r.push(isNull(this.getColumn(n.field)));let s;n.enabled?s=await this.getDb().update(t).set({[n.field]:new Date}).where(and(...r)).returning():s=await this.getDb().delete(t).where(and(...r)).returning();let i=s,l=new Set(i.map(u=>String(u[this.lookupField]))),d=e.filter(u=>!l.has(u));return {deleted:i,notFound:d}}},q=class extends BatchRestoreEndpoint{db;getDb(){return D(this)}getTable(){return f(this._meta)}getColumn(e){return b(this.getTable(),e)}async batchRestore(e){let t=this.getTable(),o=this.getColumn(this.lookupField),n=this.getSoftDeleteConfig(),r=[inArray(o,e),isNotNull(this.getColumn(n.field))],i=await this.getDb().update(t).set({[n.field]:null}).where(and(...r)).returning(),l=new Set(i.map(u=>String(u[this.lookupField]))),d=e.filter(u=>!l.has(u));return {restored:i,notFound:d}}};function ln(a,e,t){let o=t?.dialect??"sqlite";return {Create:class extends U{_meta=e;db=a},Read:class extends B{_meta=e;db=a},Update:class extends A{_meta=e;db=a},Delete:class extends L{_meta=e;db=a},List:class extends K{_meta=e;db=a;dialect=o},Restore:class extends Z{_meta=e;db=a},Upsert:class extends j{_meta=e;db=a;dialect=o},Search:class extends I{_meta=e;db=a;dialect=o},BatchCreate:class extends F{_meta=e;db=a},BatchUpdate:class extends Q{_meta=e;db=a},BatchDelete:class extends N{_meta=e;db=a},BatchRestore:class extends q{_meta=e;db=a},BatchUpsert:class extends _{_meta=e;db=a;dialect=o}}}var oe=null,Te=false,ne=null;async function re(){if(Te){if(ne)throw ne;return oe}Te=true;try{return oe=await import('drizzle-zod'),oe}catch{throw ne=new Error("drizzle-zod is not installed. Please install it: npm install drizzle-zod"),ne}}async function mt(a,e){return (await re()).createSelectSchema(a,e)}async function bt(a,e){return (await re()).createInsertSchema(a,e)}async function ht(a,e){let t=await re();return t.createUpdateSchema?t.createUpdateSchema(a,e):t.createInsertSchema(a,e).partial()}async function ft(a,e){let t=await re(),o=e?.coerceDates!==false,n=o?Mt(a):new Set,r=t.createSelectSchema(a,e?.selectRefine),s=t.createInsertSchema(a,e?.insertRefine),i;return t.createUpdateSchema?i=t.createUpdateSchema(a,e?.updateRefine):i=t.createInsertSchema(a,e?.updateRefine).partial(),o&&n.size>0&&(s=Re(s,n),i=Re(i,n)),{select:r,insert:s,update:i}}function zt(){return oe!==null}var Dt=z.preprocess(a=>{if(a instanceof Date)return a;if(typeof a=="string"){let e=new Date(a);if(!isNaN(e.getTime()))return e}return a},z.date()),yt=z.preprocess(a=>{if(a==null)return null;if(a instanceof Date)return a;if(typeof a=="string"){let e=new Date(a);if(!isNaN(e.getTime()))return e}return a},z.date().nullable());function Mt(a){let e=new Set,t=a;for(let[o,n]of Object.entries(t)){if(o==="_"||o==="$inferInsert"||o==="$inferSelect")continue;let r=n;if(!r||typeof r!="object")continue;let s=String(r.dataType??"").toLowerCase(),i=String(r.columnType??"").toLowerCase(),l=r.config,d=String(l?.dataType??"").toLowerCase();(s.includes("timestamp")||s.includes("date")||s.includes("datetime")||i.includes("pgtimestamp")||i.includes("pgdate")||i.includes("mysqltimestamp")||i.includes("mysqldate")||i.includes("sqlitetimestamp")||d.includes("timestamp")||d.includes("date"))&&e.add(o);}return e}function Re(a,e){if(e.size===0)return a;let t=a.shape,o={};for(let[n,r]of Object.entries(t))if(e.has(n)){let s=r.isOptional?.()??false,i=r.isNullable?.()??false,l=Dt;(i||s)&&(l=yt),s&&(l=l.optional()),o[n]=l;}else o[n]=r;return z.object(o)}var kn={CreateEndpoint:U,ListEndpoint:K,ReadEndpoint:B,UpdateEndpoint:A,DeleteEndpoint:L,RestoreEndpoint:Z,BatchCreateEndpoint:F,BatchUpdateEndpoint:Q,BatchDeleteEndpoint:N,BatchRestoreEndpoint:q,BatchUpsertEndpoint:_,SearchEndpoint:I,AggregateEndpoint:G,ExportEndpoint:H,ImportEndpoint:J,UpsertEndpoint:j,CloneEndpoint:Y};export{kn as DrizzleAdapters,G as DrizzleAggregateEndpoint,F as DrizzleBatchCreateEndpoint,N as DrizzleBatchDeleteEndpoint,q as DrizzleBatchRestoreEndpoint,Q as DrizzleBatchUpdateEndpoint,_ as DrizzleBatchUpsertEndpoint,Y as DrizzleCloneEndpoint,U as DrizzleCreateEndpoint,L as DrizzleDeleteEndpoint,H as DrizzleExportEndpoint,J as DrizzleImportEndpoint,K as DrizzleListEndpoint,B as DrizzleReadEndpoint,Z as DrizzleRestoreEndpoint,I as DrizzleSearchEndpoint,A as DrizzleUpdateEndpoint,j as DrizzleUpsertEndpoint,be as DrizzleVersionCompareEndpoint,ge as DrizzleVersionHistoryEndpoint,me as DrizzleVersionReadEndpoint,he as DrizzleVersionRollbackEndpoint,S as batchLoadDrizzleRelations,O as buildWhereCondition,X as cast,ln as createDrizzleCrud,ft as createDrizzleSchemas,bt as createInsertSchema,mt as createSelectSchema,ht as createUpdateSchema,b as getColumn,f as getTable,zt as isDrizzleZodAvailable,pe as loadDrizzleRelation,de as loadDrizzleRelations,ee as substringMatch};
4
+ 3. Use factory: createDrizzleCrud(db, meta)`)}function te(a,e,t){switch(t){case "pg":return sql`POSITION(LOWER(${e}) IN LOWER(${a})) > 0`;case "mysql":return sql`LOCATE(LOWER(${e}), LOWER(${a})) > 0`;default:return sql`INSTR(LOWER(${a}), LOWER(${e})) > 0`}}function tt(a){return a.split(/\s+/).filter(e=>e.length>0)}var j=class extends UpsertEndpoint{db;dialect="sqlite";getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async findExisting(e){let t=this.getTable(),r=this.getUpsertKeys(),n=this.getSoftDeleteConfig(),o=[];for(let i of r){let l=e[i];l!==void 0&&o.push(eq(this.getColumn(i),l));}return n.enabled&&o.push(isNull(this.getColumn(n.field))),o.length===0?null:(await this.getDb().select().from(t).where(z(...o)).limit(1))[0]||null}async create(e){let t=this.getTable(),r=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(r).returning())[0]}async update(e,t){let r=this.getTable(),n=this._meta.model.primaryKeys[0],o=e[n];return (await this.getDb().update(r).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(n),o)).returning())[0]}async nativeUpsert(e,t){let r=this.getTable(),n=this.getUpsertKeys(),o=this._meta.model.primaryKeys[0],s=this.getSoftDeleteConfig(),i=this.getTimestampsConfig(),l=this.applyManagedInsertFields(e,"drizzle"),d={};for(let[b,C]of Object.entries(e))!n.includes(b)&&b!==o&&(this.createOnlyFields?.includes(b)||(d[b]=C));i.enabled&&(d[i.updatedAt]=Date.now());let u=n.map(b=>this.getColumn(b)),c;s.enabled&&(c=isNull(this.getColumn(s.field)));let m=Object.keys(d).length>0?d:{[o]:sql`${this.getColumn(o)}`},p=this.getDb().insert(r).values(l);return this.dialect==="mysql"?{data:(await p.onDuplicateKeyUpdate({set:m}).returning())[0],created:false}:{data:(await p.onConflictDoUpdate({target:u,set:m,where:c}).returning())[0],created:false}}},_=class extends BatchUpsertEndpoint{db;dialect="sqlite";getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async findExisting(e){let t=this.getTable(),r=this.getUpsertKeys(),n=[];for(let s of r){let i=e[s];i!==void 0&&n.push(eq(this.getColumn(s),i));}return n.length===0?null:(await this.getDb().select().from(t).where(z(...n)).limit(1))[0]||null}async create(e){let t=this.getTable(),r=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(r).returning())[0]}async update(e,t){let r=this.getTable(),n=this._meta.model.primaryKeys[0],o=e[n];return (await this.getDb().update(r).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(n),o)).returning())[0]}async nativeBatchUpsert(e,t){if(e.length===0)return {items:[],createdCount:0,updatedCount:0,totalCount:0};let r=this.getTable(),n=this.getUpsertKeys(),o=this._meta.model.primaryKeys[0],s=this.getTimestampsConfig(),i=e.map(g=>this.applyManagedInsertFields(g,"drizzle")),l={},d=e[0];for(let g of Object.keys(d))!n.includes(g)&&g!==o&&(this.createOnlyFields?.includes(g)||(l[g]=sql`excluded.${sql.identifier(g)}`));s.enabled&&(l[s.updatedAt]=Date.now());let u=n.map(g=>this.getColumn(g)),c=Object.keys(l).length>0?l:{[o]:sql`${this.getColumn(o)}`},m=this.getDb().insert(r).values(i),p=await(this.dialect==="mysql"?m.onDuplicateKeyUpdate({set:c}):m.onConflictDoUpdate({target:u,set:c})).returning();return {items:p.map((g,b)=>({data:g,created:false,index:b})),createdCount:0,updatedCount:p.length,totalCount:p.length}}},pe=class extends VersionHistoryEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async recordExists(e){let t=this.getTable(),r=await this.getDb().select({count:sql`count(*)`}).from(t).where(eq(this.getColumn("id"),e));return k(r)>0}},ge=class extends VersionReadEndpoint{},me=class extends VersionCompareEndpoint{},he=class extends VersionRollbackEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async rollback(e,t,r){let n=this.getTable(),o=this.getVersioningConfig().field;return (await this.getDb().update(n).set({...t,[o]:r}).where(eq(this.getColumn("id"),e)).returning())[0]}},H=class extends AggregateEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async aggregate(e){let t=this.getTable(),r=[],n=this.getSoftDeleteConfig();if(n.enabled){let{query:i}=await this.getValidatedData();i?.withDeleted===true||i?.withDeleted==="true"||r.push(isNull(this.getColumn(n.field)));}if(e.filters)for(let[i,l]of Object.entries(e.filters))if(typeof l=="object"&&l!==null)for(let[d,u]of Object.entries(l)){let c=O(t,{field:i,operator:d,value:u});c&&r.push(c);}else r.push(eq(this.getColumn(i),l));let o=r.length>0?z(...r):void 0,s=await this.getDb().select().from(t).where(o);return computeAggregations(s,e)}},I=class extends SearchEndpoint{db;dialect="sqlite";getDb(){return y(this)}useNativeSearch=false;vectorColumn;vectorConfig="english";getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async search(e,t){let r=this.getTable(),n=[],o=this.getSoftDeleteConfig();o.enabled&&(t.options.onlyDeleted?n.push(isNotNull(this.getColumn(o.field))):t.options.withDeleted||n.push(isNull(this.getColumn(o.field))));for(let E of t.filters){let M=O(r,E);M&&n.push(M);}let s=this.getSearchableFields(),i=e.fields||Object.keys(s);if(this.useNativeSearch&&this.vectorColumn){let E=this.getColumn(this.vectorColumn),M=e.mode==="phrase"?sql`phraseto_tsquery(${this.vectorConfig}, ${e.query})`:e.mode==="all"?sql`plainto_tsquery(${this.vectorConfig}, ${e.query})`:sql`to_tsquery(${this.vectorConfig}, ${e.query.split(/\s+/).join(" | ")})`;n.push(sql`${E} @@ ${M}`);}else {let E=(M,x)=>{try{let ie=this.getColumn(M);return te(sql`CAST(${ie} AS TEXT)`,x,this.dialect)}catch{return}};if(e.mode==="all"){let M=tt(e.query);if(M.length>0){let x=[];for(let ie of M){let ce=i.map(ae=>E(ae,ie)).filter(ae=>ae!==void 0);ce.length>0&&x.push(B(...ce));}x.length>0&&n.push(z(...x));}}else {let M=i.map(x=>E(x,e.query)).filter(x=>x!==void 0);M.length>0&&n.push(B(...M));}}let l=n.length>0?z(...n):void 0,d=await this.getDb().select({count:sql`count(*)`}).from(r).where(l),u=k(d),c=this.getDb().select().from(r).where(l);if(t.options.order_by){let E=this.getColumn(t.options.order_by),M=t.options.order_by_direction==="desc"?desc:asc;c=c.orderBy(M(E));}let m=t.options.page||1,p=t.options.per_page||this.defaultPerPage;c=c.limit(p).offset((m-1)*p);let g=await c,b=e.mode==="all"?{...e,mode:"any"}:e,C=searchInMemory(g,b,s),R={relations:t.options.include||[]},W=C.map(E=>E.item),se=await S(this.getDb(),W,this._meta,R);return {items:C.map((E,M)=>({...E,item:se[M]})),totalCount:u}}},J=class extends ExportEndpoint{db;dialect="sqlite";getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async list(e){let t=this.getTable(),r=[],n=this.getSoftDeleteConfig();if(n.enabled){let b=this.getColumn(n.field);e.options.onlyDeleted?r.push(isNotNull(b)):e.options.withDeleted||r.push(isNull(b));}for(let b of e.filters){let C=O(t,b);C&&r.push(C);}if(e.options.search&&this.searchFields.length>0){let b=e.options.search,C=this.searchFields.map(R=>{let W=this.getColumn(R);return te(W,b,this.dialect)});r.push(B(...C));}let o=r.length>0?z(...r):void 0,s=await this.getDb().select({count:sql`count(*)`}).from(t).where(o),i=k(s),l=this.getDb().select().from(t).where(o);if(e.options.order_by){let b=this.getColumn(e.options.order_by),C=e.options.order_by_direction==="desc"?desc:asc;l=l.orderBy(C(b));}let d=e.options.page||1,u=e.options.per_page||this.defaultPerPage;l=l.limit(u).offset((d-1)*u);let c=await l,m={relations:e.options.include||[]},p=await S(this.getDb(),c,this._meta,m),g=Math.ceil(i/u);return {result:p,result_info:{page:d,per_page:u,total_count:i,total_pages:g,has_next_page:d<g,has_prev_page:d>1}}}},Y=class extends ImportEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async findExisting(e){let t=this.getTable(),r=this.getUpsertKeys(),n=this.getSoftDeleteConfig(),o=[];for(let i of r){let l=e[i];l!==void 0&&o.push(eq(this.getColumn(i),l));}return n.enabled&&o.push(isNull(this.getColumn(n.field))),o.length===0?null:(await this.getDb().select().from(t).where(z(...o)).limit(1))[0]||null}async create(e){let t=this.getTable(),r=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(r).returning())[0]}async update(e,t){let r=this.getTable(),n=this._meta.model.primaryKeys[0],o=e[n];return (await this.getDb().update(r).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(n),o)).returning())[0]}},ee=class extends CloneEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}generateId(){return crypto.randomUUID()}async findSource(e,t){let r=this.getTable(),n=this.getColumn(this.lookupField),o=this.getSoftDeleteConfig(),s=[eq(n,e)];if(t)for(let[l,d]of Object.entries(t))s.push(eq(this.getColumn(l),d));o.enabled&&s.push(isNull(this.getColumn(o.field)));let i=await this.getDb().select().from(r).where(z(...s)).limit(1);return i[0]?i[0]:null}async createClone(e){let t=this.getTable(),r=this.applyManagedInsertFields(e,"drizzle",()=>this.generateId());return (await this.getDb().insert(t).values(r).returning())[0]}};var q=class extends CreateEndpoint{db;useTransaction=false;getDb(){return y(this)}getTable(){return D(this._meta)}getRelatedTable(e){return e.table}async create(e,t){let r=t??this.getDb(),n=this.getTable(),o=this.applyManagedInsertFields(e,"drizzle");return (await r.insert(n).values(o).returning())[0]}async createNested(e,t,r,n,o){let s=o??this.getDb(),i=this.getRelatedTable(r);if(!i)return getLogger().warn(`Related table not found for ${t}. Add 'table' to the relation config.`),[];let l=Array.isArray(n)?n:[n],d=[];for(let u of l){if(typeof u!="object"||u===null)continue;let c={...u,id:crypto.randomUUID(),[r.foreignKey]:e},m=await s.insert(i).values(c).returning();m[0]&&d.push(m[0]);}return d}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}},U=class extends ReadEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async read(e,t,r){let n=this.getTable(),o=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),i=[eq(o,e)];if(t)for(let[u,c]of Object.entries(t))i.push(eq(this.getColumn(u),c));s.enabled&&i.push(isNull(this.getColumn(s.field)));let l=await this.getDb().select().from(n).where(z(...i)).limit(1);return l[0]?await de(this.getDb(),l[0],this._meta,r):null}},A=class extends UpdateEndpoint{db;useTransaction=false;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}getRelatedTable(e){return e.table}async findExisting(e,t,r){let n=r??this.getDb(),o=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return i.enabled&&l.push(isNull(this.getColumn(i.field))),(await n.select().from(o).where(z(...l)).limit(1))[0]||null}async update(e,t,r,n){let o=n??this.getDb(),s=this.getTable(),i=this.getColumn(this.lookupField),l=this.getSoftDeleteConfig(),d=[eq(i,e)];if(r)for(let[c,m]of Object.entries(r))d.push(eq(this.getColumn(c),m));return l.enabled&&d.push(isNull(this.getColumn(l.field))),(await o.update(s).set(this.applyManagedUpdateFields(t)).where(z(...d)).returning())[0]||null}async processNestedWrites(e,t,r,n,o){let s=o??this.getDb(),i=this.getRelatedTable(r);if(!i)return getLogger().warn(`Related table not found for ${t}. Add 'table' to the relation config.`),{created:[],updated:[],deleted:[],connected:[],disconnected:[]};let l={created:[],updated:[],deleted:[],connected:[],disconnected:[]},d=h(i,r.foreignKey),u=h(i,"id");if(n.create){let c=Array.isArray(n.create)?n.create:[n.create];for(let m of c){if(typeof m!="object"||m===null)continue;let p={...m,id:crypto.randomUUID(),[r.foreignKey]:e},g=await s.insert(i).values(p).returning();g[0]&&l.created.push(g[0]);}}if(n.update)for(let c of n.update){if(!c.id||!(await s.select().from(i).where(z(eq(u,c.id),eq(d,e))).limit(1))[0])continue;let{id:p,...g}=c,b=await s.update(i).set(g).where(eq(u,p)).returning();b[0]&&l.updated.push(b[0]);}if(n.delete)for(let c of n.delete)(await s.delete(i).where(z(eq(u,c),eq(d,e))).returning())[0]&&l.deleted.push(c);if(n.connect)for(let c of n.connect)(await s.update(i).set({[r.foreignKey]:e}).where(eq(u,c)).returning())[0]&&l.connected.push(c);if(n.disconnect)for(let c of n.disconnect)(await s.update(i).set({[r.foreignKey]:null}).where(z(eq(u,c),eq(d,e))).returning())[0]&&l.disconnected.push(c);return l}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}},Z=class extends DeleteEndpoint{db;useTransaction=false;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}getRelatedTable(e){return e.table}async findForDelete(e,t,r){let n=r??this.getDb(),o=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return i.enabled&&l.push(isNull(this.getColumn(i.field))),(await n.select().from(o).where(z(...l)).limit(1))[0]||null}async delete(e,t,r){let n=r??this.getDb(),o=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[d,u]of Object.entries(t))l.push(eq(this.getColumn(d),u));return i.enabled&&l.push(isNull(this.getColumn(i.field))),i.enabled?(await n.update(o).set({[i.field]:new Date}).where(z(...l)).returning())[0]||null:(await n.delete(o).where(z(...l)).returning())[0]||null}async countRelated(e,t,r,n){let o=n??this.getDb(),s=this.getRelatedTable(r);if(!s)return 0;let i=h(s,r.foreignKey),l=await o.select({count:sql`count(*)`}).from(s).where(eq(i,e));return k(l)}async deleteRelated(e,t,r,n){let o=n??this.getDb(),s=this.getRelatedTable(r);if(!s)return 0;let i=h(s,r.foreignKey);return (await o.delete(s).where(eq(i,e)).returning()).length}async nullifyRelated(e,t,r,n){let o=n??this.getDb(),s=this.getRelatedTable(r);if(!s)return 0;let i=h(s,r.foreignKey);return (await o.update(s).set({[r.foreignKey]:null}).where(eq(i,e)).returning()).length}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}},K=class extends ListEndpoint{db;dialect="sqlite";getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async list(e){let t=this.getTable(),r=[],n=this.getSoftDeleteConfig();if(n.enabled){let C=this.getColumn(n.field);e.options.onlyDeleted?r.push(isNotNull(C)):e.options.withDeleted||r.push(isNull(C));}for(let C of e.filters){let R=O(t,C);R&&r.push(R);}if(e.options.search&&this.searchFields.length>0){let C=e.options.search,R=this.searchFields.map(W=>{let se=this.getColumn(W);return te(se,C,this.dialect)});r.push(B(...R));}let o=r.length>0?z(...r):void 0,s=this.getDb(),i=await s.select({count:sql`count(*)`}).from(t).where(o),l=k(i),d=s.select().from(t).where(o);if(e.options.order_by){let C=this.getColumn(e.options.order_by),R=e.options.order_by_direction==="desc"?desc:asc;d=d.orderBy(R(C));}let u=e.options.page||1,c=e.options.per_page||this.defaultPerPage;d=d.limit(c).offset((u-1)*c);let m=await d,p={relations:e.options.include||[]},g=await S(this.getDb(),m,this._meta,p),b=Math.ceil(l/c);return {result:g,result_info:{page:u,per_page:c,total_count:l,total_pages:b,has_next_page:u<b,has_prev_page:u>1}}}},F=class extends RestoreEndpoint{db;useTransaction=false;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async restore(e,t,r){let n=r??this.getDb(),o=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return l.push(isNotNull(this.getColumn(i.field))),(await n.update(o).set({[i.field]:null}).where(z(...l)).returning())[0]||null}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}};var L=class extends BatchCreateEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}async batchCreate(e){let t=this.getTable(),r=e.map(o=>this.applyManagedInsertFields(o,"drizzle"));return await this.getDb().insert(t).values(r).returning()}},N=class extends BatchUpdateEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async batchUpdate(e){let t=this.getTable(),r=this.getColumn(this.lookupField),n=this.getSoftDeleteConfig(),o=[],s=[];for(let i of e){let l=[eq(r,i.id)];n.enabled&&l.push(isNull(this.getColumn(n.field)));let d=await this.getDb().update(t).set(this.applyManagedUpdateFields(i.data)).where(z(...l)).returning();d[0]?o.push(d[0]):s.push(i.id);}return {updated:o,notFound:s}}},$=class extends BatchDeleteEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async batchDelete(e){let t=this.getTable(),r=this.getColumn(this.lookupField),n=this.getSoftDeleteConfig(),o=[inArray(r,e)];n.enabled&&o.push(isNull(this.getColumn(n.field)));let s;n.enabled?s=await this.getDb().update(t).set({[n.field]:new Date}).where(z(...o)).returning():s=await this.getDb().delete(t).where(z(...o)).returning();let i=s,l=new Set(i.map(u=>String(u[this.lookupField]))),d=e.filter(u=>!l.has(u));return {deleted:i,notFound:d}}},Q=class extends BatchRestoreEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async batchRestore(e){let t=this.getTable(),r=this.getColumn(this.lookupField),n=this.getSoftDeleteConfig(),o=[inArray(r,e),isNotNull(this.getColumn(n.field))],i=await this.getDb().update(t).set({[n.field]:null}).where(z(...o)).returning(),l=new Set(i.map(u=>String(u[this.lookupField]))),d=e.filter(u=>!l.has(u));return {restored:i,notFound:d}}};function un(a,e,t){let r=t?.dialect??"sqlite";return {Create:class extends q{_meta=e;db=a},Read:class extends U{_meta=e;db=a},Update:class extends A{_meta=e;db=a},Delete:class extends Z{_meta=e;db=a},List:class extends K{_meta=e;db=a;dialect=r},Restore:class extends F{_meta=e;db=a},Upsert:class extends j{_meta=e;db=a;dialect=r},Search:class extends I{_meta=e;db=a;dialect=r},BatchCreate:class extends L{_meta=e;db=a},BatchUpdate:class extends N{_meta=e;db=a},BatchDelete:class extends ${_meta=e;db=a},BatchRestore:class extends Q{_meta=e;db=a},BatchUpsert:class extends _{_meta=e;db=a;dialect=r}}}var re=null,Ee=false,ne=null;async function oe(){if(Ee){if(ne)throw ne;return re}Ee=true;try{return re=await import('drizzle-zod'),re}catch{throw ne=new Error("drizzle-zod is not installed. Please install it: npm install drizzle-zod"),ne}}async function bt(a,e){return (await oe()).createSelectSchema(a,e)}async function zt(a,e){return (await oe()).createInsertSchema(a,e)}async function Dt(a,e){let t=await oe();return t.createUpdateSchema?t.createUpdateSchema(a,e):t.createInsertSchema(a,e).partial()}async function ft(a,e){let t=await oe(),r=e?.coerceDates!==false,n=r?wt(a):new Set,o=t.createSelectSchema(a,e?.selectRefine),s=t.createInsertSchema(a,e?.insertRefine),i;return t.createUpdateSchema?i=t.createUpdateSchema(a,e?.updateRefine):i=t.createInsertSchema(a,e?.updateRefine).partial(),r&&n.size>0&&(s=Te(s,n),i=Te(i,n)),{select:o,insert:s,update:i}}function yt(){return re!==null}var Ct=z$1.preprocess(a=>{if(a instanceof Date)return a;if(typeof a=="string"){let e=new Date(a);if(!isNaN(e.getTime()))return e}return a},z$1.date()),Mt=z$1.preprocess(a=>{if(a==null)return null;if(a instanceof Date)return a;if(typeof a=="string"){let e=new Date(a);if(!isNaN(e.getTime()))return e}return a},z$1.date().nullable());function wt(a){let e=new Set,t=a;for(let[r,n]of Object.entries(t)){if(r==="_"||r==="$inferInsert"||r==="$inferSelect")continue;let o=n;if(!o||typeof o!="object")continue;let s=String(o.dataType??"").toLowerCase(),i=String(o.columnType??"").toLowerCase(),l=o.config,d=String(l?.dataType??"").toLowerCase();(s.includes("timestamp")||s.includes("date")||s.includes("datetime")||i.includes("pgtimestamp")||i.includes("pgdate")||i.includes("mysqltimestamp")||i.includes("mysqldate")||i.includes("sqlitetimestamp")||d.includes("timestamp")||d.includes("date"))&&e.add(r);}return e}function Te(a,e){if(e.size===0)return a;let t=a.shape,r={};for(let[n,o]of Object.entries(t))if(e.has(n)){let s=o.isOptional?.()??false,i=o.isNullable?.()??false,l=Ct;(i||s)&&(l=Mt),s&&(l=l.optional()),r[n]=l;}else r[n]=o;return z$1.object(r)}var Bn={CreateEndpoint:q,ListEndpoint:K,ReadEndpoint:U,UpdateEndpoint:A,DeleteEndpoint:Z,RestoreEndpoint:F,BatchCreateEndpoint:L,BatchUpdateEndpoint:N,BatchDeleteEndpoint:$,BatchRestoreEndpoint:Q,BatchUpsertEndpoint:_,SearchEndpoint:I,AggregateEndpoint:H,ExportEndpoint:J,ImportEndpoint:Y,UpsertEndpoint:j,CloneEndpoint:ee};export{Ke as DRIZZLE_DIALECTS,Bn as DrizzleAdapters,H as DrizzleAggregateEndpoint,L as DrizzleBatchCreateEndpoint,$ as DrizzleBatchDeleteEndpoint,Q as DrizzleBatchRestoreEndpoint,N as DrizzleBatchUpdateEndpoint,_ as DrizzleBatchUpsertEndpoint,ee as DrizzleCloneEndpoint,q as DrizzleCreateEndpoint,Z as DrizzleDeleteEndpoint,J as DrizzleExportEndpoint,Y as DrizzleImportEndpoint,K as DrizzleListEndpoint,U as DrizzleReadEndpoint,F as DrizzleRestoreEndpoint,I as DrizzleSearchEndpoint,A as DrizzleUpdateEndpoint,j as DrizzleUpsertEndpoint,me as DrizzleVersionCompareEndpoint,pe as DrizzleVersionHistoryEndpoint,ge as DrizzleVersionReadEndpoint,he as DrizzleVersionRollbackEndpoint,S as batchLoadDrizzleRelations,O as buildWhereCondition,G as cast,un as createDrizzleCrud,ft as createDrizzleSchemas,zt as createInsertSchema,bt as createSelectSchema,Dt as createUpdateSchema,h as getColumn,D as getTable,yt as isDrizzleZodAvailable,ue as loadDrizzleRelation,de as loadDrizzleRelations,k as readCount,te as substringMatch};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hono-crud/drizzle",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Drizzle ORM CRUD adapter for hono-crud",
5
5
  "author": "Kauan Guesser <contato@kauan.net>",
6
6
  "license": "MIT",
@@ -42,7 +42,7 @@
42
42
  "access": "public"
43
43
  },
44
44
  "dependencies": {
45
- "hono-crud": "0.13.7"
45
+ "hono-crud": "0.13.8"
46
46
  },
47
47
  "peerDependencies": {
48
48
  "drizzle-orm": ">=0.30.0",