@hono-crud/drizzle 0.1.12 → 0.1.13

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,33 @@
1
1
  # @hono-crud/drizzle
2
2
 
3
+ ## 0.1.13
4
+
5
+ ### Patch Changes
6
+
7
+ - 4ba4a85: Owner-scope relation includes (`?include=`) — security fix for cross-tenant exposure.
8
+
9
+ Previously, loading a relation via `?include=` fetched the related rows by foreign key alone, ignoring the **related** model's access scope. A caller who could read a parent row could therefore read a related row in another tenant (or a soft-deleted one) through the include — a cross-tenant data leak.
10
+
11
+ Relations can now declare a `scope` naming the related table's owner and soft-delete columns:
12
+
13
+ ```ts
14
+ relations: {
15
+ post: {
16
+ type: 'belongsTo', model: 'posts', table: posts,
17
+ foreignKey: 'postId', localKey: 'id',
18
+ scope: { tenantField: 'authorId', softDeleteField: 'deletedAt' },
19
+ },
20
+ }
21
+ ```
22
+
23
+ When set, included related rows are filtered to the request's resolved tenant id and exclude soft-deleted rows (unless `?withDeleted=true`), so a foreign key pointing at another tenant's row resolves to `null` (belongsTo/hasOne) or is omitted (hasMany). The filtering lives in the core orchestrator (`batchLoadRelations` / `loadRelationsForItem`), so it applies identically across the drizzle, memory, and prisma adapters; the endpoint threads the parent request's tenant id + `withDeleted` into `IncludeOptions.scope` (Read via core; List via each adapter).
24
+
25
+ New public types: `RelationScopeConfig`, `RelationRequestScope`; new fields `RelationConfig.scope` and `IncludeOptions.scope`; new protected `getRelationScope()` on the endpoint base class.
26
+
27
+ Backward-compatible and opt-in: relations without `scope` (or requests that resolve no tenant) behave exactly as before. Declare `scope` on any relation whose related model is access-scoped to close the leak.
28
+
29
+ Note: scoping is applied as a post-fetch filter in the orchestrator (related rows are fetched, then filtered before being mapped back onto the parent — they never reach the response), not yet pushed down to the adapter `WHERE`/`where`. Correct and leak-free; pushing the predicate into the query is a performance follow-up.
30
+
3
31
  ## 0.1.12
4
32
 
