@hono-crud/drizzle 0.1.8 → 0.1.9

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/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @hono-crud/drizzle
2
2
 
3
+ ## 0.1.9
4
+
5
+ ### Patch Changes
6
+
7
+ - 97e92f5: Dedup batch: the edge-safe in-memory TTL machinery, the cache entry wire format, and the relation-batching control flow each now live in exactly one place.
8
+
9
+ - New internal `MemoryTtlStore` in core (exported via `hono-crud/internal`) owns lazy cleanup-on-access, expiry-on-read, and insertion-order capacity eviction. The cache, rate-limit, and idempotency memory storages compose it, supplying only their entry shapes and domain indices (cache tag index via an eviction hook, idempotency locks as a second store). Public constructor options are unchanged. The logging memory storage intentionally stays standalone — its newest-first ordering is a different structure, not drift.
10
+ - New cache entry codec (`packages/cache/src/entry.ts`, internal): `buildCacheEntry` / `normalizeStoredEntry` / `isCacheEntryExpired` shared by the memory, Redis, and Cloudflare KV backends — including the single canonical legacy-Date migration guard, so already-persisted entries keep reading identically.
11
+ - New relation-batching orchestrator in core (exported via `hono-crud/internal`): the ORM-agnostic control flow (key collection, grouping, map-back, lookup-map dispatch over hasOne/hasMany/belongsTo) is shared; drizzle, prisma, and memory supply only their query adapters. N+1 batching fixes now land in one place.
12
+ - Two deliberate behavior fixes that the dedup surfaced: (1) single-item relation reads in the memory and drizzle adapters now always set the relation key (`null` / `[]` instead of absent), matching the batch path and prisma — this also fixes memory's belongsTo gating on the row's own `id` instead of the foreign key; (2) the rate-limit fixed window no longer slides its stored expiry on within-window increments — the window keeps its original `windowStart + windowMs` end.
13
+ - Internal-only removals (never publicly exported): memory's `loadRelation`, prisma's `loadPrismaRelation`.
14
+
15
+ - Updated dependencies [97e92f5]
16
+ - hono-crud@0.13.11
17
+
3
18
  ## 0.1.8
4
19
 
5
20
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -161,7 +161,9 @@ declare function getTable<M extends MetaInput>(meta: M): DrizzleTable;
161
161
  */
162
162
  declare function getColumn(table: DrizzleTable, field: string): DrizzleColumn;
163
163
  /**
164
- * Loads related records for a given item using Drizzle queries.
164
+ * Loads a single related record/collection for a given item using Drizzle
165
+ * queries. Always sets the relation key: hasOne/belongsTo → record-or-null,
166
+ * hasMany → array (including when the gate value is null).
165
167
  */
166
168
  declare function loadDrizzleRelation<T extends Record<string, unknown>>(db: DrizzleDatabaseConstraint, item: T, relationName: string, relationConfig: RelationConfig<DrizzleTable>): Promise<T>;
