@hono-crud/drizzle 0.1.14 → 0.1.15

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,23 @@
1
1
  # @hono-crud/drizzle
2
2
 
3
+ ## 0.1.15
4
+
5
+ ### Patch Changes
6
+
7
+ - 26a6ecf: fix(security): scope batch verbs to the caller's tenant
8
+
9
+ `batchDelete`, `batchUpdate`, and `batchRestore` operated on a client-supplied
10
+ id list without applying the model's `multiTenant` owner filter — unlike the
11
+ single-row verbs, which get it via core-injected `additionalFilters`. A caller
12
+ could delete, update, or restore **another tenant's rows** by passing their ids.
13
+
14
+ Core now enforces tenant presence in each batch handler (`validateTenantId`,
15
+ 400 `TENANT_REQUIRED` when required), and exposes `getTenantScopeFilter()` which
16
+ each adapter ANDs into its batch WHERE (drizzle/memory) or `findMany` lookup
17
+ (prisma). Cross-tenant ids now fall through to `notFound`; the row is untouched.
18
+
19
+ Covered by a new cross-adapter conformance cell (`batch-tenant-scoping`).
20
+
3
21
  ## 0.1.14
4
22
 
5
23
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import {getTableColumns,between,isNull,isNotNull,notInArray,inArray,lte,lt,gte,gt,ne as ne$1,eq,sql,and,desc,asc,or}from'drizzle-orm';import {resolveRelationValueAsync,loadRelationsForItem,batchLoadRelations,assertNever,CreateEndpoint,getLogger,ReadEndpoint,UpdateEndpoint,DeleteEndpoint,ListEndpoint,buildCursorPage,RestoreEndpoint,BatchCreateEndpoint,BatchUpdateEndpoint,BatchDeleteEndpoint,BatchRestoreEndpoint,UpsertEndpoint,BatchUpsertEndpoint,BulkPatchEndpoint,VersionHistoryEndpoint,VersionReadEndpoint,VersionCompareEndpoint,VersionRollbackEndpoint,AggregateEndpoint,isFilterOperator,computeAggregations,SearchEndpoint,searchInMemory,ExportEndpoint,ImportEndpoint,CloneEndpoint,CONTEXT_KEYS,ConfigurationException,decodeCursor}from'hono-crud/internal';import {z as z$1}from'zod';function G(o){return o}function g(...o){return and(...o)}function J(...o){return or(...o)}var $e=["sqlite","pg","mysql"];function z(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 n=getTableColumns(o),t=n[e];if(!t)throw new Error(`Column '${e}' not found in table. Available columns: ${Object.keys(n).join(", ")}`);return t}function De(o){return {resolveRelation:e=>e.table??null,fetchRelated:(e,n,t,r)=>{let i=[inArray(p(e,n),t)];return r?.tenantField!=null&&r.tenantValue!=null&&i.push(eq(p(e,r.tenantField),r.tenantValue)),r?.excludeDeletedField!=null&&i.push(isNull(p(e,r.excludeDeletedField))),o.select().from(e).where(i.length===1?i[0]:and(...i))}}}async function Ke(o,e,n,t){let r=t.table;if(!r)return e;let i=De(o),a=await resolveRelationValueAsync(e,t,r,i.fetchRelated);return {...e,[n]:a}}async function he(o,e,n,t){return loadRelationsForItem(e,n,De(o),t)}async function v(o,e,n,t){return batchLoadRelations(e,n,De(o),t)}function W(o,e,n="sqlite"){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 B(t,String(e.value).replace(/%/g,""),n,{caseSensitive:true});case "ilike":return B(t,String(e.value).replace(/%/g,""),n);case "null":return e.value?isNull(t):isNotNull(t);case "between":{let[r,i]=e.value;return between(t,r,i)}default:return assertNever(e.operator)}}function S(o){return Number(o[0]?.count)||0}async function V(o){let{db:e,table:n,filters:t,dialect:r,searchFields:i=[],softDeleteConfig:a,defaultPerPage:s=20,extraConditions:l=[],cursorField:d}=o,c=[];if(a?.enabled){let y=p(n,a.field);t.options.onlyDeleted?c.push(isNotNull(y)):t.options.withDeleted||c.push(isNull(y));}for(let y of t.filters){let k=W(n,y,r);k&&c.push(k);}if(t.options.search&&i.length>0){let y=t.options.search,k=i.map(ke=>B(p(n,ke),y,r));c.push(J(...k));}c.push(...l);let u=c.length>0?g(...c):void 0,D=await e.select({count:sql`count(*)`}).from(n).where(u),f=S(D),h=d!==void 0&&(t.options.cursor!==void 0||t.options.limit!==void 0),C=u,w=false;if(h&&t.options.cursor){let y=decodeCursor(t.options.cursor);y!==null&&(C=g(u,gt(p(n,d),y)),w=true);}let M=e.select().from(n).where(C);if(t.options.order_by){let y=p(n,t.options.order_by),k=t.options.order_by_direction==="desc"?desc:asc;M=M.orderBy(k(y));}if(h){let y=t.options.limit||t.options.per_page||s;return {records:await M.limit(y+1),totalCount:f,page:0,perPage:y,totalPages:0,cursor:{limit:y,applied:w}}}let E=t.options.page||1,T=t.options.per_page||s,Y=await M.limit(T).offset((E-1)*T),Q=Math.ceil(f/T);return {records:Y,totalCount:f,page:E,perPage:T,totalPages:Q}}function ee(o,e){return {result:o,result_info:{page:e.page,per_page:e.perPage,total_count:e.totalCount,total_pages:e.totalPages,has_next_page:e.page<e.totalPages,has_prev_page:e.page>1}}}async function te(o,e,n,t,r){let i=[];for(let s of r){let l=t[s];l!==void 0&&i.push(eq(n(s),l));}return i.length===0?null:(await o.select().from(e).where(g(...i)).limit(1))[0]||null}function B(o,e,n,t){if(t?.caseSensitive)switch(n){case "pg":return sql`POSITION(${e} IN ${o}) > 0`;case "mysql":return sql`LOCATE(${e}, ${o}) > 0`;default:return sql`INSTR(${o}, ${e}) > 0`}switch(n){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 m(o){let e=o;if(e._tx)return e._tx;if(e.db)return e.db;let n=e.context?.get?.(CONTEXT_KEYS.db);if(n)return n;throw new ConfigurationException(`Database not configured. Either:
1
+ import {getTableColumns,between,isNull,isNotNull,notInArray,inArray,lte,lt,gte,gt,ne,eq,sql,and,desc,asc,or}from'drizzle-orm';import {resolveRelationValueAsync,loadRelationsForItem,batchLoadRelations,assertNever,CreateEndpoint,getLogger,ReadEndpoint,UpdateEndpoint,DeleteEndpoint,ListEndpoint,buildCursorPage,RestoreEndpoint,BatchCreateEndpoint,BatchUpdateEndpoint,BatchDeleteEndpoint,BatchRestoreEndpoint,UpsertEndpoint,BatchUpsertEndpoint,BulkPatchEndpoint,VersionHistoryEndpoint,VersionReadEndpoint,VersionCompareEndpoint,VersionRollbackEndpoint,AggregateEndpoint,isFilterOperator,computeAggregations,SearchEndpoint,searchInMemory,ExportEndpoint,ImportEndpoint,CloneEndpoint,CONTEXT_KEYS,ConfigurationException,decodeCursor}from'hono-crud/internal';import {z as z$1}from'zod';function G(o){return o}function g(...o){return and(...o)}function J(...o){return or(...o)}var Ke=["sqlite","pg","mysql"];function z(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 n=getTableColumns(o),t=n[e];if(!t)throw new Error(`Column '${e}' not found in table. Available columns: ${Object.keys(n).join(", ")}`);return t}function he(o){return {resolveRelation:e=>e.table??null,fetchRelated:(e,n,t,r)=>{let i=[inArray(p(e,n),t)];return r?.tenantField!=null&&r.tenantValue!=null&&i.push(eq(p(e,r.tenantField),r.tenantValue)),r?.excludeDeletedField!=null&&i.push(isNull(p(e,r.excludeDeletedField))),o.select().from(e).where(i.length===1?i[0]:and(...i))}}}async function Qe(o,e,n,t){let r=t.table;if(!r)return e;let i=he(o),s=await resolveRelationValueAsync(e,t,r,i.fetchRelated);return {...e,[n]:s}}async function fe(o,e,n,t){return loadRelationsForItem(e,n,he(o),t)}async function v(o,e,n,t){return batchLoadRelations(e,n,he(o),t)}function W(o,e,n="sqlite"){let t=p(o,e.field);switch(e.operator){case "eq":return eq(t,e.value);case "ne":return ne(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 B(t,String(e.value).replace(/%/g,""),n,{caseSensitive:true});case "ilike":return B(t,String(e.value).replace(/%/g,""),n);case "null":return e.value?isNull(t):isNotNull(t);case "between":{let[r,i]=e.value;return between(t,r,i)}default:return assertNever(e.operator)}}function S(o){return Number(o[0]?.count)||0}async function V(o){let{db:e,table:n,filters:t,dialect:r,searchFields:i=[],softDeleteConfig:s,defaultPerPage:a=20,extraConditions:l=[],cursorField:c}=o,u=[];if(s?.enabled){let y=p(n,s.field);t.options.onlyDeleted?u.push(isNotNull(y)):t.options.withDeleted||u.push(isNull(y));}for(let y of t.filters){let k=W(n,y,r);k&&u.push(k);}if(t.options.search&&i.length>0){let y=t.options.search,k=i.map(Oe=>B(p(n,Oe),y,r));u.push(J(...k));}u.push(...l);let d=u.length>0?g(...u):void 0,D=await e.select({count:sql`count(*)`}).from(n).where(d),f=S(D),h=c!==void 0&&(t.options.cursor!==void 0||t.options.limit!==void 0),C=d,w=false;if(h&&t.options.cursor){let y=decodeCursor(t.options.cursor);y!==null&&(C=g(d,gt(p(n,c),y)),w=true);}let M=e.select().from(n).where(C);if(t.options.order_by){let y=p(n,t.options.order_by),k=t.options.order_by_direction==="desc"?desc:asc;M=M.orderBy(k(y));}if(h){let y=t.options.limit||t.options.per_page||a;return {records:await M.limit(y+1),totalCount:f,page:0,perPage:y,totalPages:0,cursor:{limit:y,applied:w}}}let E=t.options.page||1,T=t.options.per_page||a,Y=await M.limit(T).offset((E-1)*T),Q=Math.ceil(f/T);return {records:Y,totalCount:f,page:E,perPage:T,totalPages:Q}}function ee(o,e){return {result:o,result_info:{page:e.page,per_page:e.perPage,total_count:e.totalCount,total_pages:e.totalPages,has_next_page:e.page<e.totalPages,has_prev_page:e.page>1}}}async function te(o,e,n,t,r){let i=[];for(let a of r){let l=t[a];l!==void 0&&i.push(eq(n(a),l));}return i.length===0?null:(await o.select().from(e).where(g(...i)).limit(1))[0]||null}function B(o,e,n,t){if(t?.caseSensitive)switch(n){case "pg":return sql`POSITION(${e} IN ${o}) > 0`;case "mysql":return sql`LOCATE(${e}, ${o}) > 0`;default:return sql`INSTR(${o}, ${e}) > 0`}switch(n){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 m(o){let e=o;if(e._tx)return e._tx;if(e.db)return e.db;let n=e.context?.get?.(CONTEXT_KEYS.db);if(n)return n;throw new ConfigurationException(`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)`)}var j=class extends CreateEndpoint{db;useTransaction=false;getDb(){return m(this)}getTable(){return z(this._meta)}getRelatedTable(e){return e.table}async create(e,n){let t=n??this.getDb(),r=this.getTable(),i=this.applyManagedInsertFields(e,"drizzle");return (await t.insert(r).values(i).returning())[0]}async createNested(e,n,t,r,i){let a=i??this.getDb(),s=this.getRelatedTable(t);if(!s)return getLogger().warn(`Related table not found for ${n}. Add 'table' to the relation config.`),[];let l=Array.isArray(r)?r:[r],d=[];for(let c of l){if(typeof c!="object"||c===null)continue;let u={...c,id:crypto.randomUUID(),[t.foreignKey]:e},D=await a.insert(s).values(u).returning();D[0]&&d.push(D[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()}},P=class extends ReadEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async read(e,n,t){let r=this.getTable(),i=this.getColumn(this.lookupField),a=this.getSoftDeleteConfig(),s=[eq(i,e)];if(n)for(let[c,u]of Object.entries(n))s.push(eq(this.getColumn(c),u));a.enabled&&s.push(isNull(this.getColumn(a.field)));let l=await this.getDb().select().from(r).where(g(...s)).limit(1);return l[0]?await he(this.getDb(),l[0],this._meta,t):null}},I=class extends UpdateEndpoint{db;useTransaction=false;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}getRelatedTable(e){return e.table}async findExisting(e,n,t){let r=t??this.getDb(),i=this.getTable(),a=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),l=[eq(a,e)];if(n)for(let[c,u]of Object.entries(n))l.push(eq(this.getColumn(c),u));return s.enabled&&l.push(isNull(this.getColumn(s.field))),(await r.select().from(i).where(g(...l)).limit(1))[0]||null}async update(e,n,t,r){let i=r??this.getDb(),a=this.getTable(),s=this.getColumn(this.lookupField),l=this.getSoftDeleteConfig(),d=[eq(s,e)];if(t)for(let[u,D]of Object.entries(t))d.push(eq(this.getColumn(u),D));return l.enabled&&d.push(isNull(this.getColumn(l.field))),(await i.update(a).set(this.applyManagedUpdateFields(n)).where(g(...d)).returning())[0]||null}async processNestedWrites(e,n,t,r,i){let a=i??this.getDb(),s=this.getRelatedTable(t);if(!s)return getLogger().warn(`Related table not found for ${n}. Add 'table' to the relation config.`),{created:[],updated:[],deleted:[],connected:[],disconnected:[]};let l={created:[],updated:[],deleted:[],connected:[],disconnected:[]},d=p(s,t.foreignKey),c=p(s,"id");if(r.create){let u=Array.isArray(r.create)?r.create:[r.create];for(let D of u){if(typeof D!="object"||D===null)continue;let f={...D,id:crypto.randomUUID(),[t.foreignKey]:e},h=await a.insert(s).values(f).returning();h[0]&&l.created.push(h[0]);}}if(r.update)for(let u of r.update){if(!u.id||!(await a.select().from(s).where(g(eq(c,u.id),eq(d,e))).limit(1))[0])continue;let{id:f,...h}=u,C=await a.update(s).set(h).where(eq(c,f)).returning();C[0]&&l.updated.push(C[0]);}if(r.delete)for(let u of r.delete)(await a.delete(s).where(g(eq(c,u),eq(d,e))).returning())[0]&&l.deleted.push(u);if(r.connect)for(let u of r.connect)(await a.update(s).set({[t.foreignKey]:e}).where(eq(c,u)).returning())[0]&&l.connected.push(u);if(r.disconnect)for(let u of r.disconnect)(await a.update(s).set({[t.foreignKey]:null}).where(g(eq(c,u),eq(d,e))).returning())[0]&&l.disconnected.push(u);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()}},_=class extends DeleteEndpoint{db;useTransaction=false;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}getRelatedTable(e){return e.table}async findForDelete(e,n,t){let r=t??this.getDb(),i=this.getTable(),a=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),l=[eq(a,e)];if(n)for(let[c,u]of Object.entries(n))l.push(eq(this.getColumn(c),u));return s.enabled&&l.push(isNull(this.getColumn(s.field))),(await r.select().from(i).where(g(...l)).limit(1))[0]||null}async delete(e,n,t){let r=t??this.getDb(),i=this.getTable(),a=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),l=[eq(a,e)];if(n)for(let[d,c]of Object.entries(n))l.push(eq(this.getColumn(d),c));return s.enabled&&l.push(isNull(this.getColumn(s.field))),s.enabled?(await r.update(i).set({[s.field]:new Date}).where(g(...l)).returning())[0]||null:(await r.delete(i).where(g(...l)).returning())[0]||null}async countRelated(e,n,t,r){let i=r??this.getDb(),a=this.getRelatedTable(t);if(!a)return 0;let s=p(a,t.foreignKey),l=await i.select({count:sql`count(*)`}).from(a).where(eq(s,e));return S(l)}async deleteRelated(e,n,t,r){let i=r??this.getDb(),a=this.getRelatedTable(t);if(!a)return 0;let s=p(a,t.foreignKey);return (await i.delete(a).where(eq(s,e)).returning()).length}async nullifyRelated(e,n,t,r){let i=r??this.getDb(),a=this.getRelatedTable(t);if(!a)return 0;let s=p(a,t.foreignKey);return (await i.update(a).set({[t.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()}},A=class extends ListEndpoint{db;dialect="sqlite";supportsCursorPagination=true;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async list(e){let n=await V({db:this.getDb(),table:this.getTable(),filters:e,dialect:this.dialect,searchFields:this.searchFields,softDeleteConfig:this.getSoftDeleteConfig(),defaultPerPage:this.defaultPerPage,cursorField:this.isCursorPaginationActive()?this.cursorField||"id":void 0}),t={relations:e.options.include||[],scope:this.getRelationScope(e.options.withDeleted)};if(n.cursor){let{items:i,result_info:a}=buildCursorPage({rows:n.records,limit:n.cursor.limit,totalCount:n.totalCount,cursorField:this.cursorField||"id",cursorApplied:n.cursor.applied});return {result:await v(this.getDb(),i,this._meta,t),result_info:a}}let r=await v(this.getDb(),n.records,this._meta,t);return ee(r,n)}},q=class extends RestoreEndpoint{db;useTransaction=false;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async restore(e,n,t){let r=t??this.getDb(),i=this.getTable(),a=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),l=[eq(a,e)];if(n)for(let[c,u]of Object.entries(n))l.push(eq(this.getColumn(c),u));return l.push(isNotNull(this.getColumn(s.field))),(await r.update(i).set({[s.field]:null}).where(g(...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 U=class extends BatchCreateEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}async batchCreate(e){let n=this.getTable(),t=e.map(i=>this.applyManagedInsertFields(i,"drizzle"));return await this.getDb().insert(n).values(t).returning()}},F=class extends BatchUpdateEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async batchUpdate(e){let n=this.getTable(),t=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),i=[],a=[];for(let s of e){let l=[eq(t,s.id)];r.enabled&&l.push(isNull(this.getColumn(r.field)));let d=await this.getDb().update(n).set(this.applyManagedUpdateFields(s.data)).where(g(...l)).returning();d[0]?i.push(d[0]):a.push(s.id);}return {updated:i,notFound:a}}},Z=class extends BatchDeleteEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async batchDelete(e){let n=this.getTable(),t=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),i=[inArray(t,e)];r.enabled&&i.push(isNull(this.getColumn(r.field)));let a;r.enabled?a=await this.getDb().update(n).set({[r.field]:new Date}).where(g(...i)).returning():a=await this.getDb().delete(n).where(g(...i)).returning();let s=a,l=new Set(s.map(c=>String(c[this.lookupField]))),d=e.filter(c=>!l.has(c));return {deleted:s,notFound:d}}},L=class extends BatchRestoreEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async batchRestore(e){let n=this.getTable(),t=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),i=[inArray(t,e),isNotNull(this.getColumn(r.field))],s=await this.getDb().update(n).set({[r.field]:null}).where(g(...i)).returning(),l=new Set(s.map(c=>String(c[this.lookupField]))),d=e.filter(c=>!l.has(c));return {restored:s,notFound:d}}};function Et(o){return o.split(/\s+/).filter(e=>e.length>0)}var N=class extends UpsertEndpoint{db;dialect="sqlite";getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async findExisting(e){return te(this.getDb(),this.getTable(),n=>this.getColumn(n),e,this.getUpsertKeys())}async create(e){let n=this.getTable(),t=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(n).values(t).returning())[0]}async update(e,n){let t=this.getTable(),r=this._meta.model.primaryKeys[0],i=e[r];return (await this.getDb().update(t).set(this.applyManagedUpdateFields(n)).where(eq(this.getColumn(r),i)).returning())[0]}async nativeUpsert(e,n){let t=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[C,w]of Object.entries(e))!r.includes(C)&&C!==i&&(this.createOnlyFields?.includes(C)||(d[C]=w));s.enabled&&(d[s.updatedAt]=Date.now());let c=r.map(C=>this.getColumn(C)),u;a.enabled&&(u=isNull(this.getColumn(a.field)));let D=Object.keys(d).length>0?d:{[i]:sql`${this.getColumn(i)}`},f=this.getDb().insert(t).values(l);return this.dialect==="mysql"?{data:(await f.onDuplicateKeyUpdate({set:D}).returning())[0],created:false}:{data:(await f.onConflictDoUpdate({target:c,set:D,where:u}).returning())[0],created:false}}},$=class extends BatchUpsertEndpoint{db;dialect="sqlite";getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async findExisting(e){return te(this.getDb(),this.getTable(),n=>this.getColumn(n),e,this.getUpsertKeys())}async create(e){let n=this.getTable(),t=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(n).values(t).returning())[0]}async update(e,n){let t=this.getTable(),r=this._meta.model.primaryKeys[0],i=e[r];return (await this.getDb().update(t).set(this.applyManagedUpdateFields(n)).where(eq(this.getColumn(r),i)).returning())[0]}async nativeBatchUpsert(e,n){if(e.length===0)return {items:[],createdCount:0,updatedCount:0,totalCount:0};let t=this.getTable(),r=this.getUpsertKeys(),i=this._meta.model.primaryKeys[0],a=this.getTimestampsConfig(),s=e.map(h=>this.applyManagedInsertFields(h,"drizzle")),l={},d=e[0];for(let h of Object.keys(d))!r.includes(h)&&h!==i&&(this.createOnlyFields?.includes(h)||(l[h]=sql`excluded.${sql.identifier(h)}`));a.enabled&&(l[a.updatedAt]=Date.now());let c=r.map(h=>this.getColumn(h)),u=Object.keys(l).length>0?l:{[i]:sql`${this.getColumn(i)}`},D=this.getDb().insert(t).values(s),f=await(this.dialect==="mysql"?D.onDuplicateKeyUpdate({set:u}):D.onConflictDoUpdate({target:c,set:u})).returning();return {items:f.map((h,C)=>({data:h,created:false,index:C})),createdCount:0,updatedCount:f.length,totalCount:f.length}}},ne=class extends BulkPatchEndpoint{db;dialect="sqlite";getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}buildConditions(e){let n=this.getTable(),t=[];for(let i of e.filters){let a=W(n,i,this.dialect);a&&t.push(a);}let r=this.getSoftDeleteConfig();return r.enabled&&t.push(isNull(this.getColumn(r.field))),t}async countMatching(e){let n=this.buildConditions(e),t=await this.getDb().select({count:sql`count(*)`}).from(this.getTable()).where(g(...n));return S(t)}async applyPatch(e,n){let t=this.buildConditions(n),r=await this.getDb().update(this.getTable()).set(this.applyManagedUpdateFields(e)).where(g(...t)).returning();return {updated:r.length,records:r}}},re=class extends VersionHistoryEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async recordExists(e){let n=this.getTable(),t=await this.getDb().select({count:sql`count(*)`}).from(n).where(eq(this.getColumn("id"),e));return S(t)>0}},oe=class extends VersionReadEndpoint{},ie=class extends VersionCompareEndpoint{},se=class extends VersionRollbackEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async rollback(e,n,t){let r=this.getTable(),i=this.getVersioningConfig().field;return (await this.getDb().update(r).set({...n,[i]:t}).where(eq(this.getColumn("id"),e)).returning())[0]}},ae=class extends AggregateEndpoint{db;dialect="sqlite";getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async aggregate(e){let n=this.getTable(),t=[],r=this.getSoftDeleteConfig();if(r.enabled){let{query:s}=await this.getValidatedData();s?.withDeleted===true||s?.withDeleted==="true"||t.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,c]of Object.entries(l)){if(!isFilterOperator(d)){t.push(sql`1 = 0`);continue}let u=W(n,{field:s,operator:d,value:c},this.dialect);u&&t.push(u);}else t.push(eq(this.getColumn(s),l));let i=t.length>0?g(...t):void 0,a=await this.getDb().select().from(n).where(i);return computeAggregations(a,e)}},K=class extends SearchEndpoint{db;dialect="sqlite";getDb(){return m(this)}useNativeSearch=false;vectorColumn;vectorConfig="english";getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async search(e,n){let t=this.getTable(),r=[],i=this.getSearchableFields(),a=e.fields||Object.keys(i);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(" | ")})`;r.push(sql`${w} @@ ${M}`);}else {let w=(M,E)=>{try{let T=this.getColumn(M);return B(sql`CAST(${T} AS TEXT)`,E,this.dialect)}catch{return}};if(e.mode==="all"){let M=Et(e.query);if(M.length>0){let E=[];for(let T of M){let Y=a.map(Q=>w(Q,T)).filter(Q=>Q!==void 0);Y.length>0&&E.push(J(...Y));}E.length>0&&r.push(g(...E));}}else {let M=a.map(E=>w(E,e.query)).filter(E=>E!==void 0);M.length>0&&r.push(J(...M));}}let s=await V({db:this.getDb(),table:t,filters:n,dialect:this.dialect,softDeleteConfig:this.getSoftDeleteConfig(),defaultPerPage:this.defaultPerPage,extraConditions:r}),l=s.records,d=s.totalCount,c=e.mode==="all"?{...e,mode:"any"}:e,u=searchInMemory(l,c,i),D={relations:n.options.include||[]},f=u.map(w=>w.item),h=await v(this.getDb(),f,this._meta,D);return {items:u.map((w,M)=>({...w,item:h[M]})),totalCount:d}}},le=class extends ExportEndpoint{db;dialect="sqlite";getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async list(e){let n=await V({db:this.getDb(),table:this.getTable(),filters:e,dialect:this.dialect,searchFields:this.searchFields,softDeleteConfig:this.getSoftDeleteConfig(),defaultPerPage:this.defaultPerPage}),t={relations:e.options.include||[]},r=await v(this.getDb(),n.records,this._meta,t);return ee(r,n)}},de=class extends ImportEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async findExisting(e){return te(this.getDb(),this.getTable(),n=>this.getColumn(n),e,this.getUpsertKeys())}async create(e){let n=this.getTable(),t=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(n).values(t).returning())[0]}async update(e,n){let t=this.getTable(),r=this._meta.model.primaryKeys[0],i=e[r];return (await this.getDb().update(t).set(this.applyManagedUpdateFields(n)).where(eq(this.getColumn(r),i)).returning())[0]}},ce=class extends CloneEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}generateId(){return crypto.randomUUID()}async findSource(e,n){let t=this.getTable(),r=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),a=[eq(r,e)];if(n)for(let[l,d]of Object.entries(n))a.push(eq(this.getColumn(l),d));i.enabled&&a.push(isNull(this.getColumn(i.field)));let s=await this.getDb().select().from(t).where(g(...a)).limit(1);return s[0]?s[0]:null}async createClone(e){let n=this.getTable(),t=this.applyManagedInsertFields(e,"drizzle",()=>this.generateId());return (await this.getDb().insert(n).values(t).returning())[0]}};function yn(o,e,n){let t=n?.dialect??"sqlite";return {Create:class extends j{_meta=e;db=o},Read:class extends P{_meta=e;db=o},Update:class extends I{_meta=e;db=o},Delete:class extends _{_meta=e;db=o},List:class extends A{_meta=e;db=o;dialect=t},Restore:class extends q{_meta=e;db=o},Upsert:class extends N{_meta=e;db=o;dialect=t},Search:class extends K{_meta=e;db=o;dialect=t},BatchCreate:class extends U{_meta=e;db=o},BatchUpdate:class extends F{_meta=e;db=o},BatchDelete:class extends Z{_meta=e;db=o},BatchRestore:class extends L{_meta=e;db=o},BatchUpsert:class extends ${_meta=e;db=o;dialect=t}}}var ge=null,Te=false,pe=null;async function ze(){if(Te){if(pe)throw pe;return ge}Te=true;try{return ge=await import('drizzle-zod'),ge}catch{throw pe=new Error("drizzle-zod is not installed. Please install it: npm install drizzle-zod"),pe}}async function Rt(o,e){return (await ze()).createSelectSchema(o,e)}async function Tt(o,e){return (await ze()).createInsertSchema(o,e)}async function xt(o,e){let n=await ze();return n.createUpdateSchema?n.createUpdateSchema(o,e):n.createInsertSchema(o,e).partial()}async function kt(o,e){let n=await ze(),t=e?.coerceDates!==false,r=t?Bt(o):new Set,i=n.createSelectSchema(o,e?.selectRefine),a=n.createInsertSchema(o,e?.insertRefine),s;return n.createUpdateSchema?s=n.createUpdateSchema(o,e?.updateRefine):s=n.createInsertSchema(o,e?.updateRefine).partial(),t&&r.size>0&&(a=xe(a,r),s=xe(s,r)),{select:i,insert:a,update:s}}function Ot(){return ge!==null}var vt=z$1.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$1.date()),St=z$1.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$1.date().nullable());function Bt(o){let e=new Set,n=o;for(let[t,r]of Object.entries(n)){if(t==="_"||t==="$inferInsert"||t==="$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(t);}return e}function xe(o,e){if(e.size===0)return o;let n=o.shape,t={};for(let[r,i]of Object.entries(n))if(e.has(r)){let a=i.isOptional?.()??false,s=i.isNullable?.()??false,l=vt;(s||a)&&(l=St),a&&(l=l.optional()),t[r]=l;}else t[r]=i;return z$1.object(t)}var Ln={CreateEndpoint:j,ListEndpoint:A,ReadEndpoint:P,UpdateEndpoint:I,DeleteEndpoint:_,RestoreEndpoint:q,BatchCreateEndpoint:U,BatchUpdateEndpoint:F,BatchDeleteEndpoint:Z,BatchRestoreEndpoint:L,BatchUpsertEndpoint:$,SearchEndpoint:K,AggregateEndpoint:ae,ExportEndpoint:le,ImportEndpoint:de,UpsertEndpoint:N,CloneEndpoint:ce,BulkPatchEndpoint:ne,VersionHistoryEndpoint:re,VersionReadEndpoint:oe,VersionCompareEndpoint:ie,VersionRollbackEndpoint:se};export{$e as DRIZZLE_DIALECTS,Ln as DrizzleAdapters,ae as DrizzleAggregateEndpoint,U as DrizzleBatchCreateEndpoint,Z as DrizzleBatchDeleteEndpoint,L as DrizzleBatchRestoreEndpoint,F as DrizzleBatchUpdateEndpoint,$ as DrizzleBatchUpsertEndpoint,ne as DrizzleBulkPatchEndpoint,ce as DrizzleCloneEndpoint,j as DrizzleCreateEndpoint,_ as DrizzleDeleteEndpoint,le as DrizzleExportEndpoint,de as DrizzleImportEndpoint,A as DrizzleListEndpoint,P as DrizzleReadEndpoint,q as DrizzleRestoreEndpoint,K as DrizzleSearchEndpoint,I as DrizzleUpdateEndpoint,N as DrizzleUpsertEndpoint,ie as DrizzleVersionCompareEndpoint,re as DrizzleVersionHistoryEndpoint,oe as DrizzleVersionReadEndpoint,se as DrizzleVersionRollbackEndpoint,v as batchLoadDrizzleRelations,W as buildWhereCondition,G as cast,yn as createDrizzleCrud,kt as createDrizzleSchemas,Tt as createInsertSchema,Rt as createSelectSchema,xt as createUpdateSchema,p as getColumn,z as getTable,Ot as isDrizzleZodAvailable,Ke as loadDrizzleRelation,he as loadDrizzleRelations,S as readCount,B as substringMatch};
4
+ 3. Use factory: createDrizzleCrud(db, meta)`)}var j=class extends CreateEndpoint{db;useTransaction=false;getDb(){return m(this)}getTable(){return z(this._meta)}getRelatedTable(e){return e.table}async create(e,n){let t=n??this.getDb(),r=this.getTable(),i=this.applyManagedInsertFields(e,"drizzle");return (await t.insert(r).values(i).returning())[0]}async createNested(e,n,t,r,i){let s=i??this.getDb(),a=this.getRelatedTable(t);if(!a)return getLogger().warn(`Related table not found for ${n}. Add 'table' to the relation config.`),[];let l=Array.isArray(r)?r:[r],c=[];for(let u of l){if(typeof u!="object"||u===null)continue;let d={...u,id:crypto.randomUUID(),[t.foreignKey]:e},D=await s.insert(a).values(d).returning();D[0]&&c.push(D[0]);}return c}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()}},P=class extends ReadEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async read(e,n,t){let r=this.getTable(),i=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),a=[eq(i,e)];if(n)for(let[u,d]of Object.entries(n))a.push(eq(this.getColumn(u),d));s.enabled&&a.push(isNull(this.getColumn(s.field)));let l=await this.getDb().select().from(r).where(g(...a)).limit(1);return l[0]?await fe(this.getDb(),l[0],this._meta,t):null}},I=class extends UpdateEndpoint{db;useTransaction=false;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}getRelatedTable(e){return e.table}async findExisting(e,n,t){let r=t??this.getDb(),i=this.getTable(),s=this.getColumn(this.lookupField),a=this.getSoftDeleteConfig(),l=[eq(s,e)];if(n)for(let[u,d]of Object.entries(n))l.push(eq(this.getColumn(u),d));return a.enabled&&l.push(isNull(this.getColumn(a.field))),(await r.select().from(i).where(g(...l)).limit(1))[0]||null}async update(e,n,t,r){let i=r??this.getDb(),s=this.getTable(),a=this.getColumn(this.lookupField),l=this.getSoftDeleteConfig(),c=[eq(a,e)];if(t)for(let[d,D]of Object.entries(t))c.push(eq(this.getColumn(d),D));return l.enabled&&c.push(isNull(this.getColumn(l.field))),(await i.update(s).set(this.applyManagedUpdateFields(n)).where(g(...c)).returning())[0]||null}async processNestedWrites(e,n,t,r,i){let s=i??this.getDb(),a=this.getRelatedTable(t);if(!a)return getLogger().warn(`Related table not found for ${n}. Add 'table' to the relation config.`),{created:[],updated:[],deleted:[],connected:[],disconnected:[]};let l={created:[],updated:[],deleted:[],connected:[],disconnected:[]},c=p(a,t.foreignKey),u=p(a,"id");if(r.create){let d=Array.isArray(r.create)?r.create:[r.create];for(let D of d){if(typeof D!="object"||D===null)continue;let f={...D,id:crypto.randomUUID(),[t.foreignKey]:e},h=await s.insert(a).values(f).returning();h[0]&&l.created.push(h[0]);}}if(r.update)for(let d of r.update){if(!d.id||!(await s.select().from(a).where(g(eq(u,d.id),eq(c,e))).limit(1))[0])continue;let{id:f,...h}=d,C=await s.update(a).set(h).where(eq(u,f)).returning();C[0]&&l.updated.push(C[0]);}if(r.delete)for(let d of r.delete)(await s.delete(a).where(g(eq(u,d),eq(c,e))).returning())[0]&&l.deleted.push(d);if(r.connect)for(let d of r.connect)(await s.update(a).set({[t.foreignKey]:e}).where(eq(u,d)).returning())[0]&&l.connected.push(d);if(r.disconnect)for(let d of r.disconnect)(await s.update(a).set({[t.foreignKey]:null}).where(g(eq(u,d),eq(c,e))).returning())[0]&&l.disconnected.push(d);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()}},_=class extends DeleteEndpoint{db;useTransaction=false;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}getRelatedTable(e){return e.table}async findForDelete(e,n,t){let r=t??this.getDb(),i=this.getTable(),s=this.getColumn(this.lookupField),a=this.getSoftDeleteConfig(),l=[eq(s,e)];if(n)for(let[u,d]of Object.entries(n))l.push(eq(this.getColumn(u),d));return a.enabled&&l.push(isNull(this.getColumn(a.field))),(await r.select().from(i).where(g(...l)).limit(1))[0]||null}async delete(e,n,t){let r=t??this.getDb(),i=this.getTable(),s=this.getColumn(this.lookupField),a=this.getSoftDeleteConfig(),l=[eq(s,e)];if(n)for(let[c,u]of Object.entries(n))l.push(eq(this.getColumn(c),u));return a.enabled&&l.push(isNull(this.getColumn(a.field))),a.enabled?(await r.update(i).set({[a.field]:new Date}).where(g(...l)).returning())[0]||null:(await r.delete(i).where(g(...l)).returning())[0]||null}async countRelated(e,n,t,r){let i=r??this.getDb(),s=this.getRelatedTable(t);if(!s)return 0;let a=p(s,t.foreignKey),l=await i.select({count:sql`count(*)`}).from(s).where(eq(a,e));return S(l)}async deleteRelated(e,n,t,r){let i=r??this.getDb(),s=this.getRelatedTable(t);if(!s)return 0;let a=p(s,t.foreignKey);return (await i.delete(s).where(eq(a,e)).returning()).length}async nullifyRelated(e,n,t,r){let i=r??this.getDb(),s=this.getRelatedTable(t);if(!s)return 0;let a=p(s,t.foreignKey);return (await i.update(s).set({[t.foreignKey]:null}).where(eq(a,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()}},A=class extends ListEndpoint{db;dialect="sqlite";supportsCursorPagination=true;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async list(e){let n=await V({db:this.getDb(),table:this.getTable(),filters:e,dialect:this.dialect,searchFields:this.searchFields,softDeleteConfig:this.getSoftDeleteConfig(),defaultPerPage:this.defaultPerPage,cursorField:this.isCursorPaginationActive()?this.cursorField||"id":void 0}),t={relations:e.options.include||[],scope:this.getRelationScope(e.options.withDeleted)};if(n.cursor){let{items:i,result_info:s}=buildCursorPage({rows:n.records,limit:n.cursor.limit,totalCount:n.totalCount,cursorField:this.cursorField||"id",cursorApplied:n.cursor.applied});return {result:await v(this.getDb(),i,this._meta,t),result_info:s}}let r=await v(this.getDb(),n.records,this._meta,t);return ee(r,n)}},F=class extends RestoreEndpoint{db;useTransaction=false;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async restore(e,n,t){let r=t??this.getDb(),i=this.getTable(),s=this.getColumn(this.lookupField),a=this.getSoftDeleteConfig(),l=[eq(s,e)];if(n)for(let[u,d]of Object.entries(n))l.push(eq(this.getColumn(u),d));return l.push(isNotNull(this.getColumn(a.field))),(await r.update(i).set({[a.field]:null}).where(g(...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 q=class extends BatchCreateEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}async batchCreate(e){let n=this.getTable(),t=e.map(i=>this.applyManagedInsertFields(i,"drizzle"));return await this.getDb().insert(n).values(t).returning()}},U=class extends BatchUpdateEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async batchUpdate(e){let n=this.getTable(),t=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),i=[],s=[],a=this.getTenantScopeFilter();for(let l of e){let c=[eq(t,l.id)];r.enabled&&c.push(isNull(this.getColumn(r.field))),a&&c.push(eq(this.getColumn(a.field),a.value));let u=await this.getDb().update(n).set(this.applyManagedUpdateFields(l.data)).where(g(...c)).returning();u[0]?i.push(u[0]):s.push(l.id);}return {updated:i,notFound:s}}},Z=class extends BatchDeleteEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async batchDelete(e){let n=this.getTable(),t=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),i=[inArray(t,e)];r.enabled&&i.push(isNull(this.getColumn(r.field)));let s=this.getTenantScopeFilter();s&&i.push(eq(this.getColumn(s.field),s.value));let a;r.enabled?a=await this.getDb().update(n).set({[r.field]:new Date}).where(g(...i)).returning():a=await this.getDb().delete(n).where(g(...i)).returning();let l=a,c=new Set(l.map(d=>String(d[this.lookupField]))),u=e.filter(d=>!c.has(d));return {deleted:l,notFound:u}}},L=class extends BatchRestoreEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async batchRestore(e){let n=this.getTable(),t=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),i=[inArray(t,e),isNotNull(this.getColumn(r.field))],s=this.getTenantScopeFilter();s&&i.push(eq(this.getColumn(s.field),s.value));let l=await this.getDb().update(n).set({[r.field]:null}).where(g(...i)).returning(),c=new Set(l.map(d=>String(d[this.lookupField]))),u=e.filter(d=>!c.has(d));return {restored:l,notFound:u}}};function Et(o){return o.split(/\s+/).filter(e=>e.length>0)}var N=class extends UpsertEndpoint{db;dialect="sqlite";getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async findExisting(e){return te(this.getDb(),this.getTable(),n=>this.getColumn(n),e,this.getUpsertKeys())}async create(e){let n=this.getTable(),t=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(n).values(t).returning())[0]}async update(e,n){let t=this.getTable(),r=this._meta.model.primaryKeys[0],i=e[r];return (await this.getDb().update(t).set(this.applyManagedUpdateFields(n)).where(eq(this.getColumn(r),i)).returning())[0]}async nativeUpsert(e,n){let t=this.getTable(),r=this.getUpsertKeys(),i=this._meta.model.primaryKeys[0],s=this.getSoftDeleteConfig(),a=this.getTimestampsConfig(),l=this.applyManagedInsertFields(e,"drizzle"),c={};for(let[C,w]of Object.entries(e))!r.includes(C)&&C!==i&&(this.createOnlyFields?.includes(C)||(c[C]=w));a.enabled&&(c[a.updatedAt]=Date.now());let u=r.map(C=>this.getColumn(C)),d;s.enabled&&(d=isNull(this.getColumn(s.field)));let D=Object.keys(c).length>0?c:{[i]:sql`${this.getColumn(i)}`},f=this.getDb().insert(t).values(l);return this.dialect==="mysql"?{data:(await f.onDuplicateKeyUpdate({set:D}).returning())[0],created:false}:{data:(await f.onConflictDoUpdate({target:u,set:D,where:d}).returning())[0],created:false}}},$=class extends BatchUpsertEndpoint{db;dialect="sqlite";getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async findExisting(e){return te(this.getDb(),this.getTable(),n=>this.getColumn(n),e,this.getUpsertKeys())}async create(e){let n=this.getTable(),t=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(n).values(t).returning())[0]}async update(e,n){let t=this.getTable(),r=this._meta.model.primaryKeys[0],i=e[r];return (await this.getDb().update(t).set(this.applyManagedUpdateFields(n)).where(eq(this.getColumn(r),i)).returning())[0]}async nativeBatchUpsert(e,n){if(e.length===0)return {items:[],createdCount:0,updatedCount:0,totalCount:0};let t=this.getTable(),r=this.getUpsertKeys(),i=this._meta.model.primaryKeys[0],s=this.getTimestampsConfig(),a=e.map(h=>this.applyManagedInsertFields(h,"drizzle")),l={},c=e[0];for(let h of Object.keys(c))!r.includes(h)&&h!==i&&(this.createOnlyFields?.includes(h)||(l[h]=sql`excluded.${sql.identifier(h)}`));s.enabled&&(l[s.updatedAt]=Date.now());let u=r.map(h=>this.getColumn(h)),d=Object.keys(l).length>0?l:{[i]:sql`${this.getColumn(i)}`},D=this.getDb().insert(t).values(a),f=await(this.dialect==="mysql"?D.onDuplicateKeyUpdate({set:d}):D.onConflictDoUpdate({target:u,set:d})).returning();return {items:f.map((h,C)=>({data:h,created:false,index:C})),createdCount:0,updatedCount:f.length,totalCount:f.length}}},re=class extends BulkPatchEndpoint{db;dialect="sqlite";getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}buildConditions(e){let n=this.getTable(),t=[];for(let i of e.filters){let s=W(n,i,this.dialect);s&&t.push(s);}let r=this.getSoftDeleteConfig();return r.enabled&&t.push(isNull(this.getColumn(r.field))),t}async countMatching(e){let n=this.buildConditions(e),t=await this.getDb().select({count:sql`count(*)`}).from(this.getTable()).where(g(...n));return S(t)}async applyPatch(e,n){let t=this.buildConditions(n),r=await this.getDb().update(this.getTable()).set(this.applyManagedUpdateFields(e)).where(g(...t)).returning();return {updated:r.length,records:r}}},oe=class extends VersionHistoryEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async recordExists(e){let n=this.getTable(),t=await this.getDb().select({count:sql`count(*)`}).from(n).where(eq(this.getColumn("id"),e));return S(t)>0}},ie=class extends VersionReadEndpoint{},se=class extends VersionCompareEndpoint{},ae=class extends VersionRollbackEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async rollback(e,n,t){let r=this.getTable(),i=this.getVersioningConfig().field;return (await this.getDb().update(r).set({...n,[i]:t}).where(eq(this.getColumn("id"),e)).returning())[0]}},le=class extends AggregateEndpoint{db;dialect="sqlite";getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async aggregate(e){let n=this.getTable(),t=[],r=this.getSoftDeleteConfig();if(r.enabled){let{query:a}=await this.getValidatedData();a?.withDeleted===true||a?.withDeleted==="true"||t.push(isNull(this.getColumn(r.field)));}if(e.filters)for(let[a,l]of Object.entries(e.filters))if(typeof l=="object"&&l!==null)for(let[c,u]of Object.entries(l)){if(!isFilterOperator(c)){t.push(sql`1 = 0`);continue}let d=W(n,{field:a,operator:c,value:u},this.dialect);d&&t.push(d);}else t.push(eq(this.getColumn(a),l));let i=t.length>0?g(...t):void 0,s=await this.getDb().select().from(n).where(i);return computeAggregations(s,e)}},K=class extends SearchEndpoint{db;dialect="sqlite";getDb(){return m(this)}useNativeSearch=false;vectorColumn;vectorConfig="english";getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async search(e,n){let t=this.getTable(),r=[],i=this.getSearchableFields(),s=e.fields||Object.keys(i);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(" | ")})`;r.push(sql`${w} @@ ${M}`);}else {let w=(M,E)=>{try{let T=this.getColumn(M);return B(sql`CAST(${T} AS TEXT)`,E,this.dialect)}catch{return}};if(e.mode==="all"){let M=Et(e.query);if(M.length>0){let E=[];for(let T of M){let Y=s.map(Q=>w(Q,T)).filter(Q=>Q!==void 0);Y.length>0&&E.push(J(...Y));}E.length>0&&r.push(g(...E));}}else {let M=s.map(E=>w(E,e.query)).filter(E=>E!==void 0);M.length>0&&r.push(J(...M));}}let a=await V({db:this.getDb(),table:t,filters:n,dialect:this.dialect,softDeleteConfig:this.getSoftDeleteConfig(),defaultPerPage:this.defaultPerPage,extraConditions:r}),l=a.records,c=a.totalCount,u=e.mode==="all"?{...e,mode:"any"}:e,d=searchInMemory(l,u,i),D={relations:n.options.include||[]},f=d.map(w=>w.item),h=await v(this.getDb(),f,this._meta,D);return {items:d.map((w,M)=>({...w,item:h[M]})),totalCount:c}}},de=class extends ExportEndpoint{db;dialect="sqlite";getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async list(e){let n=await V({db:this.getDb(),table:this.getTable(),filters:e,dialect:this.dialect,searchFields:this.searchFields,softDeleteConfig:this.getSoftDeleteConfig(),defaultPerPage:this.defaultPerPage}),t={relations:e.options.include||[]},r=await v(this.getDb(),n.records,this._meta,t);return ee(r,n)}},ce=class extends ImportEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async findExisting(e){return te(this.getDb(),this.getTable(),n=>this.getColumn(n),e,this.getUpsertKeys())}async create(e){let n=this.getTable(),t=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(n).values(t).returning())[0]}async update(e,n){let t=this.getTable(),r=this._meta.model.primaryKeys[0],i=e[r];return (await this.getDb().update(t).set(this.applyManagedUpdateFields(n)).where(eq(this.getColumn(r),i)).returning())[0]}},ue=class extends CloneEndpoint{db;getDb(){return m(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}generateId(){return crypto.randomUUID()}async findSource(e,n){let t=this.getTable(),r=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),s=[eq(r,e)];if(n)for(let[l,c]of Object.entries(n))s.push(eq(this.getColumn(l),c));i.enabled&&s.push(isNull(this.getColumn(i.field)));let a=await this.getDb().select().from(t).where(g(...s)).limit(1);return a[0]?a[0]:null}async createClone(e){let n=this.getTable(),t=this.applyManagedInsertFields(e,"drizzle",()=>this.generateId());return (await this.getDb().insert(n).values(t).returning())[0]}};function yn(o,e,n){let t=n?.dialect??"sqlite";return {Create:class extends j{_meta=e;db=o},Read:class extends P{_meta=e;db=o},Update:class extends I{_meta=e;db=o},Delete:class extends _{_meta=e;db=o},List:class extends A{_meta=e;db=o;dialect=t},Restore:class extends F{_meta=e;db=o},Upsert:class extends N{_meta=e;db=o;dialect=t},Search:class extends K{_meta=e;db=o;dialect=t},BatchCreate:class extends q{_meta=e;db=o},BatchUpdate:class extends U{_meta=e;db=o},BatchDelete:class extends Z{_meta=e;db=o},BatchRestore:class extends L{_meta=e;db=o},BatchUpsert:class extends ${_meta=e;db=o;dialect=t}}}var ze=null,xe=false,ge=null;async function me(){if(xe){if(ge)throw ge;return ze}xe=true;try{return ze=await import('drizzle-zod'),ze}catch{throw ge=new Error("drizzle-zod is not installed. Please install it: npm install drizzle-zod"),ge}}async function Rt(o,e){return (await me()).createSelectSchema(o,e)}async function Tt(o,e){return (await me()).createInsertSchema(o,e)}async function xt(o,e){let n=await me();return n.createUpdateSchema?n.createUpdateSchema(o,e):n.createInsertSchema(o,e).partial()}async function kt(o,e){let n=await me(),t=e?.coerceDates!==false,r=t?Bt(o):new Set,i=n.createSelectSchema(o,e?.selectRefine),s=n.createInsertSchema(o,e?.insertRefine),a;return n.createUpdateSchema?a=n.createUpdateSchema(o,e?.updateRefine):a=n.createInsertSchema(o,e?.updateRefine).partial(),t&&r.size>0&&(s=ke(s,r),a=ke(a,r)),{select:i,insert:s,update:a}}function Ot(){return ze!==null}var vt=z$1.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$1.date()),St=z$1.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$1.date().nullable());function Bt(o){let e=new Set,n=o;for(let[t,r]of Object.entries(n)){if(t==="_"||t==="$inferInsert"||t==="$inferSelect")continue;let i=r;if(!i||typeof i!="object")continue;let s=String(i.dataType??"").toLowerCase(),a=String(i.columnType??"").toLowerCase(),l=i.config,c=String(l?.dataType??"").toLowerCase();(s.includes("timestamp")||s.includes("date")||s.includes("datetime")||a.includes("pgtimestamp")||a.includes("pgdate")||a.includes("mysqltimestamp")||a.includes("mysqldate")||a.includes("sqlitetimestamp")||c.includes("timestamp")||c.includes("date"))&&e.add(t);}return e}function ke(o,e){if(e.size===0)return o;let n=o.shape,t={};for(let[r,i]of Object.entries(n))if(e.has(r)){let s=i.isOptional?.()??false,a=i.isNullable?.()??false,l=vt;(a||s)&&(l=St),s&&(l=l.optional()),t[r]=l;}else t[r]=i;return z$1.object(t)}var Ln={CreateEndpoint:j,ListEndpoint:A,ReadEndpoint:P,UpdateEndpoint:I,DeleteEndpoint:_,RestoreEndpoint:F,BatchCreateEndpoint:q,BatchUpdateEndpoint:U,BatchDeleteEndpoint:Z,BatchRestoreEndpoint:L,BatchUpsertEndpoint:$,SearchEndpoint:K,AggregateEndpoint:le,ExportEndpoint:de,ImportEndpoint:ce,UpsertEndpoint:N,CloneEndpoint:ue,BulkPatchEndpoint:re,VersionHistoryEndpoint:oe,VersionReadEndpoint:ie,VersionCompareEndpoint:se,VersionRollbackEndpoint:ae};export{Ke as DRIZZLE_DIALECTS,Ln as DrizzleAdapters,le as DrizzleAggregateEndpoint,q as DrizzleBatchCreateEndpoint,Z as DrizzleBatchDeleteEndpoint,L as DrizzleBatchRestoreEndpoint,U as DrizzleBatchUpdateEndpoint,$ as DrizzleBatchUpsertEndpoint,re as DrizzleBulkPatchEndpoint,ue as DrizzleCloneEndpoint,j as DrizzleCreateEndpoint,_ as DrizzleDeleteEndpoint,de as DrizzleExportEndpoint,ce as DrizzleImportEndpoint,A as DrizzleListEndpoint,P as DrizzleReadEndpoint,F as DrizzleRestoreEndpoint,K as DrizzleSearchEndpoint,I as DrizzleUpdateEndpoint,N as DrizzleUpsertEndpoint,se as DrizzleVersionCompareEndpoint,oe as DrizzleVersionHistoryEndpoint,ie as DrizzleVersionReadEndpoint,ae as DrizzleVersionRollbackEndpoint,v as batchLoadDrizzleRelations,W as buildWhereCondition,G as cast,yn as createDrizzleCrud,kt as createDrizzleSchemas,Tt as createInsertSchema,Rt as createSelectSchema,xt as createUpdateSchema,p as getColumn,z as getTable,Ot as isDrizzleZodAvailable,Qe as loadDrizzleRelation,fe as loadDrizzleRelations,S as readCount,B as substringMatch};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hono-crud/drizzle",
3
- "version": "0.1.14",
3
+ "version": "0.1.15",
4
4
  "description": "Drizzle ORM CRUD adapter for hono-crud",
5
5
  "author": "Kauan Guesser <contato@kauan.net>",
6
6
  "license": "MIT",
@@ -47,7 +47,7 @@
47
47
  "drizzle-zod": ">=0.8.0",
48
48
  "hono": ">=4.11.7 <5",
49
49
  "zod": ">=4.0.0",
50
- "hono-crud": "^0.13.17"
50
+ "hono-crud": "^0.13.18"
51
51
  },
52
52
  "devDependencies": {
53
53
  "drizzle-orm": "^0.45.1",
@@ -56,7 +56,7 @@
56
56
  "tsup": "^8.4.0",
57
57
  "typescript": "^5.8.3",
58
58
  "zod": "^4.3.5",
59
- "hono-crud": "0.13.17"
59
+ "hono-crud": "0.13.18"
60
60
  },
61
61
  "peerDependenciesMeta": {
62
62
  "drizzle-zod": {