5
33
  ### Patch Changes
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
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 be(o){return {resolveRelation:e=>e.table??null,fetchRelated:(e,n,t)=>o.select().from(e).where(inArray(p(e,n),t))}}async function Ke(o,e,n,t){let r=t.table;if(!r)return e;let s=be(o),a=await resolveRelationValueAsync(e,t,r,s.fetchRelated);return {...e,[n]:a}}async function me(o,e,n,t){return loadRelationsForItem(e,n,be(o),t)}async function v(o,e,n,t){return batchLoadRelations(e,n,be(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,s]=e.value;return between(t,r,s)}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:s=[],softDeleteConfig:a,defaultPerPage:i=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&&s.length>0){let y=t.options.search,k=s.map(xe=>B(p(n,xe),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||i;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||i,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 s=[];for(let i of r){let l=t[i];l!==void 0&&s.push(eq(n(i),l));}return s.length===0?null:(await o.select().from(e).where(g(...s)).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 b(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 b(this)}getTable(){return z(this._meta)}getRelatedTable(e){return e.table}async create(e,n){let t=n??this.getDb(),r=this.getTable(),s=this.applyManagedInsertFields(e,"drizzle");return (await t.insert(r).values(s).returning())[0]}async createNested(e,n,t,r,s){let a=s??this.getDb(),i=this.getRelatedTable(t);if(!i)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(i).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 b(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async read(e,n,t){let r=this.getTable(),s=this.getColumn(this.lookupField),a=this.getSoftDeleteConfig(),i=[eq(s,e)];if(n)for(let[c,u]of Object.entries(n))i.push(eq(this.getColumn(c),u));a.enabled&&i.push(isNull(this.getColumn(a.field)));let l=await this.getDb().select().from(r).where(g(...i)).limit(1);return l[0]?await me(this.getDb(),l[0],this._meta,t):null}},I=class extends UpdateEndpoint{db;useTransaction=false;getDb(){return b(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(),s=this.getTable(),a=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(a,e)];if(n)for(let[c,u]of Object.entries(n))l.push(eq(this.getColumn(c),u));return i.enabled&&l.push(isNull(this.getColumn(i.field))),(await r.select().from(s).where(g(...l)).limit(1))[0]||null}async update(e,n,t,r){let s=r??this.getDb(),a=this.getTable(),i=this.getColumn(this.lookupField),l=this.getSoftDeleteConfig(),d=[eq(i,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 s.update(a).set(this.applyManagedUpdateFields(n)).where(g(...d)).returning())[0]||null}async processNestedWrites(e,n,t,r,s){let a=s??this.getDb(),i=this.getRelatedTable(t);if(!i)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(i,t.foreignKey),c=p(i,"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(i).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(i).where(g(eq(c,u.id),eq(d,e))).limit(1))[0])continue;let{id:f,...h}=u,C=await a.update(i).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(i).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(i).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(i).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 b(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(),s=this.getTable(),a=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(a,e)];if(n)for(let[c,u]of Object.entries(n))l.push(eq(this.getColumn(c),u));return i.enabled&&l.push(isNull(this.getColumn(i.field))),(await r.select().from(s).where(g(...l)).limit(1))[0]||null}async delete(e,n,t){let r=t??this.getDb(),s=this.getTable(),a=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(a,e)];if(n)for(let[d,c]of Object.entries(n))l.push(eq(this.getColumn(d),c));return i.enabled&&l.push(isNull(this.getColumn(i.field))),i.enabled?(await r.update(s).set({[i.field]:new Date}).where(g(...l)).returning())[0]||null:(await r.delete(s).where(g(...l)).returning())[0]||null}async countRelated(e,n,t,r){let s=r??this.getDb(),a=this.getRelatedTable(t);if(!a)return 0;let i=p(a,t.foreignKey),l=await s.select({count:sql`count(*)`}).from(a).where(eq(i,e));return S(l)}async deleteRelated(e,n,t,r){let s=r??this.getDb(),a=this.getRelatedTable(t);if(!a)return 0;let i=p(a,t.foreignKey);return (await s.delete(a).where(eq(i,e)).returning()).length}async nullifyRelated(e,n,t,r){let s=r??this.getDb(),a=this.getRelatedTable(t);if(!a)return 0;let i=p(a,t.foreignKey);return (await s.update(a).set({[t.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()}},A=class extends ListEndpoint{db;dialect="sqlite";supportsCursorPagination=true;getDb(){return b(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||[]};if(n.cursor){let{items:s,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(),s,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 b(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async restore(e,n,t){let r=t??this.getDb(),s=this.getTable(),a=this.getColumn(this.lookupField),i=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(i.field))),(await r.update(s).set({[i.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 b(this)}getTable(){return z(this._meta)}async batchCreate(e){let n=this.getTable(),t=e.map(s=>this.applyManagedInsertFields(s,"drizzle"));return await this.getDb().insert(n).values(t).returning()}},F=class extends BatchUpdateEndpoint{db;getDb(){return b(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(),s=[],a=[];for(let i of e){let l=[eq(t,i.id)];r.enabled&&l.push(isNull(this.getColumn(r.field)));let d=await this.getDb().update(n).set(this.applyManagedUpdateFields(i.data)).where(g(...l)).returning();d[0]?s.push(d[0]):a.push(i.id);}return {updated:s,notFound:a}}},Z=class extends BatchDeleteEndpoint{db;getDb(){return b(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(),s=[inArray(t,e)];r.enabled&&s.push(isNull(this.getColumn(r.field)));let a;r.enabled?a=await this.getDb().update(n).set({[r.field]:new Date}).where(g(...s)).returning():a=await this.getDb().delete(n).where(g(...s)).returning();let i=a,l=new Set(i.map(c=>String(c[this.lookupField]))),d=e.filter(c=>!l.has(c));return {deleted:i,notFound:d}}},L=class extends BatchRestoreEndpoint{db;getDb(){return b(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(),s=[inArray(t,e),isNotNull(this.getColumn(r.field))],i=await this.getDb().update(n).set({[r.field]:null}).where(g(...s)).returning(),l=new Set(i.map(c=>String(c[this.lookupField]))),d=e.filter(c=>!l.has(c));return {restored:i,notFound:d}}};function Et(o){return o.split(/\s+/).filter(e=>e.length>0)}var N=class extends UpsertEndpoint{db;dialect="sqlite";getDb(){return b(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],s=e[r];return (await this.getDb().update(t).set(this.applyManagedUpdateFields(n)).where(eq(this.getColumn(r),s)).returning())[0]}async nativeUpsert(e,n){let t=this.getTable(),r=this.getUpsertKeys(),s=this._meta.model.primaryKeys[0],a=this.getSoftDeleteConfig(),i=this.getTimestampsConfig(),l=this.applyManagedInsertFields(e,"drizzle"),d={};for(let[C,w]of Object.entries(e))!r.includes(C)&&C!==s&&(this.createOnlyFields?.includes(C)||(d[C]=w));i.enabled&&(d[i.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:{[s]:sql`${this.getColumn(s)}`},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 b(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],s=e[r];return (await this.getDb().update(t).set(this.applyManagedUpdateFields(n)).where(eq(this.getColumn(r),s)).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(),s=this._meta.model.primaryKeys[0],a=this.getTimestampsConfig(),i=e.map(h=>this.applyManagedInsertFields(h,"drizzle")),l={},d=e[0];for(let h of Object.keys(d))!r.includes(h)&&h!==s&&(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:{[s]:sql`${this.getColumn(s)}`},D=this.getDb().insert(t).values(i),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 b(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}buildConditions(e){let n=this.getTable(),t=[];for(let s of e.filters){let a=W(n,s,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 b(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{},se=class extends VersionCompareEndpoint{},ie=class extends VersionRollbackEndpoint{db;getDb(){return b(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async rollback(e,n,t){let r=this.getTable(),s=this.getVersioningConfig().field;return (await this.getDb().update(r).set({...n,[s]:t}).where(eq(this.getColumn("id"),e)).returning())[0]}},ae=class extends AggregateEndpoint{db;dialect="sqlite";getDb(){return b(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:i}=await this.getValidatedData();i?.withDeleted===true||i?.withDeleted==="true"||t.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,c]of Object.entries(l)){if(!isFilterOperator(d)){t.push(sql`1 = 0`);continue}let u=W(n,{field:i,operator:d,value:c},this.dialect);u&&t.push(u);}else t.push(eq(this.getColumn(i),l));let s=t.length>0?g(...t):void 0,a=await this.getDb().select().from(n).where(s);return computeAggregations(a,e)}},K=class extends SearchEndpoint{db;dialect="sqlite";getDb(){return b(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=[],s=this.getSearchableFields(),a=e.fields||Object.keys(s);if(this.useNativeSearch&&this.vectorColumn){let w=this.getColumn(this.vectorColumn),M=e.mode==="phrase"?sql`phraseto_tsquery(${this.vectorConfig}, ${e.query})`:e.mode==="all"?sql`plainto_tsquery(${this.vectorConfig}, ${e.query})`:sql`to_tsquery(${this.vectorConfig}, ${e.query.split(/\s+/).join(" | ")})`;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 i=await V({db:this.getDb(),table:t,filters:n,dialect:this.dialect,softDeleteConfig:this.getSoftDeleteConfig(),defaultPerPage:this.defaultPerPage,extraConditions:r}),l=i.records,d=i.totalCount,c=e.mode==="all"?{...e,mode:"any"}:e,u=searchInMemory(l,c,s),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 b(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 b(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],s=e[r];return (await this.getDb().update(t).set(this.applyManagedUpdateFields(n)).where(eq(this.getColumn(r),s)).returning())[0]}},ce=class extends CloneEndpoint{db;getDb(){return b(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),s=this.getSoftDeleteConfig(),a=[eq(r,e)];if(n)for(let[l,d]of Object.entries(n))a.push(eq(this.getColumn(l),d));s.enabled&&a.push(isNull(this.getColumn(s.field)));let i=await this.getDb().select().from(t).where(g(...a)).limit(1);return i[0]?i[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,Re=false,pe=null;async function ze(){if(Re){if(pe)throw pe;return ge}Re=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,s=n.createSelectSchema(o,e?.selectRefine),a=n.createInsertSchema(o,e?.insertRefine),i;return n.createUpdateSchema?i=n.createUpdateSchema(o,e?.updateRefine):i=n.createInsertSchema(o,e?.updateRefine).partial(),t&&r.size>0&&(a=Te(a,r),i=Te(i,r)),{select:s,insert:a,update:i}}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 s=r;if(!s||typeof s!="object")continue;let a=String(s.dataType??"").toLowerCase(),i=String(s.columnType??"").toLowerCase(),l=s.config,d=String(l?.dataType??"").toLowerCase();(a.includes("timestamp")||a.includes("date")||a.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(t);}return e}function Te(o,e){if(e.size===0)return o;let n=o.shape,t={};for(let[r,s]of Object.entries(n))if(e.has(r)){let a=s.isOptional?.()??false,i=s.isNullable?.()??false,l=vt;(i||a)&&(l=St),a&&(l=l.optional()),t[r]=l;}else t[r]=s;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:se,VersionRollbackEndpoint:ie};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,se as DrizzleVersionCompareEndpoint,re as DrizzleVersionHistoryEndpoint,oe as DrizzleVersionReadEndpoint,ie 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,me 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 b(this)}getTable(){return z(this._meta)}getRelatedTable(e){return e.table}async create(e,n){let t=n??this.getDb(),r=this.getTable(),s=this.applyManagedInsertFields(e,"drizzle");return (await t.insert(r).values(s).returning())[0]}async createNested(e,n,t,r,s){let a=s??this.getDb(),i=this.getRelatedTable(t);if(!i)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(i).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 b(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async read(e,n,t){let r=this.getTable(),s=this.getColumn(this.lookupField),a=this.getSoftDeleteConfig(),i=[eq(s,e)];if(n)for(let[c,u]of Object.entries(n))i.push(eq(this.getColumn(c),u));a.enabled&&i.push(isNull(this.getColumn(a.field)));let l=await this.getDb().select().from(r).where(g(...i)).limit(1);return l[0]?await me(this.getDb(),l[0],this._meta,t):null}},I=class extends UpdateEndpoint{db;useTransaction=false;getDb(){return b(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(),s=this.getTable(),a=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(a,e)];if(n)for(let[c,u]of Object.entries(n))l.push(eq(this.getColumn(c),u));return i.enabled&&l.push(isNull(this.getColumn(i.field))),(await r.select().from(s).where(g(...l)).limit(1))[0]||null}async update(e,n,t,r){let s=r??this.getDb(),a=this.getTable(),i=this.getColumn(this.lookupField),l=this.getSoftDeleteConfig(),d=[eq(i,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 s.update(a).set(this.applyManagedUpdateFields(n)).where(g(...d)).returning())[0]||null}async processNestedWrites(e,n,t,r,s){let a=s??this.getDb(),i=this.getRelatedTable(t);if(!i)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(i,t.foreignKey),c=p(i,"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(i).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(i).where(g(eq(c,u.id),eq(d,e))).limit(1))[0])continue;let{id:f,...h}=u,C=await a.update(i).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(i).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(i).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(i).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 b(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(),s=this.getTable(),a=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(a,e)];if(n)for(let[c,u]of Object.entries(n))l.push(eq(this.getColumn(c),u));return i.enabled&&l.push(isNull(this.getColumn(i.field))),(await r.select().from(s).where(g(...l)).limit(1))[0]||null}async delete(e,n,t){let r=t??this.getDb(),s=this.getTable(),a=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(a,e)];if(n)for(let[d,c]of Object.entries(n))l.push(eq(this.getColumn(d),c));return i.enabled&&l.push(isNull(this.getColumn(i.field))),i.enabled?(await r.update(s).set({[i.field]:new Date}).where(g(...l)).returning())[0]||null:(await r.delete(s).where(g(...l)).returning())[0]||null}async countRelated(e,n,t,r){let s=r??this.getDb(),a=this.getRelatedTable(t);if(!a)return 0;let i=p(a,t.foreignKey),l=await s.select({count:sql`count(*)`}).from(a).where(eq(i,e));return S(l)}async deleteRelated(e,n,t,r){let s=r??this.getDb(),a=this.getRelatedTable(t);if(!a)return 0;let i=p(a,t.foreignKey);return (await s.delete(a).where(eq(i,e)).returning()).length}async nullifyRelated(e,n,t,r){let s=r??this.getDb(),a=this.getRelatedTable(t);if(!a)return 0;let i=p(a,t.foreignKey);return (await s.update(a).set({[t.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()}},A=class extends ListEndpoint{db;dialect="sqlite";supportsCursorPagination=true;getDb(){return b(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:s,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(),s,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 b(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async restore(e,n,t){let r=t??this.getDb(),s=this.getTable(),a=this.getColumn(this.lookupField),i=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(i.field))),(await r.update(s).set({[i.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 b(this)}getTable(){return z(this._meta)}async batchCreate(e){let n=this.getTable(),t=e.map(s=>this.applyManagedInsertFields(s,"drizzle"));return await this.getDb().insert(n).values(t).returning()}},F=class extends BatchUpdateEndpoint{db;getDb(){return b(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(),s=[],a=[];for(let i of e){let l=[eq(t,i.id)];r.enabled&&l.push(isNull(this.getColumn(r.field)));let d=await this.getDb().update(n).set(this.applyManagedUpdateFields(i.data)).where(g(...l)).returning();d[0]?s.push(d[0]):a.push(i.id);}return {updated:s,notFound:a}}},Z=class extends BatchDeleteEndpoint{db;getDb(){return b(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(),s=[inArray(t,e)];r.enabled&&s.push(isNull(this.getColumn(r.field)));let a;r.enabled?a=await this.getDb().update(n).set({[r.field]:new Date}).where(g(...s)).returning():a=await this.getDb().delete(n).where(g(...s)).returning();let i=a,l=new Set(i.map(c=>String(c[this.lookupField]))),d=e.filter(c=>!l.has(c));return {deleted:i,notFound:d}}},L=class extends BatchRestoreEndpoint{db;getDb(){return b(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(),s=[inArray(t,e),isNotNull(this.getColumn(r.field))],i=await this.getDb().update(n).set({[r.field]:null}).where(g(...s)).returning(),l=new Set(i.map(c=>String(c[this.lookupField]))),d=e.filter(c=>!l.has(c));return {restored:i,notFound:d}}};function Et(o){return o.split(/\s+/).filter(e=>e.length>0)}var N=class extends UpsertEndpoint{db;dialect="sqlite";getDb(){return b(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],s=e[r];return (await this.getDb().update(t).set(this.applyManagedUpdateFields(n)).where(eq(this.getColumn(r),s)).returning())[0]}async nativeUpsert(e,n){let t=this.getTable(),r=this.getUpsertKeys(),s=this._meta.model.primaryKeys[0],a=this.getSoftDeleteConfig(),i=this.getTimestampsConfig(),l=this.applyManagedInsertFields(e,"drizzle"),d={};for(let[C,w]of Object.entries(e))!r.includes(C)&&C!==s&&(this.createOnlyFields?.includes(C)||(d[C]=w));i.enabled&&(d[i.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:{[s]:sql`${this.getColumn(s)}`},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 b(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],s=e[r];return (await this.getDb().update(t).set(this.applyManagedUpdateFields(n)).where(eq(this.getColumn(r),s)).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(),s=this._meta.model.primaryKeys[0],a=this.getTimestampsConfig(),i=e.map(h=>this.applyManagedInsertFields(h,"drizzle")),l={},d=e[0];for(let h of Object.keys(d))!r.includes(h)&&h!==s&&(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:{[s]:sql`${this.getColumn(s)}`},D=this.getDb().insert(t).values(i),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 b(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}buildConditions(e){let n=this.getTable(),t=[];for(let s of e.filters){let a=W(n,s,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 b(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{},se=class extends VersionCompareEndpoint{},ie=class extends VersionRollbackEndpoint{db;getDb(){return b(this)}getTable(){return z(this._meta)}getColumn(e){return p(this.getTable(),e)}async rollback(e,n,t){let r=this.getTable(),s=this.getVersioningConfig().field;return (await this.getDb().update(r).set({...n,[s]:t}).where(eq(this.getColumn("id"),e)).returning())[0]}},ae=class extends AggregateEndpoint{db;dialect="sqlite";getDb(){return b(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:i}=await this.getValidatedData();i?.withDeleted===true||i?.withDeleted==="true"||t.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,c]of Object.entries(l)){if(!isFilterOperator(d)){t.push(sql`1 = 0`);continue}let u=W(n,{field:i,operator:d,value:c},this.dialect);u&&t.push(u);}else t.push(eq(this.getColumn(i),l));let s=t.length>0?g(...t):void 0,a=await this.getDb().select().from(n).where(s);return computeAggregations(a,e)}},K=class extends SearchEndpoint{db;dialect="sqlite";getDb(){return b(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=[],s=this.getSearchableFields(),a=e.fields||Object.keys(s);if(this.useNativeSearch&&this.vectorColumn){let w=this.getColumn(this.vectorColumn),M=e.mode==="phrase"?sql`phraseto_tsquery(${this.vectorConfig}, ${e.query})`:e.mode==="all"?sql`plainto_tsquery(${this.vectorConfig}, ${e.query})`:sql`to_tsquery(${this.vectorConfig}, ${e.query.split(/\s+/).join(" | ")})`;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 i=await V({db:this.getDb(),table:t,filters:n,dialect:this.dialect,softDeleteConfig:this.getSoftDeleteConfig(),defaultPerPage:this.defaultPerPage,extraConditions:r}),l=i.records,d=i.totalCount,c=e.mode==="all"?{...e,mode:"any"}:e,u=searchInMemory(l,c,s),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 b(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 b(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],s=e[r];return (await this.getDb().update(t).set(this.applyManagedUpdateFields(n)).where(eq(this.getColumn(r),s)).returning())[0]}},ce=class extends CloneEndpoint{db;getDb(){return b(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),s=this.getSoftDeleteConfig(),a=[eq(r,e)];if(n)for(let[l,d]of Object.entries(n))a.push(eq(this.getColumn(l),d));s.enabled&&a.push(isNull(this.getColumn(s.field)));let i=await this.getDb().select().from(t).where(g(...a)).limit(1);return i[0]?i[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,Re=false,pe=null;async function ze(){if(Re){if(pe)throw pe;return ge}Re=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,s=n.createSelectSchema(o,e?.selectRefine),a=n.createInsertSchema(o,e?.insertRefine),i;return n.createUpdateSchema?i=n.createUpdateSchema(o,e?.updateRefine):i=n.createInsertSchema(o,e?.updateRefine).partial(),t&&r.size>0&&(a=Te(a,r),i=Te(i,r)),{select:s,insert:a,update:i}}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 s=r;if(!s||typeof s!="object")continue;let a=String(s.dataType??"").toLowerCase(),i=String(s.columnType??"").toLowerCase(),l=s.config,d=String(l?.dataType??"").toLowerCase();(a.includes("timestamp")||a.includes("date")||a.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(t);}return e}function Te(o,e){if(e.size===0)return o;let n=o.shape,t={};for(let[r,s]of Object.entries(n))if(e.has(r)){let a=s.isOptional?.()??false,i=s.isNullable?.()??false,l=vt;(i||a)&&(l=St),a&&(l=l.optional()),t[r]=l;}else t[r]=s;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:se,VersionRollbackEndpoint:ie};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,se as DrizzleVersionCompareEndpoint,re as DrizzleVersionHistoryEndpoint,oe as DrizzleVersionReadEndpoint,ie 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,me 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.12",
3
+ "version": "0.1.13",
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.14"
50
+ "hono-crud": "^0.13.15"
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.14"
59
+ "hono-crud": "0.13.15"
60
60
  },
61
61
  "peerDependenciesMeta": {
62
62
  "drizzle-zod": {