@hono-crud/drizzle 0.1.6 → 0.1.7

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 ADDED
@@ -0,0 +1,75 @@
1
+ # @hono-crud/drizzle
2
+
3
+ ## 0.1.7
4
+
5
+ ### Patch Changes
6
+
7
+ - dd62008: Aggregate filters now fail closed on unknown operators across all adapters. Memory's `MemoryAggregateEndpoint` delegated to its own inline 6-operator switch with a fail-open default (unknown operators matched every record); it now delegates to `matchesFilter()`, the fail-closed single source of truth, and supports all 12 operators. Prisma's aggregate where-builder forwarded unrecognized operator strings verbatim into the Prisma where clause and 500'd on documented operators like `between`/`ilike`; it now validates with `isFilterOperator()` and delegates to `buildPrismaWhere`. Drizzle's aggregate path cast untrusted operator strings and crashed via `assertNever` on unknown operators; it now validates first and pushes a never-true condition instead. In every adapter an unknown operator now matches nothing (count 0) instead of leaking data or crashing.
8
+ - dd62008: Publishing metadata fixes: `CHANGELOG.md` is now included in the published npm artifact (it was missing from the `files` allowlist everywhere except core), and the lazily-loaded libraries `drizzle-zod` (drizzle), `pluralize` and `fastest-levenshtein` (prisma) are now optional peer dependencies — they are dynamically imported with graceful fallbacks, so consumers who don't use those features no longer have to install them.
9
+ - Updated dependencies [dd62008]
10
+ - hono-crud@0.13.9
11
+
12
+ ## 0.1.6
13
+
14
+ ### Patch Changes
15
+
16
+ - 255aaf3: Thread a row/DB type generic through both ORM adapters so query results are typed instead of `unknown`, removing the internal `as ModelObject<...>` laundering casts. Breaking: the Drizzle adapter drops the `DrizzleDatabase`/`DrizzleDB` aliases (use `DrizzleDatabaseConstraint` or the new third `DB` generic on endpoint classes) and its public API no longer references drizzle-orm builder types (`Table`/`Column`/`SQL`); `PrismaModelOperations` gains a `Row` type parameter plus `aggregate`/`groupBy` members.
17
+
18
+ ## 0.1.5
19
+
20
+ ### Patch Changes
21
+
22
+ - b880e53: Type-safety hardening (phase 1): eliminate type/schema drift and silent fall-throughs.
23
+
24
+ - **Unify `HonoOpenAPIApp`.** The publicly re-exported type was a 4-verb subset that disagreed with the 7-verb superset `fromHono` actually returns; both now resolve to one canonical definition, so typing the documented `HonoOpenAPIApp` and calling `.options()`/`.head()`/`.doc()` type-checks.
25
+ - **Closed-union exhaustiveness.** Filter-operator handling now goes through a single shared `matchesFilter` in the in-memory adapter (the four copy-pasted switches had drifted — one was missing `between` and silently matched every row), and the Drizzle/Prisma/aggregate switches gained `assertNever` exhaustiveness guards so a future operator is a compile error rather than a silent gap.
26
+ - **Validate untrusted filter operators.** `parseFilterValue` no longer blindly casts an unrecognized `field[op]=value` token to `FilterOperator` (which downstream adapters silently ignored, disabling the filter); unknown operators now fall back to literal equality. `FilterOperator` is now derived from a single `as const` `FILTER_OPERATORS` source with an `isFilterOperator` guard.
27
+ - **Scalar config.** `@hono-crud/scalar` no longer escapes its own typing via `as Record<string, unknown>`; `ScalarTheme` is derived from the upstream `ApiReferenceConfiguration` and `scalarUI` has an explicit return type.
28
+ - **De-duplicated casts.** Added a localized `readResponseEnvelope(ctx)` accessor and a Drizzle `readCount`/`CountRow` helper, removing repeated inline casts.
29
+
30
+ New exports: `FILTER_OPERATORS`, `isFilterOperator`, `assertNever`, `readResponseEnvelope` (from `hono-crud`); `readCount`/`CountRow` (from `@hono-crud/drizzle`). All additive; no breaking changes.
31
+
32
+ - 18a86c2: Type-safety hardening (phase 2): derive types from single `as const` / Zod sources so the compile-time union and its runtime validators can no longer drift.
33
+
34
+ - **Union single-sources.** `SortDirection`, `SearchMode`, `AggregateOperation`, `JWTAlgorithm` (core) and `DrizzleDialect` (drizzle) are now derived from exported `as const` arrays (`SORT_DIRECTIONS`, `SEARCH_MODES`, `AGGREGATE_OPERATIONS`, `JWT_ALGORITHMS`, `DRIZZLE_DIALECTS`). The three `z.enum(['asc','desc'])` schemas and the `z.enum(['any','all','phrase'])` schema now reference these arrays, and the aggregate query parser derives its runtime operation lists from `AGGREGATE_OPERATIONS` instead of hand-maintained copies.
35
+ - **Removed a redundant type.** The JWT middleware's `HonoAlgorithm` type and its hand-maintained `supported` allow-list were exact duplicates of `JWTAlgorithm`; both are gone (and with them two casts) — `validateAlgorithm` checks against `JWT_ALGORITHMS` directly.
36
+ - **`SortSpec`.** The repeated inline `{ field: string; order: 'asc' | 'desc' }` shape across list/search/builder/functional/config is now the named `SortSpec` type.
37
+ - **Schema-derived shapes.** `EncryptedValue` is inferred from a new `encryptedValueSchema` and `isEncryptedValue` validates with `.safeParse` (one shape, not a hand-written twin). `CrudEventType` is single-sourced from `CRUD_EVENT_TYPES`, and the webhook event-filter template-literal type derives from it, so a new event type can't silently become unfilterable.
38
+
39
+ New additive exports: `SORT_DIRECTIONS`, `SEARCH_MODES`, `AGGREGATE_OPERATIONS`, `SortDirection`, `SortSpec`, `JWT_ALGORITHMS`, `CRUD_EVENT_TYPES`, `encryptedValueSchema` (from `hono-crud`); `DRIZZLE_DIALECTS`, `readCount`, `CountRow` (from `@hono-crud/drizzle`). All derived types are structurally identical to what they replaced — no breaking changes.
40
+
41
+ - Updated dependencies [f8e5208]
42
+ - Updated dependencies [3ab0514]
43
+ - Updated dependencies [0538c4a]
44
+ - Updated dependencies [b880e53]
45
+ - Updated dependencies [a41b5d7]
46
+ - Updated dependencies [18a86c2]
47
+ - hono-crud@0.13.8
48
+
49
+ ## 0.1.4
50
+
51
+ ### Patch Changes
52
+
53
+ - Updated dependencies [245ca0b]
54
+ - hono-crud@0.13.7
55
+
56
+ ## 0.1.3
57
+
58
+ ### Patch Changes
59
+
60
+ - Updated dependencies [3278d26]
61
+ - hono-crud@0.13.6
62
+
63
+ ## 0.1.2
64
+
65
+ ### Patch Changes
66
+
67
+ - Updated dependencies [c95d8dc]
68
+ - hono-crud@0.13.5
69
+
70
+ ## 0.1.1
71
+
72
+ ### Patch Changes
73
+
74
+ - Updated dependencies [6c22eaa]
75
+ - hono-crud@0.13.4
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import {getTableColumns,eq,inArray,between,isNull,isNotNull,ilike,like,notInArray,lte,lt,gte,gt,ne as ne$1,sql,desc,asc,and,or}from'drizzle-orm';import {assertNever,UpsertEndpoint,BatchUpsertEndpoint,VersionHistoryEndpoint,VersionReadEndpoint,VersionCompareEndpoint,VersionRollbackEndpoint,AggregateEndpoint,computeAggregations,SearchEndpoint,searchInMemory,ExportEndpoint,ImportEndpoint,CloneEndpoint,CreateEndpoint,getLogger,ReadEndpoint,UpdateEndpoint,DeleteEndpoint,ListEndpoint,RestoreEndpoint,BatchCreateEndpoint,BatchUpdateEndpoint,BatchDeleteEndpoint,BatchRestoreEndpoint}from'hono-crud/internal';import {z as z$1}from'zod';function G(a){return a}function z(...a){return and(...a)}function B(...a){return or(...a)}var Ke=["sqlite","pg","mysql"];function D(a){if(!a.model.table)throw new Error(`Model ${a.model.tableName} does not have a table reference`);return a.model.table}function h(a,e){let t=getTableColumns(a),r=t[e];if(!r)throw new Error(`Column '${e}' not found in table. Available columns: ${Object.keys(t).join(", ")}`);return r}async function ue(a,e,t,r){if(!r.table)return e;let n=r.table;switch(r.type){case "hasOne":{let o=r.localKey||"id",s=e[o];if(s==null)return e;let i=h(n,r.foreignKey),l=await a.select().from(n).where(eq(i,s)).limit(1);return {...e,[t]:l[0]||null}}case "hasMany":{let o=r.localKey||"id",s=e[o];if(s==null)return {...e,[t]:[]};let i=h(n,r.foreignKey),l=await a.select().from(n).where(eq(i,s));return {...e,[t]:l}}case "belongsTo":{let o=e[r.foreignKey];if(o==null)return {...e,[t]:null};let s=h(n,r.localKey||"id"),i=await a.select().from(n).where(eq(s,o)).limit(1);return {...e,[t]:i[0]||null}}default:return e}}async function de(a,e,t,r){if(!r?.relations?.length||!t.model.relations)return e;let n={...e};for(let o of r.relations){let s=t.model.relations[o];s&&(n=await ue(a,n,o,s));}return n}async function S(a,e,t,r){if(!e.length||!r?.relations?.length||!t.model.relations)return e;let n=e.map(o=>({...o}));for(let o of r.relations){let s=t.model.relations[o];if(!s||!s.table)continue;let i=s.table;switch(s.type){case "hasOne":case "hasMany":{let l=s.localKey||"id",d=[...new Set(n.map(p=>p[l]).filter(p=>p!=null))];if(d.length===0){n=n.map(p=>({...p,[o]:s.type==="hasMany"?[]:null}));continue}let u=h(i,s.foreignKey),c=await a.select().from(i).where(inArray(u,d)),m=new Map;for(let p of c){let g=p[s.foreignKey];m.has(g)||m.set(g,[]),m.get(g).push(p);}n=n.map(p=>{let g=p[l],b=m.get(g)||[];return {...p,[o]:s.type==="hasMany"?b:b[0]||null}});break}case "belongsTo":{let l=s.localKey||"id",d=[...new Set(n.map(p=>p[s.foreignKey]).filter(p=>p!=null))];if(d.length===0){n=n.map(p=>({...p,[o]:null}));continue}let u=h(i,l),c=await a.select().from(i).where(inArray(u,d)),m=new Map;for(let p of c){let g=p[l];m.set(g,p);}n=n.map(p=>{let g=p[s.foreignKey];return {...p,[o]:m.get(g)||null}});break}}}return n}function O(a,e){let t=h(a,e.field);switch(e.operator){case "eq":return eq(t,e.value);case "ne":return ne$1(t,e.value);case "gt":return gt(t,e.value);case "gte":return gte(t,e.value);case "lt":return lt(t,e.value);case "lte":return lte(t,e.value);case "in":return inArray(t,e.value);case "nin":return notInArray(t,e.value);case "like":return like(t,e.value);case "ilike":return ilike(t,e.value);case "null":return e.value?isNull(t):isNotNull(t);case "between":{let[r,n]=e.value;return between(t,r,n)}default:return assertNever(e.operator)}}function k(a){return Number(a[0]?.count)||0}function y(a){let e=a;if(e._tx)return e._tx;if(e.db)return e.db;let t=e.context?.get?.("db");if(t)return t;throw new Error(`Database not configured. Either:
1
+ import {getTableColumns,eq,inArray,between,isNull,isNotNull,ilike,like,notInArray,lte,lt,gte,gt,ne as ne$1,sql,desc,asc,and,or}from'drizzle-orm';import {assertNever,UpsertEndpoint,BatchUpsertEndpoint,VersionHistoryEndpoint,VersionReadEndpoint,VersionCompareEndpoint,VersionRollbackEndpoint,AggregateEndpoint,isFilterOperator,computeAggregations,SearchEndpoint,searchInMemory,ExportEndpoint,ImportEndpoint,CloneEndpoint,CreateEndpoint,getLogger,ReadEndpoint,UpdateEndpoint,DeleteEndpoint,ListEndpoint,RestoreEndpoint,BatchCreateEndpoint,BatchUpdateEndpoint,BatchDeleteEndpoint,BatchRestoreEndpoint}from'hono-crud/internal';import {z as z$1}from'zod';function G(a){return a}function z(...a){return and(...a)}function B(...a){return or(...a)}var Ke=["sqlite","pg","mysql"];function D(a){if(!a.model.table)throw new Error(`Model ${a.model.tableName} does not have a table reference`);return a.model.table}function h(a,e){let t=getTableColumns(a),n=t[e];if(!n)throw new Error(`Column '${e}' not found in table. Available columns: ${Object.keys(t).join(", ")}`);return n}async function ue(a,e,t,n){if(!n.table)return e;let r=n.table;switch(n.type){case "hasOne":{let o=n.localKey||"id",s=e[o];if(s==null)return e;let i=h(r,n.foreignKey),l=await a.select().from(r).where(eq(i,s)).limit(1);return {...e,[t]:l[0]||null}}case "hasMany":{let o=n.localKey||"id",s=e[o];if(s==null)return {...e,[t]:[]};let i=h(r,n.foreignKey),l=await a.select().from(r).where(eq(i,s));return {...e,[t]:l}}case "belongsTo":{let o=e[n.foreignKey];if(o==null)return {...e,[t]:null};let s=h(r,n.localKey||"id"),i=await a.select().from(r).where(eq(s,o)).limit(1);return {...e,[t]:i[0]||null}}default:return e}}async function de(a,e,t,n){if(!n?.relations?.length||!t.model.relations)return e;let r={...e};for(let o of n.relations){let s=t.model.relations[o];s&&(r=await ue(a,r,o,s));}return r}async function S(a,e,t,n){if(!e.length||!n?.relations?.length||!t.model.relations)return e;let r=e.map(o=>({...o}));for(let o of n.relations){let s=t.model.relations[o];if(!s||!s.table)continue;let i=s.table;switch(s.type){case "hasOne":case "hasMany":{let l=s.localKey||"id",d=[...new Set(r.map(p=>p[l]).filter(p=>p!=null))];if(d.length===0){r=r.map(p=>({...p,[o]:s.type==="hasMany"?[]:null}));continue}let u=h(i,s.foreignKey),c=await a.select().from(i).where(inArray(u,d)),m=new Map;for(let p of c){let g=p[s.foreignKey];m.has(g)||m.set(g,[]),m.get(g).push(p);}r=r.map(p=>{let g=p[l],b=m.get(g)||[];return {...p,[o]:s.type==="hasMany"?b:b[0]||null}});break}case "belongsTo":{let l=s.localKey||"id",d=[...new Set(r.map(p=>p[s.foreignKey]).filter(p=>p!=null))];if(d.length===0){r=r.map(p=>({...p,[o]:null}));continue}let u=h(i,l),c=await a.select().from(i).where(inArray(u,d)),m=new Map;for(let p of c){let g=p[l];m.set(g,p);}r=r.map(p=>{let g=p[s.foreignKey];return {...p,[o]:m.get(g)||null}});break}}}return r}function O(a,e){let t=h(a,e.field);switch(e.operator){case "eq":return eq(t,e.value);case "ne":return ne$1(t,e.value);case "gt":return gt(t,e.value);case "gte":return gte(t,e.value);case "lt":return lt(t,e.value);case "lte":return lte(t,e.value);case "in":return inArray(t,e.value);case "nin":return notInArray(t,e.value);case "like":return like(t,e.value);case "ilike":return ilike(t,e.value);case "null":return e.value?isNull(t):isNotNull(t);case "between":{let[n,r]=e.value;return between(t,n,r)}default:return assertNever(e.operator)}}function k(a){return Number(a[0]?.count)||0}function y(a){let e=a;if(e._tx)return e._tx;if(e.db)return e.db;let t=e.context?.get?.("db");if(t)return t;throw new Error(`Database not configured. Either:
2
2
  1. Set db property: db = myDb;
3
3
  2. Use middleware: c.set("db", myDb);
4
- 3. Use factory: createDrizzleCrud(db, meta)`)}function te(a,e,t){switch(t){case "pg":return sql`POSITION(LOWER(${e}) IN LOWER(${a})) > 0`;case "mysql":return sql`LOCATE(LOWER(${e}), LOWER(${a})) > 0`;default:return sql`INSTR(LOWER(${a}), LOWER(${e})) > 0`}}function tt(a){return a.split(/\s+/).filter(e=>e.length>0)}var j=class extends UpsertEndpoint{db;dialect="sqlite";getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async findExisting(e){let t=this.getTable(),r=this.getUpsertKeys(),n=this.getSoftDeleteConfig(),o=[];for(let i of r){let l=e[i];l!==void 0&&o.push(eq(this.getColumn(i),l));}return n.enabled&&o.push(isNull(this.getColumn(n.field))),o.length===0?null:(await this.getDb().select().from(t).where(z(...o)).limit(1))[0]||null}async create(e){let t=this.getTable(),r=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(r).returning())[0]}async update(e,t){let r=this.getTable(),n=this._meta.model.primaryKeys[0],o=e[n];return (await this.getDb().update(r).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(n),o)).returning())[0]}async nativeUpsert(e,t){let r=this.getTable(),n=this.getUpsertKeys(),o=this._meta.model.primaryKeys[0],s=this.getSoftDeleteConfig(),i=this.getTimestampsConfig(),l=this.applyManagedInsertFields(e,"drizzle"),d={};for(let[b,C]of Object.entries(e))!n.includes(b)&&b!==o&&(this.createOnlyFields?.includes(b)||(d[b]=C));i.enabled&&(d[i.updatedAt]=Date.now());let u=n.map(b=>this.getColumn(b)),c;s.enabled&&(c=isNull(this.getColumn(s.field)));let m=Object.keys(d).length>0?d:{[o]:sql`${this.getColumn(o)}`},p=this.getDb().insert(r).values(l);return this.dialect==="mysql"?{data:(await p.onDuplicateKeyUpdate({set:m}).returning())[0],created:false}:{data:(await p.onConflictDoUpdate({target:u,set:m,where:c}).returning())[0],created:false}}},_=class extends BatchUpsertEndpoint{db;dialect="sqlite";getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async findExisting(e){let t=this.getTable(),r=this.getUpsertKeys(),n=[];for(let s of r){let i=e[s];i!==void 0&&n.push(eq(this.getColumn(s),i));}return n.length===0?null:(await this.getDb().select().from(t).where(z(...n)).limit(1))[0]||null}async create(e){let t=this.getTable(),r=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(r).returning())[0]}async update(e,t){let r=this.getTable(),n=this._meta.model.primaryKeys[0],o=e[n];return (await this.getDb().update(r).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(n),o)).returning())[0]}async nativeBatchUpsert(e,t){if(e.length===0)return {items:[],createdCount:0,updatedCount:0,totalCount:0};let r=this.getTable(),n=this.getUpsertKeys(),o=this._meta.model.primaryKeys[0],s=this.getTimestampsConfig(),i=e.map(g=>this.applyManagedInsertFields(g,"drizzle")),l={},d=e[0];for(let g of Object.keys(d))!n.includes(g)&&g!==o&&(this.createOnlyFields?.includes(g)||(l[g]=sql`excluded.${sql.identifier(g)}`));s.enabled&&(l[s.updatedAt]=Date.now());let u=n.map(g=>this.getColumn(g)),c=Object.keys(l).length>0?l:{[o]:sql`${this.getColumn(o)}`},m=this.getDb().insert(r).values(i),p=await(this.dialect==="mysql"?m.onDuplicateKeyUpdate({set:c}):m.onConflictDoUpdate({target:u,set:c})).returning();return {items:p.map((g,b)=>({data:g,created:false,index:b})),createdCount:0,updatedCount:p.length,totalCount:p.length}}},pe=class extends VersionHistoryEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async recordExists(e){let t=this.getTable(),r=await this.getDb().select({count:sql`count(*)`}).from(t).where(eq(this.getColumn("id"),e));return k(r)>0}},ge=class extends VersionReadEndpoint{},me=class extends VersionCompareEndpoint{},he=class extends VersionRollbackEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async rollback(e,t,r){let n=this.getTable(),o=this.getVersioningConfig().field;return (await this.getDb().update(n).set({...t,[o]:r}).where(eq(this.getColumn("id"),e)).returning())[0]}},H=class extends AggregateEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async aggregate(e){let t=this.getTable(),r=[],n=this.getSoftDeleteConfig();if(n.enabled){let{query:i}=await this.getValidatedData();i?.withDeleted===true||i?.withDeleted==="true"||r.push(isNull(this.getColumn(n.field)));}if(e.filters)for(let[i,l]of Object.entries(e.filters))if(typeof l=="object"&&l!==null)for(let[d,u]of Object.entries(l)){let c=O(t,{field:i,operator:d,value:u});c&&r.push(c);}else r.push(eq(this.getColumn(i),l));let o=r.length>0?z(...r):void 0,s=await this.getDb().select().from(t).where(o);return computeAggregations(s,e)}},I=class extends SearchEndpoint{db;dialect="sqlite";getDb(){return y(this)}useNativeSearch=false;vectorColumn;vectorConfig="english";getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async search(e,t){let r=this.getTable(),n=[],o=this.getSoftDeleteConfig();o.enabled&&(t.options.onlyDeleted?n.push(isNotNull(this.getColumn(o.field))):t.options.withDeleted||n.push(isNull(this.getColumn(o.field))));for(let E of t.filters){let M=O(r,E);M&&n.push(M);}let s=this.getSearchableFields(),i=e.fields||Object.keys(s);if(this.useNativeSearch&&this.vectorColumn){let E=this.getColumn(this.vectorColumn),M=e.mode==="phrase"?sql`phraseto_tsquery(${this.vectorConfig}, ${e.query})`:e.mode==="all"?sql`plainto_tsquery(${this.vectorConfig}, ${e.query})`:sql`to_tsquery(${this.vectorConfig}, ${e.query.split(/\s+/).join(" | ")})`;n.push(sql`${E} @@ ${M}`);}else {let E=(M,x)=>{try{let ie=this.getColumn(M);return te(sql`CAST(${ie} AS TEXT)`,x,this.dialect)}catch{return}};if(e.mode==="all"){let M=tt(e.query);if(M.length>0){let x=[];for(let ie of M){let ce=i.map(ae=>E(ae,ie)).filter(ae=>ae!==void 0);ce.length>0&&x.push(B(...ce));}x.length>0&&n.push(z(...x));}}else {let M=i.map(x=>E(x,e.query)).filter(x=>x!==void 0);M.length>0&&n.push(B(...M));}}let l=n.length>0?z(...n):void 0,d=await this.getDb().select({count:sql`count(*)`}).from(r).where(l),u=k(d),c=this.getDb().select().from(r).where(l);if(t.options.order_by){let E=this.getColumn(t.options.order_by),M=t.options.order_by_direction==="desc"?desc:asc;c=c.orderBy(M(E));}let m=t.options.page||1,p=t.options.per_page||this.defaultPerPage;c=c.limit(p).offset((m-1)*p);let g=await c,b=e.mode==="all"?{...e,mode:"any"}:e,C=searchInMemory(g,b,s),R={relations:t.options.include||[]},W=C.map(E=>E.item),se=await S(this.getDb(),W,this._meta,R);return {items:C.map((E,M)=>({...E,item:se[M]})),totalCount:u}}},J=class extends ExportEndpoint{db;dialect="sqlite";getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async list(e){let t=this.getTable(),r=[],n=this.getSoftDeleteConfig();if(n.enabled){let b=this.getColumn(n.field);e.options.onlyDeleted?r.push(isNotNull(b)):e.options.withDeleted||r.push(isNull(b));}for(let b of e.filters){let C=O(t,b);C&&r.push(C);}if(e.options.search&&this.searchFields.length>0){let b=e.options.search,C=this.searchFields.map(R=>{let W=this.getColumn(R);return te(W,b,this.dialect)});r.push(B(...C));}let o=r.length>0?z(...r):void 0,s=await this.getDb().select({count:sql`count(*)`}).from(t).where(o),i=k(s),l=this.getDb().select().from(t).where(o);if(e.options.order_by){let b=this.getColumn(e.options.order_by),C=e.options.order_by_direction==="desc"?desc:asc;l=l.orderBy(C(b));}let d=e.options.page||1,u=e.options.per_page||this.defaultPerPage;l=l.limit(u).offset((d-1)*u);let c=await l,m={relations:e.options.include||[]},p=await S(this.getDb(),c,this._meta,m),g=Math.ceil(i/u);return {result:p,result_info:{page:d,per_page:u,total_count:i,total_pages:g,has_next_page:d<g,has_prev_page:d>1}}}},Y=class extends ImportEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async findExisting(e){let t=this.getTable(),r=this.getUpsertKeys(),n=this.getSoftDeleteConfig(),o=[];for(let i of r){let l=e[i];l!==void 0&&o.push(eq(this.getColumn(i),l));}return n.enabled&&o.push(isNull(this.getColumn(n.field))),o.length===0?null:(await this.getDb().select().from(t).where(z(...o)).limit(1))[0]||null}async create(e){let t=this.getTable(),r=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(r).returning())[0]}async update(e,t){let r=this.getTable(),n=this._meta.model.primaryKeys[0],o=e[n];return (await this.getDb().update(r).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(n),o)).returning())[0]}},ee=class extends CloneEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}generateId(){return crypto.randomUUID()}async findSource(e,t){let r=this.getTable(),n=this.getColumn(this.lookupField),o=this.getSoftDeleteConfig(),s=[eq(n,e)];if(t)for(let[l,d]of Object.entries(t))s.push(eq(this.getColumn(l),d));o.enabled&&s.push(isNull(this.getColumn(o.field)));let i=await this.getDb().select().from(r).where(z(...s)).limit(1);return i[0]?i[0]:null}async createClone(e){let t=this.getTable(),r=this.applyManagedInsertFields(e,"drizzle",()=>this.generateId());return (await this.getDb().insert(t).values(r).returning())[0]}};var q=class extends CreateEndpoint{db;useTransaction=false;getDb(){return y(this)}getTable(){return D(this._meta)}getRelatedTable(e){return e.table}async create(e,t){let r=t??this.getDb(),n=this.getTable(),o=this.applyManagedInsertFields(e,"drizzle");return (await r.insert(n).values(o).returning())[0]}async createNested(e,t,r,n,o){let s=o??this.getDb(),i=this.getRelatedTable(r);if(!i)return getLogger().warn(`Related table not found for ${t}. Add 'table' to the relation config.`),[];let l=Array.isArray(n)?n:[n],d=[];for(let u of l){if(typeof u!="object"||u===null)continue;let c={...u,id:crypto.randomUUID(),[r.foreignKey]:e},m=await s.insert(i).values(c).returning();m[0]&&d.push(m[0]);}return d}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}},U=class extends ReadEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async read(e,t,r){let n=this.getTable(),o=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),i=[eq(o,e)];if(t)for(let[u,c]of Object.entries(t))i.push(eq(this.getColumn(u),c));s.enabled&&i.push(isNull(this.getColumn(s.field)));let l=await this.getDb().select().from(n).where(z(...i)).limit(1);return l[0]?await de(this.getDb(),l[0],this._meta,r):null}},A=class extends UpdateEndpoint{db;useTransaction=false;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}getRelatedTable(e){return e.table}async findExisting(e,t,r){let n=r??this.getDb(),o=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return i.enabled&&l.push(isNull(this.getColumn(i.field))),(await n.select().from(o).where(z(...l)).limit(1))[0]||null}async update(e,t,r,n){let o=n??this.getDb(),s=this.getTable(),i=this.getColumn(this.lookupField),l=this.getSoftDeleteConfig(),d=[eq(i,e)];if(r)for(let[c,m]of Object.entries(r))d.push(eq(this.getColumn(c),m));return l.enabled&&d.push(isNull(this.getColumn(l.field))),(await o.update(s).set(this.applyManagedUpdateFields(t)).where(z(...d)).returning())[0]||null}async processNestedWrites(e,t,r,n,o){let s=o??this.getDb(),i=this.getRelatedTable(r);if(!i)return getLogger().warn(`Related table not found for ${t}. Add 'table' to the relation config.`),{created:[],updated:[],deleted:[],connected:[],disconnected:[]};let l={created:[],updated:[],deleted:[],connected:[],disconnected:[]},d=h(i,r.foreignKey),u=h(i,"id");if(n.create){let c=Array.isArray(n.create)?n.create:[n.create];for(let m of c){if(typeof m!="object"||m===null)continue;let p={...m,id:crypto.randomUUID(),[r.foreignKey]:e},g=await s.insert(i).values(p).returning();g[0]&&l.created.push(g[0]);}}if(n.update)for(let c of n.update){if(!c.id||!(await s.select().from(i).where(z(eq(u,c.id),eq(d,e))).limit(1))[0])continue;let{id:p,...g}=c,b=await s.update(i).set(g).where(eq(u,p)).returning();b[0]&&l.updated.push(b[0]);}if(n.delete)for(let c of n.delete)(await s.delete(i).where(z(eq(u,c),eq(d,e))).returning())[0]&&l.deleted.push(c);if(n.connect)for(let c of n.connect)(await s.update(i).set({[r.foreignKey]:e}).where(eq(u,c)).returning())[0]&&l.connected.push(c);if(n.disconnect)for(let c of n.disconnect)(await s.update(i).set({[r.foreignKey]:null}).where(z(eq(u,c),eq(d,e))).returning())[0]&&l.disconnected.push(c);return l}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}},Z=class extends DeleteEndpoint{db;useTransaction=false;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}getRelatedTable(e){return e.table}async findForDelete(e,t,r){let n=r??this.getDb(),o=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return i.enabled&&l.push(isNull(this.getColumn(i.field))),(await n.select().from(o).where(z(...l)).limit(1))[0]||null}async delete(e,t,r){let n=r??this.getDb(),o=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[d,u]of Object.entries(t))l.push(eq(this.getColumn(d),u));return i.enabled&&l.push(isNull(this.getColumn(i.field))),i.enabled?(await n.update(o).set({[i.field]:new Date}).where(z(...l)).returning())[0]||null:(await n.delete(o).where(z(...l)).returning())[0]||null}async countRelated(e,t,r,n){let o=n??this.getDb(),s=this.getRelatedTable(r);if(!s)return 0;let i=h(s,r.foreignKey),l=await o.select({count:sql`count(*)`}).from(s).where(eq(i,e));return k(l)}async deleteRelated(e,t,r,n){let o=n??this.getDb(),s=this.getRelatedTable(r);if(!s)return 0;let i=h(s,r.foreignKey);return (await o.delete(s).where(eq(i,e)).returning()).length}async nullifyRelated(e,t,r,n){let o=n??this.getDb(),s=this.getRelatedTable(r);if(!s)return 0;let i=h(s,r.foreignKey);return (await o.update(s).set({[r.foreignKey]:null}).where(eq(i,e)).returning()).length}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}},K=class extends ListEndpoint{db;dialect="sqlite";getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async list(e){let t=this.getTable(),r=[],n=this.getSoftDeleteConfig();if(n.enabled){let C=this.getColumn(n.field);e.options.onlyDeleted?r.push(isNotNull(C)):e.options.withDeleted||r.push(isNull(C));}for(let C of e.filters){let R=O(t,C);R&&r.push(R);}if(e.options.search&&this.searchFields.length>0){let C=e.options.search,R=this.searchFields.map(W=>{let se=this.getColumn(W);return te(se,C,this.dialect)});r.push(B(...R));}let o=r.length>0?z(...r):void 0,s=this.getDb(),i=await s.select({count:sql`count(*)`}).from(t).where(o),l=k(i),d=s.select().from(t).where(o);if(e.options.order_by){let C=this.getColumn(e.options.order_by),R=e.options.order_by_direction==="desc"?desc:asc;d=d.orderBy(R(C));}let u=e.options.page||1,c=e.options.per_page||this.defaultPerPage;d=d.limit(c).offset((u-1)*c);let m=await d,p={relations:e.options.include||[]},g=await S(this.getDb(),m,this._meta,p),b=Math.ceil(l/c);return {result:g,result_info:{page:u,per_page:c,total_count:l,total_pages:b,has_next_page:u<b,has_prev_page:u>1}}}},F=class extends RestoreEndpoint{db;useTransaction=false;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async restore(e,t,r){let n=r??this.getDb(),o=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return l.push(isNotNull(this.getColumn(i.field))),(await n.update(o).set({[i.field]:null}).where(z(...l)).returning())[0]||null}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}};var L=class extends BatchCreateEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}async batchCreate(e){let t=this.getTable(),r=e.map(o=>this.applyManagedInsertFields(o,"drizzle"));return await this.getDb().insert(t).values(r).returning()}},N=class extends BatchUpdateEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async batchUpdate(e){let t=this.getTable(),r=this.getColumn(this.lookupField),n=this.getSoftDeleteConfig(),o=[],s=[];for(let i of e){let l=[eq(r,i.id)];n.enabled&&l.push(isNull(this.getColumn(n.field)));let d=await this.getDb().update(t).set(this.applyManagedUpdateFields(i.data)).where(z(...l)).returning();d[0]?o.push(d[0]):s.push(i.id);}return {updated:o,notFound:s}}},$=class extends BatchDeleteEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async batchDelete(e){let t=this.getTable(),r=this.getColumn(this.lookupField),n=this.getSoftDeleteConfig(),o=[inArray(r,e)];n.enabled&&o.push(isNull(this.getColumn(n.field)));let s;n.enabled?s=await this.getDb().update(t).set({[n.field]:new Date}).where(z(...o)).returning():s=await this.getDb().delete(t).where(z(...o)).returning();let i=s,l=new Set(i.map(u=>String(u[this.lookupField]))),d=e.filter(u=>!l.has(u));return {deleted:i,notFound:d}}},Q=class extends BatchRestoreEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async batchRestore(e){let t=this.getTable(),r=this.getColumn(this.lookupField),n=this.getSoftDeleteConfig(),o=[inArray(r,e),isNotNull(this.getColumn(n.field))],i=await this.getDb().update(t).set({[n.field]:null}).where(z(...o)).returning(),l=new Set(i.map(u=>String(u[this.lookupField]))),d=e.filter(u=>!l.has(u));return {restored:i,notFound:d}}};function un(a,e,t){let r=t?.dialect??"sqlite";return {Create:class extends q{_meta=e;db=a},Read:class extends U{_meta=e;db=a},Update:class extends A{_meta=e;db=a},Delete:class extends Z{_meta=e;db=a},List:class extends K{_meta=e;db=a;dialect=r},Restore:class extends F{_meta=e;db=a},Upsert:class extends j{_meta=e;db=a;dialect=r},Search:class extends I{_meta=e;db=a;dialect=r},BatchCreate:class extends L{_meta=e;db=a},BatchUpdate:class extends N{_meta=e;db=a},BatchDelete:class extends ${_meta=e;db=a},BatchRestore:class extends Q{_meta=e;db=a},BatchUpsert:class extends _{_meta=e;db=a;dialect=r}}}var re=null,Ee=false,ne=null;async function oe(){if(Ee){if(ne)throw ne;return re}Ee=true;try{return re=await import('drizzle-zod'),re}catch{throw ne=new Error("drizzle-zod is not installed. Please install it: npm install drizzle-zod"),ne}}async function bt(a,e){return (await oe()).createSelectSchema(a,e)}async function zt(a,e){return (await oe()).createInsertSchema(a,e)}async function Dt(a,e){let t=await oe();return t.createUpdateSchema?t.createUpdateSchema(a,e):t.createInsertSchema(a,e).partial()}async function ft(a,e){let t=await oe(),r=e?.coerceDates!==false,n=r?wt(a):new Set,o=t.createSelectSchema(a,e?.selectRefine),s=t.createInsertSchema(a,e?.insertRefine),i;return t.createUpdateSchema?i=t.createUpdateSchema(a,e?.updateRefine):i=t.createInsertSchema(a,e?.updateRefine).partial(),r&&n.size>0&&(s=Te(s,n),i=Te(i,n)),{select:o,insert:s,update:i}}function yt(){return re!==null}var Ct=z$1.preprocess(a=>{if(a instanceof Date)return a;if(typeof a=="string"){let e=new Date(a);if(!isNaN(e.getTime()))return e}return a},z$1.date()),Mt=z$1.preprocess(a=>{if(a==null)return null;if(a instanceof Date)return a;if(typeof a=="string"){let e=new Date(a);if(!isNaN(e.getTime()))return e}return a},z$1.date().nullable());function wt(a){let e=new Set,t=a;for(let[r,n]of Object.entries(t)){if(r==="_"||r==="$inferInsert"||r==="$inferSelect")continue;let o=n;if(!o||typeof o!="object")continue;let s=String(o.dataType??"").toLowerCase(),i=String(o.columnType??"").toLowerCase(),l=o.config,d=String(l?.dataType??"").toLowerCase();(s.includes("timestamp")||s.includes("date")||s.includes("datetime")||i.includes("pgtimestamp")||i.includes("pgdate")||i.includes("mysqltimestamp")||i.includes("mysqldate")||i.includes("sqlitetimestamp")||d.includes("timestamp")||d.includes("date"))&&e.add(r);}return e}function Te(a,e){if(e.size===0)return a;let t=a.shape,r={};for(let[n,o]of Object.entries(t))if(e.has(n)){let s=o.isOptional?.()??false,i=o.isNullable?.()??false,l=Ct;(i||s)&&(l=Mt),s&&(l=l.optional()),r[n]=l;}else r[n]=o;return z$1.object(r)}var Bn={CreateEndpoint:q,ListEndpoint:K,ReadEndpoint:U,UpdateEndpoint:A,DeleteEndpoint:Z,RestoreEndpoint:F,BatchCreateEndpoint:L,BatchUpdateEndpoint:N,BatchDeleteEndpoint:$,BatchRestoreEndpoint:Q,BatchUpsertEndpoint:_,SearchEndpoint:I,AggregateEndpoint:H,ExportEndpoint:J,ImportEndpoint:Y,UpsertEndpoint:j,CloneEndpoint:ee};export{Ke as DRIZZLE_DIALECTS,Bn as DrizzleAdapters,H as DrizzleAggregateEndpoint,L as DrizzleBatchCreateEndpoint,$ as DrizzleBatchDeleteEndpoint,Q as DrizzleBatchRestoreEndpoint,N as DrizzleBatchUpdateEndpoint,_ as DrizzleBatchUpsertEndpoint,ee as DrizzleCloneEndpoint,q as DrizzleCreateEndpoint,Z as DrizzleDeleteEndpoint,J as DrizzleExportEndpoint,Y as DrizzleImportEndpoint,K as DrizzleListEndpoint,U as DrizzleReadEndpoint,F as DrizzleRestoreEndpoint,I as DrizzleSearchEndpoint,A as DrizzleUpdateEndpoint,j as DrizzleUpsertEndpoint,me as DrizzleVersionCompareEndpoint,pe as DrizzleVersionHistoryEndpoint,ge as DrizzleVersionReadEndpoint,he as DrizzleVersionRollbackEndpoint,S as batchLoadDrizzleRelations,O as buildWhereCondition,G as cast,un as createDrizzleCrud,ft as createDrizzleSchemas,zt as createInsertSchema,bt as createSelectSchema,Dt as createUpdateSchema,h as getColumn,D as getTable,yt as isDrizzleZodAvailable,ue as loadDrizzleRelation,de as loadDrizzleRelations,k as readCount,te as substringMatch};
4
+ 3. Use factory: createDrizzleCrud(db, meta)`)}function te(a,e,t){switch(t){case "pg":return sql`POSITION(LOWER(${e}) IN LOWER(${a})) > 0`;case "mysql":return sql`LOCATE(LOWER(${e}), LOWER(${a})) > 0`;default:return sql`INSTR(LOWER(${a}), LOWER(${e})) > 0`}}function nt(a){return a.split(/\s+/).filter(e=>e.length>0)}var j=class extends UpsertEndpoint{db;dialect="sqlite";getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async findExisting(e){let t=this.getTable(),n=this.getUpsertKeys(),r=this.getSoftDeleteConfig(),o=[];for(let i of n){let l=e[i];l!==void 0&&o.push(eq(this.getColumn(i),l));}return r.enabled&&o.push(isNull(this.getColumn(r.field))),o.length===0?null:(await this.getDb().select().from(t).where(z(...o)).limit(1))[0]||null}async create(e){let t=this.getTable(),n=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(n).returning())[0]}async update(e,t){let n=this.getTable(),r=this._meta.model.primaryKeys[0],o=e[r];return (await this.getDb().update(n).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(r),o)).returning())[0]}async nativeUpsert(e,t){let n=this.getTable(),r=this.getUpsertKeys(),o=this._meta.model.primaryKeys[0],s=this.getSoftDeleteConfig(),i=this.getTimestampsConfig(),l=this.applyManagedInsertFields(e,"drizzle"),d={};for(let[b,M]of Object.entries(e))!r.includes(b)&&b!==o&&(this.createOnlyFields?.includes(b)||(d[b]=M));i.enabled&&(d[i.updatedAt]=Date.now());let u=r.map(b=>this.getColumn(b)),c;s.enabled&&(c=isNull(this.getColumn(s.field)));let m=Object.keys(d).length>0?d:{[o]:sql`${this.getColumn(o)}`},p=this.getDb().insert(n).values(l);return this.dialect==="mysql"?{data:(await p.onDuplicateKeyUpdate({set:m}).returning())[0],created:false}:{data:(await p.onConflictDoUpdate({target:u,set:m,where:c}).returning())[0],created:false}}},_=class extends BatchUpsertEndpoint{db;dialect="sqlite";getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async findExisting(e){let t=this.getTable(),n=this.getUpsertKeys(),r=[];for(let s of n){let i=e[s];i!==void 0&&r.push(eq(this.getColumn(s),i));}return r.length===0?null:(await this.getDb().select().from(t).where(z(...r)).limit(1))[0]||null}async create(e){let t=this.getTable(),n=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(n).returning())[0]}async update(e,t){let n=this.getTable(),r=this._meta.model.primaryKeys[0],o=e[r];return (await this.getDb().update(n).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(r),o)).returning())[0]}async nativeBatchUpsert(e,t){if(e.length===0)return {items:[],createdCount:0,updatedCount:0,totalCount:0};let n=this.getTable(),r=this.getUpsertKeys(),o=this._meta.model.primaryKeys[0],s=this.getTimestampsConfig(),i=e.map(g=>this.applyManagedInsertFields(g,"drizzle")),l={},d=e[0];for(let g of Object.keys(d))!r.includes(g)&&g!==o&&(this.createOnlyFields?.includes(g)||(l[g]=sql`excluded.${sql.identifier(g)}`));s.enabled&&(l[s.updatedAt]=Date.now());let u=r.map(g=>this.getColumn(g)),c=Object.keys(l).length>0?l:{[o]:sql`${this.getColumn(o)}`},m=this.getDb().insert(n).values(i),p=await(this.dialect==="mysql"?m.onDuplicateKeyUpdate({set:c}):m.onConflictDoUpdate({target:u,set:c})).returning();return {items:p.map((g,b)=>({data:g,created:false,index:b})),createdCount:0,updatedCount:p.length,totalCount:p.length}}},pe=class extends VersionHistoryEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async recordExists(e){let t=this.getTable(),n=await this.getDb().select({count:sql`count(*)`}).from(t).where(eq(this.getColumn("id"),e));return k(n)>0}},ge=class extends VersionReadEndpoint{},me=class extends VersionCompareEndpoint{},he=class extends VersionRollbackEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async rollback(e,t,n){let r=this.getTable(),o=this.getVersioningConfig().field;return (await this.getDb().update(r).set({...t,[o]:n}).where(eq(this.getColumn("id"),e)).returning())[0]}},H=class extends AggregateEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async aggregate(e){let t=this.getTable(),n=[],r=this.getSoftDeleteConfig();if(r.enabled){let{query:i}=await this.getValidatedData();i?.withDeleted===true||i?.withDeleted==="true"||n.push(isNull(this.getColumn(r.field)));}if(e.filters)for(let[i,l]of Object.entries(e.filters))if(typeof l=="object"&&l!==null)for(let[d,u]of Object.entries(l)){if(!isFilterOperator(d)){n.push(sql`1 = 0`);continue}let c=O(t,{field:i,operator:d,value:u});c&&n.push(c);}else n.push(eq(this.getColumn(i),l));let o=n.length>0?z(...n):void 0,s=await this.getDb().select().from(t).where(o);return computeAggregations(s,e)}},I=class extends SearchEndpoint{db;dialect="sqlite";getDb(){return y(this)}useNativeSearch=false;vectorColumn;vectorConfig="english";getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async search(e,t){let n=this.getTable(),r=[],o=this.getSoftDeleteConfig();o.enabled&&(t.options.onlyDeleted?r.push(isNotNull(this.getColumn(o.field))):t.options.withDeleted||r.push(isNull(this.getColumn(o.field))));for(let E of t.filters){let C=O(n,E);C&&r.push(C);}let s=this.getSearchableFields(),i=e.fields||Object.keys(s);if(this.useNativeSearch&&this.vectorColumn){let E=this.getColumn(this.vectorColumn),C=e.mode==="phrase"?sql`phraseto_tsquery(${this.vectorConfig}, ${e.query})`:e.mode==="all"?sql`plainto_tsquery(${this.vectorConfig}, ${e.query})`:sql`to_tsquery(${this.vectorConfig}, ${e.query.split(/\s+/).join(" | ")})`;r.push(sql`${E} @@ ${C}`);}else {let E=(C,x)=>{try{let ie=this.getColumn(C);return te(sql`CAST(${ie} AS TEXT)`,x,this.dialect)}catch{return}};if(e.mode==="all"){let C=nt(e.query);if(C.length>0){let x=[];for(let ie of C){let ce=i.map(ae=>E(ae,ie)).filter(ae=>ae!==void 0);ce.length>0&&x.push(B(...ce));}x.length>0&&r.push(z(...x));}}else {let C=i.map(x=>E(x,e.query)).filter(x=>x!==void 0);C.length>0&&r.push(B(...C));}}let l=r.length>0?z(...r):void 0,d=await this.getDb().select({count:sql`count(*)`}).from(n).where(l),u=k(d),c=this.getDb().select().from(n).where(l);if(t.options.order_by){let E=this.getColumn(t.options.order_by),C=t.options.order_by_direction==="desc"?desc:asc;c=c.orderBy(C(E));}let m=t.options.page||1,p=t.options.per_page||this.defaultPerPage;c=c.limit(p).offset((m-1)*p);let g=await c,b=e.mode==="all"?{...e,mode:"any"}:e,M=searchInMemory(g,b,s),R={relations:t.options.include||[]},W=M.map(E=>E.item),se=await S(this.getDb(),W,this._meta,R);return {items:M.map((E,C)=>({...E,item:se[C]})),totalCount:u}}},J=class extends ExportEndpoint{db;dialect="sqlite";getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async list(e){let t=this.getTable(),n=[],r=this.getSoftDeleteConfig();if(r.enabled){let b=this.getColumn(r.field);e.options.onlyDeleted?n.push(isNotNull(b)):e.options.withDeleted||n.push(isNull(b));}for(let b of e.filters){let M=O(t,b);M&&n.push(M);}if(e.options.search&&this.searchFields.length>0){let b=e.options.search,M=this.searchFields.map(R=>{let W=this.getColumn(R);return te(W,b,this.dialect)});n.push(B(...M));}let o=n.length>0?z(...n):void 0,s=await this.getDb().select({count:sql`count(*)`}).from(t).where(o),i=k(s),l=this.getDb().select().from(t).where(o);if(e.options.order_by){let b=this.getColumn(e.options.order_by),M=e.options.order_by_direction==="desc"?desc:asc;l=l.orderBy(M(b));}let d=e.options.page||1,u=e.options.per_page||this.defaultPerPage;l=l.limit(u).offset((d-1)*u);let c=await l,m={relations:e.options.include||[]},p=await S(this.getDb(),c,this._meta,m),g=Math.ceil(i/u);return {result:p,result_info:{page:d,per_page:u,total_count:i,total_pages:g,has_next_page:d<g,has_prev_page:d>1}}}},Y=class extends ImportEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async findExisting(e){let t=this.getTable(),n=this.getUpsertKeys(),r=this.getSoftDeleteConfig(),o=[];for(let i of n){let l=e[i];l!==void 0&&o.push(eq(this.getColumn(i),l));}return r.enabled&&o.push(isNull(this.getColumn(r.field))),o.length===0?null:(await this.getDb().select().from(t).where(z(...o)).limit(1))[0]||null}async create(e){let t=this.getTable(),n=this.applyManagedInsertFields(e,"drizzle");return (await this.getDb().insert(t).values(n).returning())[0]}async update(e,t){let n=this.getTable(),r=this._meta.model.primaryKeys[0],o=e[r];return (await this.getDb().update(n).set(this.applyManagedUpdateFields(t)).where(eq(this.getColumn(r),o)).returning())[0]}},ee=class extends CloneEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}generateId(){return crypto.randomUUID()}async findSource(e,t){let n=this.getTable(),r=this.getColumn(this.lookupField),o=this.getSoftDeleteConfig(),s=[eq(r,e)];if(t)for(let[l,d]of Object.entries(t))s.push(eq(this.getColumn(l),d));o.enabled&&s.push(isNull(this.getColumn(o.field)));let i=await this.getDb().select().from(n).where(z(...s)).limit(1);return i[0]?i[0]:null}async createClone(e){let t=this.getTable(),n=this.applyManagedInsertFields(e,"drizzle",()=>this.generateId());return (await this.getDb().insert(t).values(n).returning())[0]}};var q=class extends CreateEndpoint{db;useTransaction=false;getDb(){return y(this)}getTable(){return D(this._meta)}getRelatedTable(e){return e.table}async create(e,t){let n=t??this.getDb(),r=this.getTable(),o=this.applyManagedInsertFields(e,"drizzle");return (await n.insert(r).values(o).returning())[0]}async createNested(e,t,n,r,o){let s=o??this.getDb(),i=this.getRelatedTable(n);if(!i)return getLogger().warn(`Related table not found for ${t}. Add 'table' to the relation config.`),[];let l=Array.isArray(r)?r:[r],d=[];for(let u of l){if(typeof u!="object"||u===null)continue;let c={...u,id:crypto.randomUUID(),[n.foreignKey]:e},m=await s.insert(i).values(c).returning();m[0]&&d.push(m[0]);}return d}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}},U=class extends ReadEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async read(e,t,n){let r=this.getTable(),o=this.getColumn(this.lookupField),s=this.getSoftDeleteConfig(),i=[eq(o,e)];if(t)for(let[u,c]of Object.entries(t))i.push(eq(this.getColumn(u),c));s.enabled&&i.push(isNull(this.getColumn(s.field)));let l=await this.getDb().select().from(r).where(z(...i)).limit(1);return l[0]?await de(this.getDb(),l[0],this._meta,n):null}},A=class extends UpdateEndpoint{db;useTransaction=false;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}getRelatedTable(e){return e.table}async findExisting(e,t,n){let r=n??this.getDb(),o=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return i.enabled&&l.push(isNull(this.getColumn(i.field))),(await r.select().from(o).where(z(...l)).limit(1))[0]||null}async update(e,t,n,r){let o=r??this.getDb(),s=this.getTable(),i=this.getColumn(this.lookupField),l=this.getSoftDeleteConfig(),d=[eq(i,e)];if(n)for(let[c,m]of Object.entries(n))d.push(eq(this.getColumn(c),m));return l.enabled&&d.push(isNull(this.getColumn(l.field))),(await o.update(s).set(this.applyManagedUpdateFields(t)).where(z(...d)).returning())[0]||null}async processNestedWrites(e,t,n,r,o){let s=o??this.getDb(),i=this.getRelatedTable(n);if(!i)return getLogger().warn(`Related table not found for ${t}. Add 'table' to the relation config.`),{created:[],updated:[],deleted:[],connected:[],disconnected:[]};let l={created:[],updated:[],deleted:[],connected:[],disconnected:[]},d=h(i,n.foreignKey),u=h(i,"id");if(r.create){let c=Array.isArray(r.create)?r.create:[r.create];for(let m of c){if(typeof m!="object"||m===null)continue;let p={...m,id:crypto.randomUUID(),[n.foreignKey]:e},g=await s.insert(i).values(p).returning();g[0]&&l.created.push(g[0]);}}if(r.update)for(let c of r.update){if(!c.id||!(await s.select().from(i).where(z(eq(u,c.id),eq(d,e))).limit(1))[0])continue;let{id:p,...g}=c,b=await s.update(i).set(g).where(eq(u,p)).returning();b[0]&&l.updated.push(b[0]);}if(r.delete)for(let c of r.delete)(await s.delete(i).where(z(eq(u,c),eq(d,e))).returning())[0]&&l.deleted.push(c);if(r.connect)for(let c of r.connect)(await s.update(i).set({[n.foreignKey]:e}).where(eq(u,c)).returning())[0]&&l.connected.push(c);if(r.disconnect)for(let c of r.disconnect)(await s.update(i).set({[n.foreignKey]:null}).where(z(eq(u,c),eq(d,e))).returning())[0]&&l.disconnected.push(c);return l}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}},Z=class extends DeleteEndpoint{db;useTransaction=false;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}getRelatedTable(e){return e.table}async findForDelete(e,t,n){let r=n??this.getDb(),o=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return i.enabled&&l.push(isNull(this.getColumn(i.field))),(await r.select().from(o).where(z(...l)).limit(1))[0]||null}async delete(e,t,n){let r=n??this.getDb(),o=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[d,u]of Object.entries(t))l.push(eq(this.getColumn(d),u));return i.enabled&&l.push(isNull(this.getColumn(i.field))),i.enabled?(await r.update(o).set({[i.field]:new Date}).where(z(...l)).returning())[0]||null:(await r.delete(o).where(z(...l)).returning())[0]||null}async countRelated(e,t,n,r){let o=r??this.getDb(),s=this.getRelatedTable(n);if(!s)return 0;let i=h(s,n.foreignKey),l=await o.select({count:sql`count(*)`}).from(s).where(eq(i,e));return k(l)}async deleteRelated(e,t,n,r){let o=r??this.getDb(),s=this.getRelatedTable(n);if(!s)return 0;let i=h(s,n.foreignKey);return (await o.delete(s).where(eq(i,e)).returning()).length}async nullifyRelated(e,t,n,r){let o=r??this.getDb(),s=this.getRelatedTable(n);if(!s)return 0;let i=h(s,n.foreignKey);return (await o.update(s).set({[n.foreignKey]:null}).where(eq(i,e)).returning()).length}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}},K=class extends ListEndpoint{db;dialect="sqlite";getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async list(e){let t=this.getTable(),n=[],r=this.getSoftDeleteConfig();if(r.enabled){let M=this.getColumn(r.field);e.options.onlyDeleted?n.push(isNotNull(M)):e.options.withDeleted||n.push(isNull(M));}for(let M of e.filters){let R=O(t,M);R&&n.push(R);}if(e.options.search&&this.searchFields.length>0){let M=e.options.search,R=this.searchFields.map(W=>{let se=this.getColumn(W);return te(se,M,this.dialect)});n.push(B(...R));}let o=n.length>0?z(...n):void 0,s=this.getDb(),i=await s.select({count:sql`count(*)`}).from(t).where(o),l=k(i),d=s.select().from(t).where(o);if(e.options.order_by){let M=this.getColumn(e.options.order_by),R=e.options.order_by_direction==="desc"?desc:asc;d=d.orderBy(R(M));}let u=e.options.page||1,c=e.options.per_page||this.defaultPerPage;d=d.limit(c).offset((u-1)*c);let m=await d,p={relations:e.options.include||[]},g=await S(this.getDb(),m,this._meta,p),b=Math.ceil(l/c);return {result:g,result_info:{page:u,per_page:c,total_count:l,total_pages:b,has_next_page:u<b,has_prev_page:u>1}}}},F=class extends RestoreEndpoint{db;useTransaction=false;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async restore(e,t,n){let r=n??this.getDb(),o=this.getTable(),s=this.getColumn(this.lookupField),i=this.getSoftDeleteConfig(),l=[eq(s,e)];if(t)for(let[u,c]of Object.entries(t))l.push(eq(this.getColumn(u),c));return l.push(isNotNull(this.getColumn(i.field))),(await r.update(o).set({[i.field]:null}).where(z(...l)).returning())[0]||null}async handle(){return this.useTransaction?this.getDb().transaction(async e=>{this._tx=e;try{return await super.handle()}finally{this._tx=void 0;}}):super.handle()}};var L=class extends BatchCreateEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}async batchCreate(e){let t=this.getTable(),n=e.map(o=>this.applyManagedInsertFields(o,"drizzle"));return await this.getDb().insert(t).values(n).returning()}},N=class extends BatchUpdateEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async batchUpdate(e){let t=this.getTable(),n=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),o=[],s=[];for(let i of e){let l=[eq(n,i.id)];r.enabled&&l.push(isNull(this.getColumn(r.field)));let d=await this.getDb().update(t).set(this.applyManagedUpdateFields(i.data)).where(z(...l)).returning();d[0]?o.push(d[0]):s.push(i.id);}return {updated:o,notFound:s}}},$=class extends BatchDeleteEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async batchDelete(e){let t=this.getTable(),n=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),o=[inArray(n,e)];r.enabled&&o.push(isNull(this.getColumn(r.field)));let s;r.enabled?s=await this.getDb().update(t).set({[r.field]:new Date}).where(z(...o)).returning():s=await this.getDb().delete(t).where(z(...o)).returning();let i=s,l=new Set(i.map(u=>String(u[this.lookupField]))),d=e.filter(u=>!l.has(u));return {deleted:i,notFound:d}}},Q=class extends BatchRestoreEndpoint{db;getDb(){return y(this)}getTable(){return D(this._meta)}getColumn(e){return h(this.getTable(),e)}async batchRestore(e){let t=this.getTable(),n=this.getColumn(this.lookupField),r=this.getSoftDeleteConfig(),o=[inArray(n,e),isNotNull(this.getColumn(r.field))],i=await this.getDb().update(t).set({[r.field]:null}).where(z(...o)).returning(),l=new Set(i.map(u=>String(u[this.lookupField]))),d=e.filter(u=>!l.has(u));return {restored:i,notFound:d}}};function gn(a,e,t){let n=t?.dialect??"sqlite";return {Create:class extends q{_meta=e;db=a},Read:class extends U{_meta=e;db=a},Update:class extends A{_meta=e;db=a},Delete:class extends Z{_meta=e;db=a},List:class extends K{_meta=e;db=a;dialect=n},Restore:class extends F{_meta=e;db=a},Upsert:class extends j{_meta=e;db=a;dialect=n},Search:class extends I{_meta=e;db=a;dialect=n},BatchCreate:class extends L{_meta=e;db=a},BatchUpdate:class extends N{_meta=e;db=a},BatchDelete:class extends ${_meta=e;db=a},BatchRestore:class extends Q{_meta=e;db=a},BatchUpsert:class extends _{_meta=e;db=a;dialect=n}}}var re=null,Ee=false,ne=null;async function oe(){if(Ee){if(ne)throw ne;return re}Ee=true;try{return re=await import('drizzle-zod'),re}catch{throw ne=new Error("drizzle-zod is not installed. Please install it: npm install drizzle-zod"),ne}}async function zt(a,e){return (await oe()).createSelectSchema(a,e)}async function Dt(a,e){return (await oe()).createInsertSchema(a,e)}async function ft(a,e){let t=await oe();return t.createUpdateSchema?t.createUpdateSchema(a,e):t.createInsertSchema(a,e).partial()}async function yt(a,e){let t=await oe(),n=e?.coerceDates!==false,r=n?Et(a):new Set,o=t.createSelectSchema(a,e?.selectRefine),s=t.createInsertSchema(a,e?.insertRefine),i;return t.createUpdateSchema?i=t.createUpdateSchema(a,e?.updateRefine):i=t.createInsertSchema(a,e?.updateRefine).partial(),n&&r.size>0&&(s=Te(s,r),i=Te(i,r)),{select:o,insert:s,update:i}}function Mt(){return re!==null}var Ct=z$1.preprocess(a=>{if(a instanceof Date)return a;if(typeof a=="string"){let e=new Date(a);if(!isNaN(e.getTime()))return e}return a},z$1.date()),wt=z$1.preprocess(a=>{if(a==null)return null;if(a instanceof Date)return a;if(typeof a=="string"){let e=new Date(a);if(!isNaN(e.getTime()))return e}return a},z$1.date().nullable());function Et(a){let e=new Set,t=a;for(let[n,r]of Object.entries(t)){if(n==="_"||n==="$inferInsert"||n==="$inferSelect")continue;let o=r;if(!o||typeof o!="object")continue;let s=String(o.dataType??"").toLowerCase(),i=String(o.columnType??"").toLowerCase(),l=o.config,d=String(l?.dataType??"").toLowerCase();(s.includes("timestamp")||s.includes("date")||s.includes("datetime")||i.includes("pgtimestamp")||i.includes("pgdate")||i.includes("mysqltimestamp")||i.includes("mysqldate")||i.includes("sqlitetimestamp")||d.includes("timestamp")||d.includes("date"))&&e.add(n);}return e}function Te(a,e){if(e.size===0)return a;let t=a.shape,n={};for(let[r,o]of Object.entries(t))if(e.has(r)){let s=o.isOptional?.()??false,i=o.isNullable?.()??false,l=Ct;(i||s)&&(l=wt),s&&(l=l.optional()),n[r]=l;}else n[r]=o;return z$1.object(n)}var jn={CreateEndpoint:q,ListEndpoint:K,ReadEndpoint:U,UpdateEndpoint:A,DeleteEndpoint:Z,RestoreEndpoint:F,BatchCreateEndpoint:L,BatchUpdateEndpoint:N,BatchDeleteEndpoint:$,BatchRestoreEndpoint:Q,BatchUpsertEndpoint:_,SearchEndpoint:I,AggregateEndpoint:H,ExportEndpoint:J,ImportEndpoint:Y,UpsertEndpoint:j,CloneEndpoint:ee};export{Ke as DRIZZLE_DIALECTS,jn as DrizzleAdapters,H as DrizzleAggregateEndpoint,L as DrizzleBatchCreateEndpoint,$ as DrizzleBatchDeleteEndpoint,Q as DrizzleBatchRestoreEndpoint,N as DrizzleBatchUpdateEndpoint,_ as DrizzleBatchUpsertEndpoint,ee as DrizzleCloneEndpoint,q as DrizzleCreateEndpoint,Z as DrizzleDeleteEndpoint,J as DrizzleExportEndpoint,Y as DrizzleImportEndpoint,K as DrizzleListEndpoint,U as DrizzleReadEndpoint,F as DrizzleRestoreEndpoint,I as DrizzleSearchEndpoint,A as DrizzleUpdateEndpoint,j as DrizzleUpsertEndpoint,me as DrizzleVersionCompareEndpoint,pe as DrizzleVersionHistoryEndpoint,ge as DrizzleVersionReadEndpoint,he as DrizzleVersionRollbackEndpoint,S as batchLoadDrizzleRelations,O as buildWhereCondition,G as cast,gn as createDrizzleCrud,yt as createDrizzleSchemas,Dt as createInsertSchema,zt as createSelectSchema,ft as createUpdateSchema,h as getColumn,D as getTable,Mt as isDrizzleZodAvailable,ue as loadDrizzleRelation,de as loadDrizzleRelations,k as readCount,te as substringMatch};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hono-crud/drizzle",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Drizzle ORM CRUD adapter for hono-crud",
5
5
  "author": "Kauan Guesser <contato@kauan.net>",
6
6
  "license": "MIT",
@@ -33,7 +33,8 @@
33
33
  "files": [
34
34
  "dist",
35
35
  "README.md",
36
- "LICENSE"
36
+ "LICENSE",
37
+ "CHANGELOG.md"
37
38
  ],
38
39
  "engines": {
39
40
  "node": ">=20.19.0"
@@ -42,7 +43,7 @@
42
43
  "access": "public"
43
44
  },
44
45
  "dependencies": {
45
- "hono-crud": "0.13.8"
46
+ "hono-crud": "0.13.9"
46
47
  },
47
48
  "peerDependencies": {
48
49
  "drizzle-orm": ">=0.30.0",
@@ -58,6 +59,11 @@
58
59
  "typescript": "^5.8.3",
59
60
  "zod": "^4.3.5"
60
61
  },
62
+ "peerDependenciesMeta": {
63
+ "drizzle-zod": {
64
+ "optional": true
65
+ }
66
+ },
61
67
  "scripts": {
62
68
  "build": "tsup",
63
69
  "typecheck": "tsc --noEmit",