167
169
  /**
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,desc,asc,and,or}from'drizzle-orm';import {assertNever,UpsertEndpoint,BatchUpsertEndpoint,VersionHistoryEndpoint,VersionReadEndpoint,VersionCompareEndpoint,VersionRollbackEndpoint,AggregateEndpoint,isFilterOperator,computeAggregations,SearchEndpoint,searchInMemory,ExportEndpoint,ImportEndpoint,CloneEndpoint,CreateEndpoint,getLogger,ReadEndpoint,UpdateEndpoint,DeleteEndpoint,ListEndpoint,RestoreEndpoint,BatchCreateEndpoint,BatchUpdateEndpoint,BatchDeleteEndpoint,BatchRestoreEndpoint,CONTEXT_KEYS}from'hono-crud/internal';import {z as z$1}from'zod';function Y(a){return a}function z(...a){return and(...a)}function S(...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),n=t[e];if(!n)throw new Error(`Column '${e}' not found in table. Available columns: ${Object.keys(t).join(", ")}`);return n}async function ue(a,e,t,n){if(!n.table)return e;let r=n.table;switch(n.type){case "hasOne":{let o=n.localKey||"id",s=e[o];if(s==null)return e;let i=h(r,n.foreignKey),l=await a.select().from(r).where(eq(i,s)).limit(1);return {...e,[t]:l[0]||null}}case "hasMany":{let o=n.localKey||"id",s=e[o];if(s==null)return {...e,[t]:[]};let i=h(r,n.foreignKey),l=await a.select().from(r).where(eq(i,s));return {...e,[t]:l}}case "belongsTo":{let o=e[n.foreignKey];if(o==null)return {...e,[t]:null};let s=h(r,n.localKey||"id"),i=await a.select().from(r).where(eq(s,o)).limit(1);return {...e,[t]:i[0]||null}}default:return e}}async function de(a,e,t,n){if(!n?.relations?.length||!t.model.relations)return e;let r={...e};for(let o of n.relations){let s=t.model.relations[o];s&&(r=await ue(a,r,o,s));}return r}async function B(a,e,t,n){if(!e.length||!n?.relations?.length||!t.model.relations)return e;let r=e.map(o=>({...o}));for(let o of n.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(r.map(p=>p[l]).filter(p=>p!=null))];if(d.length===0){r=r.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);}r=r.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(r.map(p=>p[s.foreignKey]).filter(p=>p!=null))];if(d.length===0){r=r.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);}r=r.map(p=>{let g=p[s.foreignKey];return {...p,[o]:m.get(g)||null}});break}}}return r}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[n,r]=e.value;return between(t,n,r)}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?.(CONTEXT_KEYS.db);if(t)return t;throw new Error(`Database not configured. Either:
1
+ import {getTableColumns,between,isNull,isNotNull,ilike,like,notInArray,inArray,lte,lt,gte,gt,ne as ne$1,eq,sql,desc,asc,and,or}from'drizzle-orm';import {resolveRelationValueAsync,loadRelationsForItem,batchLoadRelations,assertNever,UpsertEndpoint,BatchUpsertEndpoint,VersionHistoryEndpoint,VersionReadEndpoint,VersionCompareEndpoint,VersionRollbackEndpoint,AggregateEndpoint,isFilterOperator,computeAggregations,SearchEndpoint,searchInMemory,ExportEndpoint,ImportEndpoint,CloneEndpoint,CreateEndpoint,getLogger,ReadEndpoint,UpdateEndpoint,DeleteEndpoint,ListEndpoint,RestoreEndpoint,BatchCreateEndpoint,BatchUpdateEndpoint,BatchDeleteEndpoint,BatchRestoreEndpoint,CONTEXT_KEYS}from'hono-crud/internal';import {z}from'zod';function X(o){return o}function m(...o){return and(...o)}function S(...o){return or(...o)}var Ke=["sqlite","pg","mysql"];function h(o){if(!o.model.table)throw new Error(`Model ${o.model.tableName} does not have a table reference`);return o.model.table}function p(o,e){let t=getTableColumns(o),n=t[e];if(!n)throw new Error(`Column '${e}' not found in table. Available columns: ${Object.keys(t).join(", ")}`);return n}function ae(o){return {resolveRelation:e=>e.table??null,fetchRelated:(e,t,n)=>o.select().from(e).where(inArray(p(e,t),n))}}async function $e(o,e,t,n){let r=n.table;if(!r)return e;let i=ae(o),a=await resolveRelationValueAsync(e,n,r,i.fetchRelated);return {...e,[t]:a}}async function le(o,e,t,n){return loadRelationsForItem(e,t,ae(o),n)}async function B(o,e,t,n){return batchLoadRelations(e,t,ae(o),n)}function k(o,e){let t=p(o,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[n,r]=e.value;return between(t,n,r)}default:return assertNever(e.operator)}}function O(o){return Number(o[0]?.count)||0}function f(o){let e=o;if(e._tx)return e._tx;if(e.db)return e.db;let t=e.context?.get?.(CONTEXT_KEYS.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(CONTEXT_KEYS.db, myDb);
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 rt(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(),n=this.getUpsertKeys(),r=this.getSoftDeleteConfig(),o=[];for(let i of n){let l=e[i];l!==void 0&&o.push(eq(this.getColumn(i),l));}return r.enabled&&o.push(isNull(this.getColumn(r.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(),n=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(n).returning())[0]}async update(e,t){let n=this.getTable(),r=this._meta.model.primaryKeys[0],o=e[r];return (await this.getDb().update(n).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(r),o)).returning())[0]}async nativeUpsert(e,t){let n=this.getTable(),r=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))!r.includes(b)&&b!==o&&(this.createOnlyFields?.includes(b)||(d[b]=C));i.enabled&&(d[i.updatedAt]=Date.now());let u=r.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(n).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(),n=this.getUpsertKeys(),r=[];for(let s of n){let i=e[s];i!==void 0&&r.push(eq(this.getColumn(s),i));}return r.length===0?null:(await this.getDb().select().from(t).where(z(...r)).limit(1))[0]||null}async create(e){let t=this.getTable(),n=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(n).returning())[0]}async update(e,t){let n=this.getTable(),r=this._meta.model.primaryKeys[0],o=e[r];return (await this.getDb().update(n).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(r),o)).returning())[0]}async nativeBatchUpsert(e,t){if(e.length===0)return {items:[],createdCount:0,updatedCount:0,totalCount:0};let n=this.getTable(),r=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))!r.includes(g)&&g!==o&&(this.createOnlyFields?.includes(g)||(l[g]=sql`excluded.${sql.identifier(g)}`));s.enabled&&(l[s.updatedAt]=Date.now());let u=r.map(g=>this.getColumn(g)),c=Object.keys(l).length>0?l:{[o]:sql`${this.getColumn(o)}`},m=this.getDb().insert(n).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(),n=await this.getDb().select({count:sql`count(*)`}).from(t).where(eq(this.getColumn("id"),e));return k(n)>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,n){let r=this.getTable(),o=this.getVersioningConfig().field;return (await this.getDb().update(r).set({...t,[o]:n}).where(eq(this.getColumn("id"),e)).returning())[0]}},G=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(),n=[],r=this.getSoftDeleteConfig();if(r.enabled){let{query:i}=await this.getValidatedData();i?.withDeleted===true||i?.withDeleted==="true"||n.push(isNull(this.getColumn(r.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)){if(!isFilterOperator(d)){n.push(sql`1 = 0`);continue}let c=O(t,{field:i,operator:d,value:u});c&&n.push(c);}else n.push(eq(this.getColumn(i),l));let o=n.length>0?z(...n):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 n=this.getTable(),r=[],o=this.getSoftDeleteConfig();o.enabled&&(t.options.onlyDeleted?r.push(isNotNull(this.getColumn(o.field))):t.options.withDeleted||r.push(isNull(this.getColumn(o.field))));for(let E of t.filters){let M=O(n,E);M&&r.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(" | ")})`;r.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=rt(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(S(...ce));}x.length>0&&r.push(z(...x));}}else {let M=i.map(x=>E(x,e.query)).filter(x=>x!==void 0);M.length>0&&r.push(S(...M));}}let l=r.length>0?z(...r):void 0,d=await this.getDb().select({count:sql`count(*)`}).from(n).where(l),u=k(d),c=this.getDb().select().from(n).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 B(this.getDb(),W,this._meta,R);return {items:C.map((E,M)=>({...E,item:se[M]})),totalCount:u}}},H=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(),n=[],r=this.getSoftDeleteConfig();if(r.enabled){let b=this.getColumn(r.field);e.options.onlyDeleted?n.push(isNotNull(b)):e.options.withDeleted||n.push(isNull(b));}for(let b of e.filters){let C=O(t,b);C&&n.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)});n.push(S(...C));}let o=n.length>0?z(...n):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 B(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 y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async findExisting(e){let t=this.getTable(),n=this.getUpsertKeys(),r=this.getSoftDeleteConfig(),o=[];for(let i of n){let l=e[i];l!==void 0&&o.push(eq(this.getColumn(i),l));}return r.enabled&&o.push(isNull(this.getColumn(r.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(),n=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(n).returning())[0]}async update(e,t){let n=this.getTable(),r=this._meta.model.primaryKeys[0],o=e[r];return (await this.getDb().update(n).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(r),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 n=this.getTable(),r=this.getColumn(this.lookupField),o=this.getSoftDeleteConfig(),s=[eq(r,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(n).where(z(...s)).limit(1);return i[0]?i[0]:null}async createClone(e){let t=this.getTable(),n=this.applyManagedInsertFields(e,"drizzle",()=>this.generateId());return (await this.getDb().insert(t).values(n).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 n=t??this.getDb(),r=this.getTable(),o=this.applyManagedInsertFields(e,"drizzle");return (await n.insert(r).values(o).returning())[0]}async createNested(e,t,n,r,o){let s=o??this.getDb(),i=this.getRelatedTable(n);if(!i)return getLogger().warn(`Related table not found for ${t}. Add 'table' to the relation config.`),[];let l=Array.isArray(r)?r:[r],d=[];for(let u of l){if(typeof u!="object"||u===null)continue;let c={...u,id:crypto.randomUUID(),[n.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,n){let r=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(r).where(z(...i)).limit(1);return l[0]?await de(this.getDb(),l[0],this._meta,n):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,n){let r=n??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 r.select().from(o).where(z(...l)).limit(1))[0]||null}async update(e,t,n,r){let o=r??this.getDb(),s=this.getTable(),i=this.getColumn(this.lookupField),l=this.getSoftDeleteConfig(),d=[eq(i,e)];if(n)for(let[c,m]of Object.entries(n))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,n,r,o){let s=o??this.getDb(),i=this.getRelatedTable(n);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,n.foreignKey),u=h(i,"id");if(r.create){let c=Array.isArray(r.create)?r.create:[r.create];for(let m of c){if(typeof m!="object"||m===null)continue;let p={...m,id:crypto.randomUUID(),[n.foreignKey]:e},g=await s.insert(i).values(p).returning();g[0]&&l.created.push(g[0]);}}if(r.update)for(let c of r.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(r.delete)for(let c of r.delete)(await s.delete(i).where(z(eq(u,c),eq(d,e))).returning())[0]&&l.deleted.push(c);if(r.connect)for(let c of r.connect)(await s.update(i).set({[n.foreignKey]:e}).where(eq(u,c)).returning())[0]&&l.connected.push(c);if(r.disconnect)for(let c of r.disconnect)(await s.update(i).set({[n.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,n){let r=n??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 r.select().from(o).where(z(...l)).limit(1))[0]||null}async delete(e,t,n){let r=n??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 r.update(o).set({[i.field]:new Date}).where(z(...l)).returning())[0]||null:(await r.delete(o).where(z(...l)).returning())[0]||null}async countRelated(e,t,n,r){let o=r??this.getDb(),s=this.getRelatedTable(n);if(!s)return 0;let i=h(s,n.foreignKey),l=await o.select({count:sql`count(*)`}).from(s).where(eq(i,e));return k(l)}async deleteRelated(e,t,n,r){let o=r??this.getDb(),s=this.getRelatedTable(n);if(!s)return 0;let i=h(s,n.foreignKey);return (await o.delete(s).where(eq(i,e)).returning()).length}async nullifyRelated(e,t,n,r){let o=r??this.getDb(),s=this.getRelatedTable(n);if(!s)return 0;let i=h(s,n.foreignKey);return (await o.update(s).set({[n.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(),n=[],r=this.getSoftDeleteConfig();if(r.enabled){let C=this.getColumn(r.field);e.options.onlyDeleted?n.push(isNotNull(C)):e.options.withDeleted||n.push(isNull(C));}for(let C of e.filters){let R=O(t,C);R&&n.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)});n.push(S(...R));}let o=n.length>0?z(...n):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 B(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,n){let r=n??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 r.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(),n=e.map(o=>this.applyManagedInsertFields(o,"drizzle"));return await this.getDb().insert(t).values(n).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(),n=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),o=[],s=[];for(let i of e){let l=[eq(n,i.id)];r.enabled&&l.push(isNull(this.getColumn(r.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(),n=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),o=[inArray(n,e)];r.enabled&&o.push(isNull(this.getColumn(r.field)));let s;r.enabled?s=await this.getDb().update(t).set({[r.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(),n=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),o=[inArray(n,e),isNotNull(this.getColumn(r.field))],i=await this.getDb().update(t).set({[r.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 hn(a,e,t){let n=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=n},Restore:class extends F{_meta=e;db=a},Upsert:class extends j{_meta=e;db=a;dialect=n},Search:class extends I{_meta=e;db=a;dialect=n},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=n}}}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 Dt(a,e){return (await oe()).createSelectSchema(a,e)}async function ft(a,e){return (await oe()).createInsertSchema(a,e)}async function yt(a,e){let t=await oe();return t.createUpdateSchema?t.createUpdateSchema(a,e):t.createInsertSchema(a,e).partial()}async function Ct(a,e){let t=await oe(),n=e?.coerceDates!==false,r=n?Tt(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(),n&&r.size>0&&(s=Te(s,r),i=Te(i,r)),{select:o,insert:s,update:i}}function Mt(){return re!==null}var wt=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()),Et=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 Tt(a){let e=new Set,t=a;for(let[n,r]of Object.entries(t)){if(n==="_"||n==="$inferInsert"||n==="$inferSelect")continue;let o=r;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(n);}return e}function Te(a,e){if(e.size===0)return a;let t=a.shape,n={};for(let[r,o]of Object.entries(t))if(e.has(r)){let s=o.isOptional?.()??false,i=o.isNullable?.()??false,l=wt;(i||s)&&(l=Et),s&&(l=l.optional()),n[r]=l;}else n[r]=o;return z$1.object(n)}var In={CreateEndpoint:q,ListEndpoint:K,ReadEndpoint:U,UpdateEndpoint:A,DeleteEndpoint:Z,RestoreEndpoint:F,BatchCreateEndpoint:L,BatchUpdateEndpoint:N,BatchDeleteEndpoint:$,BatchRestoreEndpoint:Q,BatchUpsertEndpoint:_,SearchEndpoint:I,AggregateEndpoint:G,ExportEndpoint:H,ImportEndpoint:J,UpsertEndpoint:j,CloneEndpoint:ee};export{Ke as DRIZZLE_DIALECTS,In as DrizzleAdapters,G as DrizzleAggregateEndpoint,L as DrizzleBatchCreateEndpoint,$ as DrizzleBatchDeleteEndpoint,Q as DrizzleBatchRestoreEndpoint,N as DrizzleBatchUpdateEndpoint,_ as DrizzleBatchUpsertEndpoint,ee as DrizzleCloneEndpoint,q as DrizzleCreateEndpoint,Z as DrizzleDeleteEndpoint,H as DrizzleExportEndpoint,J 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,B as batchLoadDrizzleRelations,O as buildWhereCondition,Y as cast,hn as createDrizzleCrud,Ct as createDrizzleSchemas,ft as createInsertSchema,Dt as createSelectSchema,yt as createUpdateSchema,h as getColumn,D as getTable,Mt as isDrizzleZodAvailable,ue as loadDrizzleRelation,de as loadDrizzleRelations,k as readCount,te as substringMatch};
4
+ 3. Use factory: createDrizzleCrud(db, meta)`)}function ee(o,e,t){switch(t){case "pg":return sql`POSITION(LOWER(${e}) IN LOWER(${o})) > 0`;case "mysql":return sql`LOCATE(LOWER(${e}), LOWER(${o})) > 0`;default:return sql`INSTR(LOWER(${o}), LOWER(${e})) > 0`}}function at(o){return o.split(/\s+/).filter(e=>e.length>0)}var j=class extends UpsertEndpoint{db;dialect="sqlite";getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async findExisting(e){let t=this.getTable(),n=this.getUpsertKeys(),r=this.getSoftDeleteConfig(),i=[];for(let s of n){let l=e[s];l!==void 0&&i.push(eq(this.getColumn(s),l));}return r.enabled&&i.push(isNull(this.getColumn(r.field))),i.length===0?null:(await this.getDb().select().from(t).where(m(...i)).limit(1))[0]||null}async create(e){let t=this.getTable(),n=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(n).returning())[0]}async update(e,t){let n=this.getTable(),r=this._meta.model.primaryKeys[0],i=e[r];return (await this.getDb().update(n).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(r),i)).returning())[0]}async nativeUpsert(e,t){let n=this.getTable(),r=this.getUpsertKeys(),i=this._meta.model.primaryKeys[0],a=this.getSoftDeleteConfig(),s=this.getTimestampsConfig(),l=this.applyManagedInsertFields(e,"drizzle"),d={};for(let[g,C]of Object.entries(e))!r.includes(g)&&g!==i&&(this.createOnlyFields?.includes(g)||(d[g]=C));s.enabled&&(d[s.updatedAt]=Date.now());let u=r.map(g=>this.getColumn(g)),c;a.enabled&&(c=isNull(this.getColumn(a.field)));let b=Object.keys(d).length>0?d:{[i]:sql`${this.getColumn(i)}`},M=this.getDb().insert(n).values(l);return this.dialect==="mysql"?{data:(await M.onDuplicateKeyUpdate({set:b}).returning())[0],created:false}:{data:(await M.onConflictDoUpdate({target:u,set:b,where:c}).returning())[0],created:false}}},_=class extends BatchUpsertEndpoint{db;dialect="sqlite";getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async findExisting(e){let t=this.getTable(),n=this.getUpsertKeys(),r=[];for(let a of n){let s=e[a];s!==void 0&&r.push(eq(this.getColumn(a),s));}return r.length===0?null:(await this.getDb().select().from(t).where(m(...r)).limit(1))[0]||null}async create(e){let t=this.getTable(),n=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(n).returning())[0]}async update(e,t){let n=this.getTable(),r=this._meta.model.primaryKeys[0],i=e[r];return (await this.getDb().update(n).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(r),i)).returning())[0]}async nativeBatchUpsert(e,t){if(e.length===0)return {items:[],createdCount:0,updatedCount:0,totalCount:0};let n=this.getTable(),r=this.getUpsertKeys(),i=this._meta.model.primaryKeys[0],a=this.getTimestampsConfig(),s=e.map(z=>this.applyManagedInsertFields(z,"drizzle")),l={},d=e[0];for(let z of Object.keys(d))!r.includes(z)&&z!==i&&(this.createOnlyFields?.includes(z)||(l[z]=sql`excluded.${sql.identifier(z)}`));a.enabled&&(l[a.updatedAt]=Date.now());let u=r.map(z=>this.getColumn(z)),c=Object.keys(l).length>0?l:{[i]:sql`${this.getColumn(i)}`},b=this.getDb().insert(n).values(s),M=await(this.dialect==="mysql"?b.onDuplicateKeyUpdate({set:c}):b.onConflictDoUpdate({target:u,set:c})).returning();return {items:M.map((z,g)=>({data:z,created:false,index:g})),createdCount:0,updatedCount:M.length,totalCount:M.length}}},ue=class extends VersionHistoryEndpoint{db;getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async recordExists(e){let t=this.getTable(),n=await this.getDb().select({count:sql`count(*)`}).from(t).where(eq(this.getColumn("id"),e));return O(n)>0}},pe=class extends VersionReadEndpoint{},ge=class extends VersionCompareEndpoint{},me=class extends VersionRollbackEndpoint{db;getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async rollback(e,t,n){let r=this.getTable(),i=this.getVersioningConfig().field;return (await this.getDb().update(r).set({...t,[i]:n}).where(eq(this.getColumn("id"),e)).returning())[0]}},Y=class extends AggregateEndpoint{db;getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async aggregate(e){let t=this.getTable(),n=[],r=this.getSoftDeleteConfig();if(r.enabled){let{query:s}=await this.getValidatedData();s?.withDeleted===true||s?.withDeleted==="true"||n.push(isNull(this.getColumn(r.field)));}if(e.filters)for(let[s,l]of Object.entries(e.filters))if(typeof l=="object"&&l!==null)for(let[d,u]of Object.entries(l)){if(!isFilterOperator(d)){n.push(sql`1 = 0`);continue}let c=k(t,{field:s,operator:d,value:u});c&&n.push(c);}else n.push(eq(this.getColumn(s),l));let i=n.length>0?m(...n):void 0,a=await this.getDb().select().from(t).where(i);return computeAggregations(a,e)}},I=class extends SearchEndpoint{db;dialect="sqlite";getDb(){return f(this)}useNativeSearch=false;vectorColumn;vectorConfig="english";getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async search(e,t){let n=this.getTable(),r=[],i=this.getSoftDeleteConfig();i.enabled&&(t.options.onlyDeleted?r.push(isNotNull(this.getColumn(i.field))):t.options.withDeleted||r.push(isNull(this.getColumn(i.field))));for(let E of t.filters){let y=k(n,E);y&&r.push(y);}let a=this.getSearchableFields(),s=e.fields||Object.keys(a);if(this.useNativeSearch&&this.vectorColumn){let E=this.getColumn(this.vectorColumn),y=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(" | ")})`;r.push(sql`${E} @@ ${y}`);}else {let E=(y,x)=>{try{let se=this.getColumn(y);return ee(sql`CAST(${se} AS TEXT)`,x,this.dialect)}catch{return}};if(e.mode==="all"){let y=at(e.query);if(y.length>0){let x=[];for(let se of y){let de=s.map(ie=>E(ie,se)).filter(ie=>ie!==void 0);de.length>0&&x.push(S(...de));}x.length>0&&r.push(m(...x));}}else {let y=s.map(x=>E(x,e.query)).filter(x=>x!==void 0);y.length>0&&r.push(S(...y));}}let l=r.length>0?m(...r):void 0,d=await this.getDb().select({count:sql`count(*)`}).from(n).where(l),u=O(d),c=this.getDb().select().from(n).where(l);if(t.options.order_by){let E=this.getColumn(t.options.order_by),y=t.options.order_by_direction==="desc"?desc:asc;c=c.orderBy(y(E));}let b=t.options.page||1,M=t.options.per_page||this.defaultPerPage;c=c.limit(M).offset((b-1)*M);let z=await c,g=e.mode==="all"?{...e,mode:"any"}:e,C=searchInMemory(z,g,a),R={relations:t.options.include||[]},W=C.map(E=>E.item),oe=await B(this.getDb(),W,this._meta,R);return {items:C.map((E,y)=>({...E,item:oe[y]})),totalCount:u}}},G=class extends ExportEndpoint{db;dialect="sqlite";getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async list(e){let t=this.getTable(),n=[],r=this.getSoftDeleteConfig();if(r.enabled){let g=this.getColumn(r.field);e.options.onlyDeleted?n.push(isNotNull(g)):e.options.withDeleted||n.push(isNull(g));}for(let g of e.filters){let C=k(t,g);C&&n.push(C);}if(e.options.search&&this.searchFields.length>0){let g=e.options.search,C=this.searchFields.map(R=>{let W=this.getColumn(R);return ee(W,g,this.dialect)});n.push(S(...C));}let i=n.length>0?m(...n):void 0,a=await this.getDb().select({count:sql`count(*)`}).from(t).where(i),s=O(a),l=this.getDb().select().from(t).where(i);if(e.options.order_by){let g=this.getColumn(e.options.order_by),C=e.options.order_by_direction==="desc"?desc:asc;l=l.orderBy(C(g));}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,b={relations:e.options.include||[]},M=await B(this.getDb(),c,this._meta,b),z=Math.ceil(s/u);return {result:M,result_info:{page:d,per_page:u,total_count:s,total_pages:z,has_next_page:d<z,has_prev_page:d>1}}}},H=class extends ImportEndpoint{db;getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async findExisting(e){let t=this.getTable(),n=this.getUpsertKeys(),r=this.getSoftDeleteConfig(),i=[];for(let s of n){let l=e[s];l!==void 0&&i.push(eq(this.getColumn(s),l));}return r.enabled&&i.push(isNull(this.getColumn(r.field))),i.length===0?null:(await this.getDb().select().from(t).where(m(...i)).limit(1))[0]||null}async create(e){let t=this.getTable(),n=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(n).returning())[0]}async update(e,t){let n=this.getTable(),r=this._meta.model.primaryKeys[0],i=e[r];return (await this.getDb().update(n).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(r),i)).returning())[0]}},J=class extends CloneEndpoint{db;getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}generateId(){return crypto.randomUUID()}async findSource(e,t){let n=this.getTable(),r=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),a=[eq(r,e)];if(t)for(let[l,d]of Object.entries(t))a.push(eq(this.getColumn(l),d));i.enabled&&a.push(isNull(this.getColumn(i.field)));let s=await this.getDb().select().from(n).where(m(...a)).limit(1);return s[0]?s[0]:null}async createClone(e){let t=this.getTable(),n=this.applyManagedInsertFields(e,"drizzle",()=>this.generateId());return (await this.getDb().insert(t).values(n).returning())[0]}};var A=class extends CreateEndpoint{db;useTransaction=false;getDb(){return f(this)}getTable(){return h(this._meta)}getRelatedTable(e){return e.table}async create(e,t){let n=t??this.getDb(),r=this.getTable(),i=this.applyManagedInsertFields(e,"drizzle");return (await n.insert(r).values(i).returning())[0]}async createNested(e,t,n,r,i){let a=i??this.getDb(),s=this.getRelatedTable(n);if(!s)return getLogger().warn(`Related table not found for ${t}. Add 'table' to the relation config.`),[];let l=Array.isArray(r)?r:[r],d=[];for(let u of l){if(typeof u!="object"||u===null)continue;let c={...u,id:crypto.randomUUID(),[n.foreignKey]:e},b=await a.insert(s).values(c).returning();b[0]&&d.push(b[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()}},q=class extends ReadEndpoint{db;getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async read(e,t,n){let r=this.getTable(),i=this.getColumn(this.lookupField),a=this.getSoftDeleteConfig(),s=[eq(i,e)];if(t)for(let[u,c]of Object.entries(t))s.push(eq(this.getColumn(u),c));a.enabled&&s.push(isNull(this.getColumn(a.field)));let l=await this.getDb().select().from(r).where(m(...s)).limit(1);return l[0]?await le(this.getDb(),l[0],this._meta,n):null}},U=class extends UpdateEndpoint{db;useTransaction=false;getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}getRelatedTable(e){return e.table}async findExisting(e,t,n){let r=n??this.getDb(),i=this.getTable(),a=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),l=[eq(a,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return s.enabled&&l.push(isNull(this.getColumn(s.field))),(await r.select().from(i).where(m(...l)).limit(1))[0]||null}async update(e,t,n,r){let i=r??this.getDb(),a=this.getTable(),s=this.getColumn(this.lookupField),l=this.getSoftDeleteConfig(),d=[eq(s,e)];if(n)for(let[c,b]of Object.entries(n))d.push(eq(this.getColumn(c),b));return l.enabled&&d.push(isNull(this.getColumn(l.field))),(await i.update(a).set(this.applyManagedUpdateFields(t)).where(m(...d)).returning())[0]||null}async processNestedWrites(e,t,n,r,i){let a=i??this.getDb(),s=this.getRelatedTable(n);if(!s)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=p(s,n.foreignKey),u=p(s,"id");if(r.create){let c=Array.isArray(r.create)?r.create:[r.create];for(let b of c){if(typeof b!="object"||b===null)continue;let M={...b,id:crypto.randomUUID(),[n.foreignKey]:e},z=await a.insert(s).values(M).returning();z[0]&&l.created.push(z[0]);}}if(r.update)for(let c of r.update){if(!c.id||!(await a.select().from(s).where(m(eq(u,c.id),eq(d,e))).limit(1))[0])continue;let{id:M,...z}=c,g=await a.update(s).set(z).where(eq(u,M)).returning();g[0]&&l.updated.push(g[0]);}if(r.delete)for(let c of r.delete)(await a.delete(s).where(m(eq(u,c),eq(d,e))).returning())[0]&&l.deleted.push(c);if(r.connect)for(let c of r.connect)(await a.update(s).set({[n.foreignKey]:e}).where(eq(u,c)).returning())[0]&&l.connected.push(c);if(r.disconnect)for(let c of r.disconnect)(await a.update(s).set({[n.foreignKey]:null}).where(m(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 f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}getRelatedTable(e){return e.table}async findForDelete(e,t,n){let r=n??this.getDb(),i=this.getTable(),a=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),l=[eq(a,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return s.enabled&&l.push(isNull(this.getColumn(s.field))),(await r.select().from(i).where(m(...l)).limit(1))[0]||null}async delete(e,t,n){let r=n??this.getDb(),i=this.getTable(),a=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),l=[eq(a,e)];if(t)for(let[d,u]of Object.entries(t))l.push(eq(this.getColumn(d),u));return s.enabled&&l.push(isNull(this.getColumn(s.field))),s.enabled?(await r.update(i).set({[s.field]:new Date}).where(m(...l)).returning())[0]||null:(await r.delete(i).where(m(...l)).returning())[0]||null}async countRelated(e,t,n,r){let i=r??this.getDb(),a=this.getRelatedTable(n);if(!a)return 0;let s=p(a,n.foreignKey),l=await i.select({count:sql`count(*)`}).from(a).where(eq(s,e));return O(l)}async deleteRelated(e,t,n,r){let i=r??this.getDb(),a=this.getRelatedTable(n);if(!a)return 0;let s=p(a,n.foreignKey);return (await i.delete(a).where(eq(s,e)).returning()).length}async nullifyRelated(e,t,n,r){let i=r??this.getDb(),a=this.getRelatedTable(n);if(!a)return 0;let s=p(a,n.foreignKey);return (await i.update(a).set({[n.foreignKey]:null}).where(eq(s,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()}},F=class extends ListEndpoint{db;dialect="sqlite";getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async list(e){let t=this.getTable(),n=[],r=this.getSoftDeleteConfig();if(r.enabled){let C=this.getColumn(r.field);e.options.onlyDeleted?n.push(isNotNull(C)):e.options.withDeleted||n.push(isNull(C));}for(let C of e.filters){let R=k(t,C);R&&n.push(R);}if(e.options.search&&this.searchFields.length>0){let C=e.options.search,R=this.searchFields.map(W=>{let oe=this.getColumn(W);return ee(oe,C,this.dialect)});n.push(S(...R));}let i=n.length>0?m(...n):void 0,a=this.getDb(),s=await a.select({count:sql`count(*)`}).from(t).where(i),l=O(s),d=a.select().from(t).where(i);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 b=await d,M={relations:e.options.include||[]},z=await B(this.getDb(),b,this._meta,M),g=Math.ceil(l/c);return {result:z,result_info:{page:u,per_page:c,total_count:l,total_pages:g,has_next_page:u<g,has_prev_page:u>1}}}},N=class extends RestoreEndpoint{db;useTransaction=false;getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async restore(e,t,n){let r=n??this.getDb(),i=this.getTable(),a=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),l=[eq(a,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return l.push(isNotNull(this.getColumn(s.field))),(await r.update(i).set({[s.field]:null}).where(m(...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 f(this)}getTable(){return h(this._meta)}async batchCreate(e){let t=this.getTable(),n=e.map(i=>this.applyManagedInsertFields(i,"drizzle"));return await this.getDb().insert(t).values(n).returning()}},K=class extends BatchUpdateEndpoint{db;getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async batchUpdate(e){let t=this.getTable(),n=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),i=[],a=[];for(let s of e){let l=[eq(n,s.id)];r.enabled&&l.push(isNull(this.getColumn(r.field)));let d=await this.getDb().update(t).set(this.applyManagedUpdateFields(s.data)).where(m(...l)).returning();d[0]?i.push(d[0]):a.push(s.id);}return {updated:i,notFound:a}}},$=class extends BatchDeleteEndpoint{db;getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async batchDelete(e){let t=this.getTable(),n=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),i=[inArray(n,e)];r.enabled&&i.push(isNull(this.getColumn(r.field)));let a;r.enabled?a=await this.getDb().update(t).set({[r.field]:new Date}).where(m(...i)).returning():a=await this.getDb().delete(t).where(m(...i)).returning();let s=a,l=new Set(s.map(u=>String(u[this.lookupField]))),d=e.filter(u=>!l.has(u));return {deleted:s,notFound:d}}},Q=class extends BatchRestoreEndpoint{db;getDb(){return f(this)}getTable(){return h(this._meta)}getColumn(e){return p(this.getTable(),e)}async batchRestore(e){let t=this.getTable(),n=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),i=[inArray(n,e),isNotNull(this.getColumn(r.field))],s=await this.getDb().update(t).set({[r.field]:null}).where(m(...i)).returning(),l=new Set(s.map(u=>String(u[this.lookupField]))),d=e.filter(u=>!l.has(u));return {restored:s,notFound:d}}};function fn(o,e,t){let n=t?.dialect??"sqlite";return {Create:class extends A{_meta=e;db=o},Read:class extends q{_meta=e;db=o},Update:class extends U{_meta=e;db=o},Delete:class extends Z{_meta=e;db=o},List:class extends F{_meta=e;db=o;dialect=n},Restore:class extends N{_meta=e;db=o},Upsert:class extends j{_meta=e;db=o;dialect=n},Search:class extends I{_meta=e;db=o;dialect=n},BatchCreate:class extends L{_meta=e;db=o},BatchUpdate:class extends K{_meta=e;db=o},BatchDelete:class extends ${_meta=e;db=o},BatchRestore:class extends Q{_meta=e;db=o},BatchUpsert:class extends _{_meta=e;db=o;dialect=n}}}var ne=null,we=false,te=null;async function re(){if(we){if(te)throw te;return ne}we=true;try{return ne=await import('drizzle-zod'),ne}catch{throw te=new Error("drizzle-zod is not installed. Please install it: npm install drizzle-zod"),te}}async function yt(o,e){return (await re()).createSelectSchema(o,e)}async function wt(o,e){return (await re()).createInsertSchema(o,e)}async function Et(o,e){let t=await re();return t.createUpdateSchema?t.createUpdateSchema(o,e):t.createInsertSchema(o,e).partial()}async function Tt(o,e){let t=await re(),n=e?.coerceDates!==false,r=n?kt(o):new Set,i=t.createSelectSchema(o,e?.selectRefine),a=t.createInsertSchema(o,e?.insertRefine),s;return t.createUpdateSchema?s=t.createUpdateSchema(o,e?.updateRefine):s=t.createInsertSchema(o,e?.updateRefine).partial(),n&&r.size>0&&(a=Ee(a,r),s=Ee(s,r)),{select:i,insert:a,update:s}}function Rt(){return ne!==null}var xt=z.preprocess(o=>{if(o instanceof Date)return o;if(typeof o=="string"){let e=new Date(o);if(!isNaN(e.getTime()))return e}return o},z.date()),Ot=z.preprocess(o=>{if(o==null)return null;if(o instanceof Date)return o;if(typeof o=="string"){let e=new Date(o);if(!isNaN(e.getTime()))return e}return o},z.date().nullable());function kt(o){let e=new Set,t=o;for(let[n,r]of Object.entries(t)){if(n==="_"||n==="$inferInsert"||n==="$inferSelect")continue;let i=r;if(!i||typeof i!="object")continue;let a=String(i.dataType??"").toLowerCase(),s=String(i.columnType??"").toLowerCase(),l=i.config,d=String(l?.dataType??"").toLowerCase();(a.includes("timestamp")||a.includes("date")||a.includes("datetime")||s.includes("pgtimestamp")||s.includes("pgdate")||s.includes("mysqltimestamp")||s.includes("mysqldate")||s.includes("sqlitetimestamp")||d.includes("timestamp")||d.includes("date"))&&e.add(n);}return e}function Ee(o,e){if(e.size===0)return o;let t=o.shape,n={};for(let[r,i]of Object.entries(t))if(e.has(r)){let a=i.isOptional?.()??false,s=i.isNullable?.()??false,l=xt;(s||a)&&(l=Ot),a&&(l=l.optional()),n[r]=l;}else n[r]=i;return z.object(n)}var Un={CreateEndpoint:A,ListEndpoint:F,ReadEndpoint:q,UpdateEndpoint:U,DeleteEndpoint:Z,RestoreEndpoint:N,BatchCreateEndpoint:L,BatchUpdateEndpoint:K,BatchDeleteEndpoint:$,BatchRestoreEndpoint:Q,BatchUpsertEndpoint:_,SearchEndpoint:I,AggregateEndpoint:Y,ExportEndpoint:G,ImportEndpoint:H,UpsertEndpoint:j,CloneEndpoint:J};export{Ke as DRIZZLE_DIALECTS,Un as DrizzleAdapters,Y as DrizzleAggregateEndpoint,L as DrizzleBatchCreateEndpoint,$ as DrizzleBatchDeleteEndpoint,Q as DrizzleBatchRestoreEndpoint,K as DrizzleBatchUpdateEndpoint,_ as DrizzleBatchUpsertEndpoint,J as DrizzleCloneEndpoint,A as DrizzleCreateEndpoint,Z as DrizzleDeleteEndpoint,G as DrizzleExportEndpoint,H as DrizzleImportEndpoint,F as DrizzleListEndpoint,q as DrizzleReadEndpoint,N as DrizzleRestoreEndpoint,I as DrizzleSearchEndpoint,U as DrizzleUpdateEndpoint,j as DrizzleUpsertEndpoint,ge as DrizzleVersionCompareEndpoint,ue as DrizzleVersionHistoryEndpoint,pe as DrizzleVersionReadEndpoint,me as DrizzleVersionRollbackEndpoint,B as batchLoadDrizzleRelations,k as buildWhereCondition,X as cast,fn as createDrizzleCrud,Tt as createDrizzleSchemas,wt as createInsertSchema,yt as createSelectSchema,Et as createUpdateSchema,p as getColumn,h as getTable,Rt as isDrizzleZodAvailable,$e as loadDrizzleRelation,le as loadDrizzleRelations,O as readCount,ee as substringMatch};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hono-crud/drizzle",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Drizzle ORM CRUD adapter for hono-crud",
5
5
  "author": "Kauan Guesser <contato@kauan.net>",
6
6
  "license": "MIT",
@@ -43,7 +43,7 @@
43
43
  "access": "public"
44
44
  },
45
45
  "dependencies": {
46
- "hono-crud": "0.13.10"
46
+ "hono-crud": "0.13.11"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "drizzle-orm": ">=0.30.0",