@stacksjs/orm 0.71.2 → 0.72.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/define-model.d.ts +3 -1
- package/dist/index.js +19 -19
- package/dist/routes.js +1 -1
- package/package.json +4 -4
package/dist/routes.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
var i$=Object.create;var{getPrototypeOf:n$,defineProperty:H$,getOwnPropertyNames:l$}=Object;var t$=Object.prototype.hasOwnProperty;function o$($){return this[$]}var s$,d$,TZ=($,Z,J)=>{var z=$!=null&&typeof $==="object";if(z){var G=Z?s$??=new WeakMap:d$??=new WeakMap,W=G.get($);if(W)return W}J=$!=null?i$(n$($)):{};let K=Z||!$||!$.__esModule?H$(J,"default",{value:$,enumerable:!0}):J;for(let T of l$($))if(!t$.call(K,T))H$(K,T,{get:o$.bind($,T),enumerable:!0});if(z)G.set($,K);return K};var DZ=($,Z)=>()=>(Z||$((Z={exports:{}}).exports,Z),Z.exports);var N$=import.meta.require;import{route as h}from"@stacksjs/router";import{env as p}from"@stacksjs/env";import{projectPath as q$,storagePath as LZ}from"@stacksjs/path";import{createQueryBuilder as XZ,defaultConfig as R$,setConfig as f$}from"@stacksjs/query-builder";import{HttpError as q}from"@stacksjs/error-handling";import{log as z$}from"@stacksjs/logging";function r$($){let Z=$;return Z?.code==="SQLITE_CONSTRAINT_UNIQUE"||Z?.code==="SQLITE_CONSTRAINT"||Z?.code==="23505"||Z?.errno===1062||/unique|duplicate/i.test(Z?.message??"")}function Q$($,Z,J){let z=$;if($ instanceof Error&&typeof z.status==="number"&&Number.isInteger(z.status)&&z.status>=400&&z.status<600){let G={error:$.message};if(z.details!==void 0)G.details=z.details;return{status:z.status,body:G}}if(r$($))return{status:409,body:{error:`${Z} already exists`}};return{status:500,body:{error:`Failed to ${J} ${Z}`,detail:String($)}}}function I($){return $.replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}function K$($){let Z={};for(let[J,z]of Object.entries($))Z[I(J)]=z;return Z}function U$($,Z){let J=String(Z||"").replace(/^\/+|\/+$/g,""),z=String($).replace(/^\/+/,"");return`/api/${J?`${J}/`:""}${z}`}function I$($){if(!$)return null;let Z=$.attributes??{};if(Object.prototype.hasOwnProperty.call(Z,"teamId")||Object.prototype.hasOwnProperty.call(Z,"team_id"))return"team_id";return $.belongsTo?.some((J)=>J==="Team")?"team_id":null}function A$($,Z,J){let z=Object.keys($).find((W)=>I(W)===I(Z));if(Array.isArray(J)){if(z===void 0)return{data:$,error:"Ownership value is required"};if(!J.some((W)=>String(W)===String($[z])))return{data:$,error:"Ownership value is not available to this caller"};return{data:{...$,[Z]:$[z]}}}if(J===null||J===void 0)return{data:$,error:"Caller has no ownership identity"};let G={...$};for(let W of Object.keys(G))if(I(W)===I(Z))delete G[W];return G[Z]=J,{data:G}}function E$($){if(!$)return[];let Z=Object.entries($.attributes??{}).filter(([,J])=>J?.fillable===!0).map(([J])=>J);for(let J of $.belongsTo??[]){if(typeof J!=="string"||!J.trim())continue;let z=I(J.trim()).split("_").filter(Boolean);if(z.length===0)continue;let G=`${z[0]}${z.slice(1).map((W)=>`${W[0]?.toUpperCase()}${W.slice(1)}`).join("")}Id`;Z.push(G)}return[...new Set(Z)]}function L$($,Z){if(!$||Z.length===0)return{};let J={};for(let z of Z){if(z in $){J[z]=$[z];continue}let G=I(z);if(G!==z&&G in $)J[z]=$[G]}return J}function a$($,Z){if($?.name!=="date"||Z instanceof Date||typeof Z!=="string")return Z;let J=/^(\d{4})-(\d{2})-(\d{2})$/.exec(Z);if(!J)return Z;let z=Number(J[1]),G=Number(J[2]),W=Number(J[3]),K=new Date(Date.UTC(z,G-1,W));if(K.getUTCFullYear()!==z||K.getUTCMonth()!==G-1||K.getUTCDate()!==W)return Z;return K}function X$($,Z){if(!Z.length)return $;let J={...$};for(let z of Z)delete J[z],delete J[I(z)];return J}function l($,Z){if(!$||Z.length===0)return $;let J={...$};for(let z of Z)delete J[z],delete J[I(z)];return J}var e$=["id","uuid","created_at","updated_at","deleted_at"];function M$($,Z){let J=new Map;for(let z of[...Object.keys($??{}),...e$]){let G=I(z);if(!/^\w+$/.test(G))continue;J.set(z,G),J.set(G,G)}for(let z of Z)J.delete(z),J.delete(I(z));return J}function j$($,Z,J){if(!Z)return $;let z=String(Z).split(",").map((W)=>W.trim()).filter(Boolean),G=$;for(let W of z){let K=W.startsWith("-"),T=K?W.slice(1):W;if(!/^\w+$/.test(T))continue;let N=J.get(T);if(!N)continue;G=G.orderBy(N,K?"desc":"asc")}return G}var $Z={string:{get:($)=>$!=null?String($):null,set:($)=>$!=null?String($):null},number:{get:($)=>$!=null?Number($):null,set:($)=>$!=null?Number($):null},integer:{get:($)=>$!=null?Math.trunc(Number($)):null,set:($)=>$!=null?Math.trunc(Number($)):null},float:{get:($)=>$!=null?Number.parseFloat(String($)):null,set:($)=>$!=null?Number.parseFloat(String($)):null},boolean:{get:($)=>$===1||$==="1"||$===!0||$==="true",set:($)=>$===!0||$===1||$==="1"||$==="true"?1:0},json:{get:($)=>$==null?null:typeof $==="string"?ZZ($):$,set:($)=>$==null?null:typeof $==="string"?$:JSON.stringify($)},datetime:{get:($)=>$?new Date($):null,set:($)=>$ instanceof Date?$.toISOString():$},date:{get:($)=>$?new Date($):null,set:($)=>$ instanceof Date?$.toISOString().split("T")[0]:$},array:{get:($)=>$==null?[]:Array.isArray($)?$:typeof $==="string"?JZ($):[],set:($)=>$==null?null:Array.isArray($)?JSON.stringify($):$}};function ZZ($){try{return JSON.parse($)}catch{return $}}function JZ($){try{return JSON.parse($)}catch{return[]}}function Y$($,Z,J){if(!$||typeof $!=="object"||!Z||Object.keys(Z).length===0)return $;let z={...$};for(let[G,W]of Object.entries(Z)){let K=typeof W==="string"?$Z[W]:W;if(!K||typeof K[J]!=="function")continue;if(Object.prototype.hasOwnProperty.call(z,G))z[G]=K[J](z[G]);let T=I(G);if(T!==G&&Object.prototype.hasOwnProperty.call(z,T))z[T]=K[J](z[T])}return z}function V$($,Z,J){let z=Z?.attributes??{},G={};for(let[W,K]of Object.entries(z)){let T=K?.validation?.rule;if(!T||typeof T.validate!=="function")continue;let N=Object.prototype.hasOwnProperty.call($,W);if(!N&&J==="updating")continue;let Y=K!==null&&typeof K==="object"&&Object.prototype.hasOwnProperty.call(K,"default"),R=N?$[W]:Y?K.default:void 0,f=a$(T,R),F=T.validate(f);if(!F?.valid&&Array.isArray(F?.errors)&&F.errors.length>0)G[W]=F.errors.map((v)=>K?.validation?.message?.[v?.code]??v?.message??"invalid")}return Object.keys(G).length===0?{valid:!0}:{valid:!1,errors:G}}function B$($){return $.replace(/\{[^}]*\}/g,"{}").replace(/:[^/]+/g,"{}")}function W$($){if(Array.isArray($))return $.filter((Z)=>typeof Z==="string"&&Z.length>0);return typeof $==="string"&&$?[$]:[]}function S$($){let Z=typeof $==="object"&&$!==null&&"middleware"in $,J=$?.middleware;if(!Z)return{read:["auth"],write:["auth"],declared:!1};if(J&&typeof J==="object"&&!Array.isArray(J)){let G=J;return{read:"read"in G?W$(G.read):["auth"],write:"write"in G?W$(G.write):["auth"],declared:!0}}let z=W$(J);return{read:z,write:z,declared:!0}}var O$=15,zZ=100;function F$($){let Z=Number.parseInt($.get("page")||String(1),10),J=Number.isFinite(Z)?Math.max(1,Z):1,z=Number.parseInt($.get("per_page")||String(O$),10),G=Math.min(Number.isFinite(z)?Math.max(1,z):O$,zZ);return{page:J,perPage:G,offset:(J-1)*G}}function e($,Z){let J=new URL($.toString());return J.searchParams.set("page",String(Z)),`${J.pathname}${J.search}`}function $$($,Z,J,z,G,W){let K=(Z-1)*J,T=z===0,N={page:Z,per_page:J,from:T?null:K+1,to:T?null:K+z,has_more_pages:G,prev_page_url:Z>1?e($,Z-1):null,next_page_url:G?e($,Z+1):null};if(W!==void 0&&!Number.isNaN(W)){let Y=Math.max(1,Math.ceil(W/J));N.total=W,N.last_page=Y,N.first_page_url=e($,1),N.last_page_url=e($,Y)}return N}function T$($,Z,J,z,G,W){let{page:K,...T}=$$($,Z,J,z,G,W);return{current_page:K,...T}}import{readdirSync as GZ}from"fs";import{basename as WZ,extname as P$,join as QZ}from"path";function KZ($){let Z=[],J=(z)=>{let G;try{G=GZ(z,{withFileTypes:!0})}catch{return}for(let W of G){let K=QZ(z,W.name);if(W.isDirectory()){J(K);continue}if(![".ts",".js"].includes(P$(W.name)))continue;if(W.name.startsWith(".")||W.name.startsWith("index"))continue;Z.push(K)}};return J($),Z.sort()}async function C$($,Z,J){for(let z of KZ($))try{let G=P$(z),W=await import(`${z}?t=${Date.now()}`),K=W.default??W,T=K.name??WZ(z,G);Z[T]={...K,name:T}}catch(G){J?.(z,G)}}async function k$($){let Z={};return await C$($.defaultsRoot,Z,$.onImportError),await C$($.userRoot,Z,$.onImportError),Z}var YZ=q$("config/qb.ts");try{let $=(await import(YZ)).default;f$($??R$)}catch{z$.debug("[orm] No config/qb.ts override found \u2014 deriving config from DB_CONNECTION");let $=p.DB_CONNECTION||"sqlite";f$({...R$,dialect:$,database:$==="sqlite"?{database:p.DB_DATABASE_PATH||"database/stacks.sqlite"}:{database:p.DB_DATABASE||"stacks",host:p.DB_HOST||"127.0.0.1",port:p.DB_PORT||($==="postgres"?5432:3306),username:p.DB_USERNAME||($==="postgres"?"postgres":"root"),password:p.DB_PASSWORD||""}})}var D$=await k$({defaultsRoot:LZ("framework/defaults/app/Models"),userRoot:q$("app/Models"),onImportError:($,Z)=>z$.warn(`[orm] Could not load model ${$}: ${Z.message}`)}),S=XZ();function u($,Z){let J=B$(Z);return h.routes.some((z)=>z.method===$&&B$(String(z.path??""))===J)}function v$($){if(!$.attributes)return[];return Object.entries($.attributes).filter(([Z,J])=>J.hidden===!0).map(([Z])=>Z)}function g$($){if($.endsWith("y")&&!/[aeiou]y$/i.test($))return`${$.slice(0,-1)}ies`;if(/(?:s|x|z|ch|sh)$/i.test($))return`${$}es`;return`${$}s`}async function y$($,Z,J,z){if(!$.length)return $;let G=J.split(",").map((Y)=>Y.trim()).filter(Boolean);if(!G.length)return $;let W=Array.isArray(Z.belongsTo)?Z.belongsTo:[],K=Array.isArray(Z.hasMany)?Z.hasMany:[],T=Array.isArray(Z.hasOne)?Z.hasOne:[],N=new Map;for(let Y of W)N.set(I(Y),{kind:"belongsTo",modelName:Y});for(let Y of T)N.set(I(Y),{kind:"hasOne",modelName:Y});for(let Y of K)N.set(g$(I(Y)),{kind:"hasMany",modelName:Y});for(let Y of G){let R=N.get(Y);if(!R)continue;let f=z[R.modelName];if(!f)continue;let F=f.table||g$(I(R.modelName)),v=v$(f),G$=(w)=>l(r(w,f),v);if(R.kind==="belongsTo"||R.kind==="hasOne"){let w=`${I(R.modelName)}_id`,y=[...new Set($.map((E)=>E[w]).filter((E)=>E!=null))];if(!y.length){for(let E of $)E[Y]=null;continue}let i=await S.selectFrom(F).whereIn("id",y).get(),P=new Map;for(let E of i??[])P.set(String(E.id),G$(E));for(let E of $)E[Y]=P.get(String(E[w]))??null}else{let w=String(Z.name??""),y=`${I(w)}_id`,i=[...new Set($.map((X)=>X.id).filter((X)=>X!=null))];if(!i.length){for(let X of $)X[Y]=[];continue}let P=await S.selectFrom(F).whereIn(y,i).get(),E=new Map;for(let X of P??[]){let Q=String(X[y]),L=E.get(Q)??[];L.push(G$(X)),E.set(Q,L)}for(let X of $)X[Y]=E.get(String(X.id))??[]}}return $}async function c$($,Z){let J=Z?.set;if(!J||typeof J!=="object")return $;let z={...$};for(let[G,W]of Object.entries(J)){if(typeof W!=="function"||!(G in z))continue;try{z[G]=await W(z)}catch{}}return z}function b$($,Z){return Y$($,Z?.casts,"set")}function r($,Z){return Y$($,Z?.casts,"get")}function V($,Z=200){return new Response(JSON.stringify($),{status:Z,headers:{"Content-Type":"application/json"}})}var Z$=1048576;async function x$($){if(Number($.headers?.get?.("content-length")??0)>Z$)throw new q(413,`Request body exceeds ${Z$}-byte limit`);if($.jsonBody&&typeof $.jsonBody==="object")return $.jsonBody;if($.formBody&&typeof $.formBody==="object")return $.formBody;try{let J=await $.clone().text();if(J.length>Z$)throw new q(413,`Request body exceeds ${Z$}-byte limit`);if(!J)return{};let z=JSON.parse(J);return z&&typeof z==="object"&&!Array.isArray(z)?z:{}}catch(J){if(J instanceof q)throw J;throw new q(400,`Invalid JSON body: ${J.message}`)}}function J$($){if($==null)return null;if(typeof $==="number")return Number.isFinite($)&&$>0?$:null;if(typeof $==="string"){let Z=$.trim();if(!Z)return null;if(/^\d+$/.test(Z)){let J=Number(Z);return Number.isFinite(J)&&J>0?J:null}return Z}return null}function w$($){let Z=$.bearerToken;if(typeof Z==="function"){let z=Z.call($);if(z)return z}let J=$.headers?.get?.("authorization")||$.headers?.get?.("Authorization")||"";if(typeof J==="string"&&J.startsWith("Bearer "))return J.substring(7);return null}async function t($){let Z=$._authenticatedUser;if(Z)return Z;let J=w$($);if(!J)return null;try{let{Auth:z}=await import("@stacksjs/auth"),G=await z.getUserFromToken(J);if(G)$._authenticatedUser=G;return G||null}catch{return null}}function d($,Z){if($==null||Z==null)return!1;if(Array.isArray(Z))return Z.some((J)=>String(J)===String($));return String($)===String(Z)}function VZ($){let Z=w$($),J=$.headers?.get?.("cookie")||"";return{bearerToken:()=>Z,cookies:{get:(z)=>{for(let G of J.split(";")){let W=G.indexOf("=");if(W===-1)continue;if(G.slice(0,W).trim()===z)return decodeURIComponent(G.slice(W+1).trim())}return null}}}}function m$($){if($?.ownership)return $.ownership;let Z=I$($);if(!Z)return null;return{field:Z,resolve:async(J,z)=>{let{resolveAuthenticatedTeamId:G}=await import("@stacksjs/auth");return G(VZ(z))}}}async function o($,Z,J){let z=m$($);if(!z||!z.field||typeof z.resolve!=="function")return{enforced:!1,value:null,field:"",bypass:!1};let G=typeof z.bypass==="function"?!!z.bypass(Z,J):!1,W=null;try{W=await z.resolve(Z,J)}catch{W=null}return{enforced:!0,value:W,field:String(z.field),bypass:G}}async function h$($,Z,J,z){let G=$?.authedFill?.[Z];if(!G)return{};if(typeof G==="function")try{let W=await G(J,z);return W&&typeof W==="object"?W:{}}catch{return{}}if(typeof G==="object"){let W={};for(let[K,T]of Object.entries(G))try{W[K]=typeof T==="function"?await T(J,z):T}catch{}return W}return{}}for(let[$,Z]of Object.entries(D$)){let J=Z.traits?.useApi;if(!J)continue;let z=typeof J==="object"?J:{},G=z.uri||Z.table||$.toLowerCase()+"s",W=z.routes||["index","show","store","update","destroy"],K=Z.table||G,T=E$(Z),N=v$(Z),Y=U$(G,z.prefix),R=M$(Z.attributes,N),{read:f,write:F,declared:v}=S$(J);if(["store","update","destroy"].some((X)=>W.includes(X))&&v&&F.length===0)z$.warn(`[orm] ${$}: registering UNAUTHENTICATED mutating routes at ${Y} (explicit \`middleware: []\` opt-out)`);if(["index","show"].some((X)=>W.includes(X))&&v&&f.length===0)z$.debug(`[orm] ${$}: registering public read routes at ${Y} (declared \`middleware.read: []\`)`);let y=!!m$(Z),i=y&&!f.includes("auth")?["auth",...f]:f,P=(X,Q=i)=>{let L=X;for(let B of Q)if(L&&typeof L.middleware==="function")L=L.middleware(B);return L};if(W.includes("index")&&!u("GET",Y))P(h.get(Y,async(X)=>{try{let Q=new URL(X.url),{page:L,perPage:B,offset:H}=F$(Q.searchParams),_=Q.searchParams.get("sort"),D=S.selectFrom(K);D=j$(D,_,R);let k=new Set(["page","per_page","sort","fields","search","include","limit","offset","with_count","withTrashed","onlyTrashed"]);for(let[M,j]of Q.searchParams.entries()){if(k.has(M)||!j)continue;if(!/^[a-z_][a-z0-9_]*$/i.test(M))continue;let m=R.get(M);if(m)D=D.where(m,"=",j)}let U=Q.searchParams.get("search");if(U&&T.length>0){let M=T.slice(0,5);D=D.where((j)=>{for(let m of M)j=j.orWhere(I(m),"like",`%${U}%`);return j})}let A=Q.searchParams.get("fields");if(A){let M=A.split(",").map((j)=>j.trim()).filter((j)=>/^[a-z_][a-z0-9_]*$/i.test(j)).map((j)=>I(j));if(M.length>0)D=D.select(M)}let C=!!Z.traits?.useSoftDeletes,O=Q.searchParams.get("withTrashed")==="true",g=Q.searchParams.get("onlyTrashed")==="true";if(C&&!O)D=g?D.whereNotNull("deleted_at"):D.whereNull("deleted_at");let x=y?await o(Z,await t(X),X):{enforced:!1,value:null,field:"",bypass:!1};if(x.enforced&&!x.bypass){if(x.value==null||Array.isArray(x.value)&&x.value.length===0){let M=T$(Q,L,B,0,!1,void 0);return new Response(JSON.stringify({data:[],...M,meta:$$(Q,L,B,0,!1,void 0)}),{status:200,headers:{"Content-Type":"application/json","Cache-Control":"private, no-store",Vary:"Authorization"}})}D=Array.isArray(x.value)?D.where(x.field,"in",x.value):D.where(x.field,"=",x.value)}let c=await D.limit(B+1).offset(H).get()||[],b=c.length>B,s=(b?c.slice(0,B):c).map((M)=>l(r(M,Z),N)),_$=Q.searchParams.get("include");if(_$)s=await y$(s,Z,_$,D$);let p$=Q.searchParams.get("with_count")==="true",n;if(p$)try{let M=S.selectFrom(K);if(x.enforced&&!x.bypass&&x.value!=null)M=Array.isArray(x.value)?M.where(x.field,"in",x.value):M.where(x.field,"=",x.value);let j=await M.count(),m=typeof j==="number"?j:Number(j?.count??j);if(Number.isFinite(m))n=m}catch{}let a={"Content-Type":"application/json"};if(n!==void 0&&!Number.isNaN(n))a["X-Total-Count"]=String(n);a["Cache-Control"]=x.enforced&&!x.bypass?"private, no-store":"public, max-age=15, must-revalidate",a.Vary="Authorization";let u$=T$(Q,L,B,s.length,b,n);return new Response(JSON.stringify({data:s,...u$,meta:$$(Q,L,B,s.length,b,n)}),{status:200,headers:a})}catch(Q){if(Q instanceof q){let L={error:Q.message};if(Q.details!==void 0)L.details=Q.details;return V(L,Q.status||400)}return V({error:`Failed to fetch ${G}`,detail:String(Q)},500)}}));if(W.includes("show")&&!u("GET",`${Y}/{id}`))P(h.get(`${Y}/{id}`,async(X)=>{try{let Q=J$(X.params?.id);if(Q==null)return V({error:"Invalid ID parameter"},400);let L=await S.selectFrom(K).where({id:Q}).executeTakeFirst();if(!L)return V({error:`${$} not found`},404);let B=new URL(X.url);if(Z.traits?.useSoftDeletes&&L.deleted_at&&B.searchParams.get("withTrashed")!=="true")return V({error:`${$} not found`},404);let H=y?await o(Z,await t(X),X):{enforced:!1,value:null,field:"",bypass:!1};if(H.enforced&&!H.bypass){if(H.value==null||!d(L[H.field],H.value))return V({error:`${$} not found`},404)}let _=l(r(L,Z),N),D=B.searchParams.get("include");if(D){let[O]=await y$([_],Z,D,D$);_=O}let k=_?.updated_at||_?.created_at,U=k?`W/"${_.id}-${String(k)}"`:void 0,A=X.headers?.get?.("if-none-match");if(U&&A&&A===U)return new Response(null,{status:304,headers:{ETag:U}});let C={"Content-Type":"application/json"};if(U)C.ETag=U;return C["Cache-Control"]=H.enforced&&!H.bypass?"private, no-store":"public, max-age=30, must-revalidate",C.Vary="Authorization",new Response(JSON.stringify({data:_}),{status:200,headers:C})}catch(Q){if(Q instanceof q){let L={error:Q.message};if(Q.details!==void 0)L.details=Q.details;return V(L,Q.status||400)}return V({error:`Failed to fetch ${$}`,detail:String(Q)},500)}}));if(W.includes("store")&&!u("POST",Y))P(h.post(Y,async(X)=>{try{let Q=await x$(X),L=X$(Q,N),B=L$(L,T),H=await t(X);if(H){let O=await h$(Z,"creating",H,X);for(let[g,x]of Object.entries(O))if(x!==void 0&&x!==null&&B[g]===void 0)B[g]=x}let _=await o(Z,H,X);if(_.enforced&&!_.bypass){if(!H)return V({error:"Auth required"},401);let O=A$(B,_.field,_.value);if(O.error)return V({error:O.error},403);B=O.data}if(Object.keys(B).length===0)return V({error:"No fillable fields provided"},422);let D=V$(B,Z,"creating");if(!D.valid)return V({success:!1,message:"Validation failed",errors:D.errors},422);if(Z.traits?.useTimestamps!==!1){let O=new Date().toISOString();B.created_at=O,B.updated_at=O}let k=await c$(B,Z),U=K$(b$(k,Z)),A=await S.insertInto(K).values(U).execute(),C=U;try{let O=A?.lastInsertRowid??A?.insertId??A;if(O){let g=await S.selectFrom(K).where({id:O}).executeTakeFirst();if(g)C=g}}catch{}return V({data:l(r(C,Z),N)},201)}catch(Q){let{status:L,body:B}=Q$(Q,$,"create");return V(B,L)}}),F);if(W.includes("update")){let X=async(Q)=>{try{let L=J$(Q.params?.id);if(L==null)return V({error:"Invalid ID parameter"},400);let B=await x$(Q),H=X$(B,N),_=L$(H,T),D=await t(Q);if(D){let x=await h$(Z,"updating",D,Q);for(let[c,b]of Object.entries(x))if(b!==void 0&&b!==null&&_[c]===void 0)_[c]=b}if(Object.keys(_).length===0)return V({error:"No fillable fields provided"},422);let k=V$(_,Z,"updating");if(!k.valid)return V({success:!1,message:"Validation failed",errors:k.errors},422);let U=await S.selectFrom(K).where({id:L}).executeTakeFirst();if(!U)return V({error:`${$} not found`},404);let A=await o(Z,D,Q);if(A.enforced&&!A.bypass){if(!D)return V({error:"Auth required"},401);let x=U[A.field];if(!d(x,A.value))return V({error:`Not your ${$}`},403);let c=Object.keys(_).find((b)=>I(b)===I(A.field));if(c!==void 0&&!d(_[c],A.value))return V({error:`Cannot reassign ${$} ownership`},403)}if(Z.traits?.useTimestamps!==!1)_.updated_at=new Date().toISOString();let C=await c$(_,Z),O=K$(b$(C,Z));await S.updateTable(K).set(O).where({id:L}).execute();let g={...U,...O};try{let x=await S.selectFrom(K).where({id:L}).executeTakeFirst();if(x)g=x}catch{}return V({data:l(r(g,Z),N)})}catch(L){let{status:B,body:H}=Q$(L,$,"update");return V(H,B)}};if(!u("PUT",`${Y}/{id}`))P(h.put(`${Y}/{id}`,X),F);if(!u("PATCH",`${Y}/{id}`))P(h.patch(`${Y}/{id}`,X),F)}let E=!!Z.traits?.useSoftDeletes;if(W.includes("destroy")&&!u("DELETE",`${Y}/{id}`))P(h.delete(`${Y}/{id}`,async(X)=>{try{let Q=J$(X.params?.id);if(Q==null)return V({error:"Invalid ID parameter"},400);let L=await S.selectFrom(K).where({id:Q}).executeTakeFirst();if(!L)return V({error:`${$} not found`},404);let B=await t(X),H=await o(Z,B,X);if(H.enforced&&!H.bypass){if(!B)return V({error:"Auth required"},401);let _=L[H.field];if(!d(_,H.value))return V({error:`Not your ${$}`},403)}if(E){let _=new Date().toISOString();await S.updateTable(K).set({deleted_at:_,updated_at:_}).where({id:Q}).execute()}else await S.deleteFrom(K).where({id:Q}).execute();return new Response(null,{status:204})}catch(Q){if(Q instanceof q){let L={error:Q.message};if(Q.details!==void 0)L.details=Q.details;return V(L,Q.status||400)}return V({error:`Failed to delete ${$}`,detail:String(Q)},500)}}),F);if(W.includes("destroy")&&!u("POST",`${Y}/bulk-delete`))P(h.post(`${Y}/bulk-delete`,async(X)=>{try{let L=(await x$(X))?.ids;if(!Array.isArray(L)||L.length===0)return V({error:"An array of IDs is required"},422);if(L.length>100)return V({error:"Cannot delete more than 100 records at once"},422);let B=[],H=[];for(let U of L){let A=J$(U);if(A!=null)B.push(A);else H.push(U)}if(H.length>0)return V({error:"Invalid IDs in batch",invalid:H},422);let _=await t(X),D=await o(Z,_,X);if(D.enforced&&!D.bypass){if(!_)return V({error:"Auth required"},401);if(D.value==null)return V({error:"Caller has no ownership identity"},403);let U=await S.selectFrom(K).select(["id",D.field]).execute(),A=new Set(U.filter((O)=>d(O[D.field],D.value)).map((O)=>String(O.id))),C=B.filter((O)=>!A.has(String(O)));if(C.length>0)return V({error:`Cannot delete ${$} you don't own`,ids:C},403)}let k=new Date().toISOString();for(let U of B)if(E)await S.updateTable(K).set({deleted_at:k,updated_at:k}).where({id:U}).execute();else await S.deleteFrom(K).where({id:U}).execute();return V({message:`Successfully deleted ${B.length} ${G}`})}catch(Q){if(Q instanceof q){let L={error:Q.message};if(Q.details!==void 0)L.details=Q.details;return V(L,Q.status||400)}return V({error:`Failed to bulk delete ${G}`,detail:String(Q)},500)}}),F)}var kZ=h;export{kZ as default};
|
|
2
|
+
var u$=Object.defineProperty;var i$=($)=>$;function n$($,Z){this[$]=i$.bind(null,Z)}var LZ=($,Z)=>{for(var J in Z)u$($,J,{get:Z[J],enumerable:!0,configurable:!0,set:n$.bind(Z,J)})};var XZ=($,Z)=>()=>($&&(Z=$($=0)),Z);var H$=import.meta.require;import{route as h}from"@stacksjs/router";import{env as p}from"@stacksjs/env";import{projectPath as h$,storagePath as zZ}from"@stacksjs/path";import{createQueryBuilder as GZ,defaultConfig as k$,setConfig as R$}from"@stacksjs/query-builder";import{HttpError as q}from"@stacksjs/error-handling";import{log as z$}from"@stacksjs/logging";function l$($){let Z=$;return Z?.code==="SQLITE_CONSTRAINT_UNIQUE"||Z?.code==="SQLITE_CONSTRAINT"||Z?.code==="23505"||Z?.errno===1062||/unique|duplicate/i.test(Z?.message??"")}function Q$($,Z,J){let z=$;if($ instanceof Error&&typeof z.status==="number"&&Number.isInteger(z.status)&&z.status>=400&&z.status<600){let G={error:$.message};if(z.details!==void 0)G.details=z.details;return{status:z.status,body:G}}if(l$($))return{status:409,body:{error:`${Z} already exists`}};return{status:500,body:{error:`Failed to ${J} ${Z}`,detail:String($)}}}function I($){return $.replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}function K$($){let Z={};for(let[J,z]of Object.entries($))Z[I(J)]=z;return Z}function O$($,Z){let J=String(Z||"").replace(/^\/+|\/+$/g,""),z=String($).replace(/^\/+/,"");return`/api/${J?`${J}/`:""}${z}`}function U$($){if(!$)return null;let Z=$.attributes??{};if(Object.prototype.hasOwnProperty.call(Z,"teamId")||Object.prototype.hasOwnProperty.call(Z,"team_id"))return"team_id";return $.belongsTo?.some((J)=>J==="Team")?"team_id":null}function I$($,Z,J){let z=Object.keys($).find((W)=>I(W)===I(Z));if(Array.isArray(J)){if(z===void 0)return{data:$,error:"Ownership value is required"};if(!J.some((W)=>String(W)===String($[z])))return{data:$,error:"Ownership value is not available to this caller"};return{data:{...$,[Z]:$[z]}}}if(J===null||J===void 0)return{data:$,error:"Caller has no ownership identity"};let G={...$};for(let W of Object.keys(G))if(I(W)===I(Z))delete G[W];return G[Z]=J,{data:G}}function A$($){if(!$)return[];let Z=Object.entries($.attributes??{}).filter(([,J])=>J?.fillable===!0).map(([J])=>J);for(let J of $.belongsTo??[]){if(typeof J!=="string"||!J.trim())continue;let z=I(J.trim()).split("_").filter(Boolean);if(z.length===0)continue;let G=`${z[0]}${z.slice(1).map((W)=>`${W[0]?.toUpperCase()}${W.slice(1)}`).join("")}Id`;Z.push(G)}return[...new Set(Z)]}function L$($,Z){if(!$||Z.length===0)return{};let J={};for(let z of Z){if(z in $){J[z]=$[z];continue}let G=I(z);if(G!==z&&G in $)J[z]=$[G]}return J}function t$($,Z){if($?.name!=="date"||Z instanceof Date||typeof Z!=="string")return Z;let J=/^(\d{4})-(\d{2})-(\d{2})$/.exec(Z);if(!J)return Z;let z=Number(J[1]),G=Number(J[2]),W=Number(J[3]),K=new Date(Date.UTC(z,G-1,W));if(K.getUTCFullYear()!==z||K.getUTCMonth()!==G-1||K.getUTCDate()!==W)return Z;return K}function X$($,Z){if(!Z.length)return $;let J={...$};for(let z of Z)delete J[z],delete J[I(z)];return J}function l($,Z){if(!$||Z.length===0)return $;let J={...$};for(let z of Z)delete J[z],delete J[I(z)];return J}var o$=["id","uuid","created_at","updated_at","deleted_at"];function E$($,Z){let J=new Map;for(let z of[...Object.keys($??{}),...o$]){let G=I(z);if(!/^\w+$/.test(G))continue;J.set(z,G),J.set(G,G)}for(let z of Z)J.delete(z),J.delete(I(z));return J}function M$($,Z,J){if(!Z)return $;let z=String(Z).split(",").map((W)=>W.trim()).filter(Boolean),G=$;for(let W of z){let K=W.startsWith("-"),D=K?W.slice(1):W;if(!/^\w+$/.test(D))continue;let N=J.get(D);if(!N)continue;G=G.orderBy(N,K?"desc":"asc")}return G}var s$={string:{get:($)=>$!=null?String($):null,set:($)=>$!=null?String($):null},number:{get:($)=>$!=null?Number($):null,set:($)=>$!=null?Number($):null},integer:{get:($)=>$!=null?Math.trunc(Number($)):null,set:($)=>$!=null?Math.trunc(Number($)):null},float:{get:($)=>$!=null?Number.parseFloat(String($)):null,set:($)=>$!=null?Number.parseFloat(String($)):null},boolean:{get:($)=>$===1||$==="1"||$===!0||$==="true",set:($)=>$===!0||$===1||$==="1"||$==="true"?1:0},json:{get:($)=>$==null?null:typeof $==="string"?d$($):$,set:($)=>$==null?null:typeof $==="string"?$:JSON.stringify($)},datetime:{get:($)=>$?new Date($):null,set:($)=>$ instanceof Date?$.toISOString():$},date:{get:($)=>$?new Date($):null,set:($)=>$ instanceof Date?$.toISOString().split("T")[0]:$},array:{get:($)=>$==null?[]:Array.isArray($)?$:typeof $==="string"?r$($):[],set:($)=>$==null?null:Array.isArray($)?JSON.stringify($):$}};function d$($){try{return JSON.parse($)}catch{return $}}function r$($){try{return JSON.parse($)}catch{return[]}}function Y$($,Z,J){if(!$||typeof $!=="object"||!Z||Object.keys(Z).length===0)return $;let z={...$};for(let[G,W]of Object.entries(Z)){let K=typeof W==="string"?s$[W]:W;if(!K||typeof K[J]!=="function")continue;if(Object.prototype.hasOwnProperty.call(z,G))z[G]=K[J](z[G]);let D=I(G);if(D!==G&&Object.prototype.hasOwnProperty.call(z,D))z[D]=K[J](z[D])}return z}function V$($,Z,J){let z=Z?.attributes??{},G={};for(let[W,K]of Object.entries(z)){let D=K?.validation?.rule;if(!D||typeof D.validate!=="function")continue;let N=Object.prototype.hasOwnProperty.call($,W);if(!N&&J==="updating")continue;let Y=K!==null&&typeof K==="object"&&Object.prototype.hasOwnProperty.call(K,"default"),R=N?$[W]:Y?K.default:void 0,f=t$(D,R),F=D.validate(f);if(!F?.valid&&Array.isArray(F?.errors)&&F.errors.length>0)G[W]=F.errors.map((v)=>K?.validation?.message?.[v?.code]??v?.message??"invalid")}return Object.keys(G).length===0?{valid:!0}:{valid:!1,errors:G}}function B$($){return $.replace(/\{[^}]*\}/g,"{}").replace(/:[^/]+/g,"{}")}function W$($){if(Array.isArray($))return $.filter((Z)=>typeof Z==="string"&&Z.length>0);return typeof $==="string"&&$?[$]:[]}function j$($){let Z=typeof $==="object"&&$!==null&&"middleware"in $,J=$?.middleware;if(!Z)return{read:["auth"],write:["auth"],declared:!1};if(J&&typeof J==="object"&&!Array.isArray(J)){let G=J;return{read:"read"in G?W$(G.read):["auth"],write:"write"in G?W$(G.write):["auth"],declared:!0}}let z=W$(J);return{read:z,write:z,declared:!0}}var N$=15,a$=100;function S$($){let Z=Number.parseInt($.get("page")||String(1),10),J=Number.isFinite(Z)?Math.max(1,Z):1,z=Number.parseInt($.get("per_page")||String(N$),10),G=Math.min(Number.isFinite(z)?Math.max(1,z):N$,a$);return{page:J,perPage:G,offset:(J-1)*G}}function e($,Z){let J=new URL($.toString());return J.searchParams.set("page",String(Z)),`${J.pathname}${J.search}`}function $$($,Z,J,z,G,W){let K=(Z-1)*J,D=z===0,N={page:Z,per_page:J,from:D?null:K+1,to:D?null:K+z,has_more_pages:G,prev_page_url:Z>1?e($,Z-1):null,next_page_url:G?e($,Z+1):null};if(W!==void 0&&!Number.isNaN(W)){let Y=Math.max(1,Math.ceil(W/J));N.total=W,N.last_page=Y,N.first_page_url=e($,1),N.last_page_url=e($,Y)}return N}function T$($,Z,J,z,G,W){let{page:K,...D}=$$($,Z,J,z,G,W);return{current_page:K,...D}}import{readdirSync as e$}from"fs";import{basename as $Z,extname as C$,join as ZZ}from"path";function JZ($){let Z=[],J=(z)=>{let G;try{G=e$(z,{withFileTypes:!0})}catch{return}for(let W of G){let K=ZZ(z,W.name);if(W.isDirectory()){J(K);continue}if(![".ts",".js"].includes(C$(W.name)))continue;if(W.name.startsWith(".")||W.name.startsWith("index"))continue;Z.push(K)}};return J($),Z.sort()}async function F$($,Z,J){for(let z of JZ($))try{let G=C$(z),W=await import(`${z}?t=${Date.now()}`),K=W.default??W,D=K.name??$Z(z,G);Z[D]={...K,name:D}}catch(G){J?.(z,G)}}async function P$($){let Z={};return await F$($.defaultsRoot,Z,$.onImportError),await F$($.userRoot,Z,$.onImportError),Z}var WZ=h$("config/qb.ts");try{let $=(await import(WZ)).default;R$($??k$)}catch{z$.debug("[orm] No config/qb.ts override found \u2014 deriving config from DB_CONNECTION");let $=p.DB_CONNECTION||"sqlite";R$({...k$,dialect:$,database:$==="sqlite"?{database:p.DB_DATABASE_PATH||"database/stacks.sqlite"}:{database:p.DB_DATABASE||"stacks",host:p.DB_HOST||"127.0.0.1",port:p.DB_PORT||($==="postgres"?5432:3306),username:p.DB_USERNAME||($==="postgres"?"postgres":"root"),password:p.DB_PASSWORD||""}})}var D$=await P$({defaultsRoot:zZ("framework/defaults/app/Models"),userRoot:h$("app/Models"),onImportError:($,Z)=>z$.warn(`[orm] Could not load model ${$}: ${Z.message}`)}),S=GZ();function u($,Z){let J=B$(Z);return h.routes.some((z)=>z.method===$&&B$(String(z.path??""))===J)}function q$($){if(!$.attributes)return[];return Object.entries($.attributes).filter(([Z,J])=>J.hidden===!0).map(([Z])=>Z)}function f$($){if($.endsWith("y")&&!/[aeiou]y$/i.test($))return`${$.slice(0,-1)}ies`;if(/(?:s|x|z|ch|sh)$/i.test($))return`${$}es`;return`${$}s`}async function g$($,Z,J,z){if(!$.length)return $;let G=J.split(",").map((Y)=>Y.trim()).filter(Boolean);if(!G.length)return $;let W=Array.isArray(Z.belongsTo)?Z.belongsTo:[],K=Array.isArray(Z.hasMany)?Z.hasMany:[],D=Array.isArray(Z.hasOne)?Z.hasOne:[],N=new Map;for(let Y of W)N.set(I(Y),{kind:"belongsTo",modelName:Y});for(let Y of D)N.set(I(Y),{kind:"hasOne",modelName:Y});for(let Y of K)N.set(f$(I(Y)),{kind:"hasMany",modelName:Y});for(let Y of G){let R=N.get(Y);if(!R)continue;let f=z[R.modelName];if(!f)continue;let F=f.table||f$(I(R.modelName)),v=q$(f),G$=(w)=>l(r(w,f),v);if(R.kind==="belongsTo"||R.kind==="hasOne"){let w=`${I(R.modelName)}_id`,y=[...new Set($.map((E)=>E[w]).filter((E)=>E!=null))];if(!y.length){for(let E of $)E[Y]=null;continue}let i=await S.selectFrom(F).whereIn("id",y).get(),P=new Map;for(let E of i??[])P.set(String(E.id),G$(E));for(let E of $)E[Y]=P.get(String(E[w]))??null}else{let w=String(Z.name??""),y=`${I(w)}_id`,i=[...new Set($.map((X)=>X.id).filter((X)=>X!=null))];if(!i.length){for(let X of $)X[Y]=[];continue}let P=await S.selectFrom(F).whereIn(y,i).get(),E=new Map;for(let X of P??[]){let Q=String(X[y]),L=E.get(Q)??[];L.push(G$(X)),E.set(Q,L)}for(let X of $)X[Y]=E.get(String(X.id))??[]}}return $}async function y$($,Z){let J=Z?.set;if(!J||typeof J!=="object")return $;let z={...$};for(let[G,W]of Object.entries(J)){if(typeof W!=="function"||!(G in z))continue;try{z[G]=await W(z)}catch{}}return z}function c$($,Z){return Y$($,Z?.casts,"set")}function r($,Z){return Y$($,Z?.casts,"get")}function V($,Z=200){return new Response(JSON.stringify($),{status:Z,headers:{"Content-Type":"application/json"}})}var Z$=1048576;async function x$($){if(Number($.headers?.get?.("content-length")??0)>Z$)throw new q(413,`Request body exceeds ${Z$}-byte limit`);if($.jsonBody&&typeof $.jsonBody==="object")return $.jsonBody;if($.formBody&&typeof $.formBody==="object")return $.formBody;try{let J=await $.clone().text();if(J.length>Z$)throw new q(413,`Request body exceeds ${Z$}-byte limit`);if(!J)return{};let z=JSON.parse(J);return z&&typeof z==="object"&&!Array.isArray(z)?z:{}}catch(J){if(J instanceof q)throw J;throw new q(400,`Invalid JSON body: ${J.message}`)}}function J$($){if($==null)return null;if(typeof $==="number")return Number.isFinite($)&&$>0?$:null;if(typeof $==="string"){let Z=$.trim();if(!Z)return null;if(/^\d+$/.test(Z)){let J=Number(Z);return Number.isFinite(J)&&J>0?J:null}return Z}return null}function v$($){let Z=$.bearerToken;if(typeof Z==="function"){let z=Z.call($);if(z)return z}let J=$.headers?.get?.("authorization")||$.headers?.get?.("Authorization")||"";if(typeof J==="string"&&J.startsWith("Bearer "))return J.substring(7);return null}async function t($){let Z=$._authenticatedUser;if(Z)return Z;let J=v$($);if(!J)return null;try{let{Auth:z}=await import("@stacksjs/auth"),G=await z.getUserFromToken(J);if(G)$._authenticatedUser=G;return G||null}catch{return null}}function d($,Z){if($==null||Z==null)return!1;if(Array.isArray(Z))return Z.some((J)=>String(J)===String($));return String($)===String(Z)}function QZ($){let Z=v$($),J=$.headers?.get?.("cookie")||"";return{bearerToken:()=>Z,cookies:{get:(z)=>{for(let G of J.split(";")){let W=G.indexOf("=");if(W===-1)continue;if(G.slice(0,W).trim()===z)return decodeURIComponent(G.slice(W+1).trim())}return null}}}}function w$($){if($?.ownership)return $.ownership;let Z=U$($);if(!Z)return null;return{field:Z,resolve:async(J,z)=>{let{resolveAuthenticatedTeamId:G}=await import("@stacksjs/auth");return G(QZ(z))}}}async function o($,Z,J){let z=w$($);if(!z||!z.field||typeof z.resolve!=="function")return{enforced:!1,value:null,field:"",bypass:!1};let G=typeof z.bypass==="function"?!!z.bypass(Z,J):!1,W=null;try{W=await z.resolve(Z,J)}catch{W=null}return{enforced:!0,value:W,field:String(z.field),bypass:G}}async function b$($,Z,J,z){let G=$?.authedFill?.[Z];if(!G)return{};if(typeof G==="function")try{let W=await G(J,z);return W&&typeof W==="object"?W:{}}catch{return{}}if(typeof G==="object"){let W={};for(let[K,D]of Object.entries(G))try{W[K]=typeof D==="function"?await D(J,z):D}catch{}return W}return{}}for(let[$,Z]of Object.entries(D$)){let J=Z.traits?.useApi;if(!J)continue;let z=typeof J==="object"?J:{},G=z.uri||Z.table||$.toLowerCase()+"s",W=z.routes||["index","show","store","update","destroy"],K=Z.table||G,D=A$(Z),N=q$(Z),Y=O$(G,z.prefix),R=E$(Z.attributes,N),{read:f,write:F,declared:v}=j$(J);if(["store","update","destroy"].some((X)=>W.includes(X))&&v&&F.length===0)z$.warn(`[orm] ${$}: registering UNAUTHENTICATED mutating routes at ${Y} (explicit \`middleware: []\` opt-out)`);if(["index","show"].some((X)=>W.includes(X))&&v&&f.length===0)z$.debug(`[orm] ${$}: registering public read routes at ${Y} (declared \`middleware.read: []\`)`);let y=!!w$(Z),i=y&&!f.includes("auth")?["auth",...f]:f,P=(X,Q=i)=>{let L=X;for(let B of Q)if(L&&typeof L.middleware==="function")L=L.middleware(B);return L};if(W.includes("index")&&!u("GET",Y))P(h.get(Y,async(X)=>{try{let Q=new URL(X.url),{page:L,perPage:B,offset:H}=S$(Q.searchParams),_=Q.searchParams.get("sort"),T=S.selectFrom(K);T=M$(T,_,R);let k=new Set(["page","per_page","sort","fields","search","include","limit","offset","with_count","withTrashed","onlyTrashed"]);for(let[M,j]of Q.searchParams.entries()){if(k.has(M)||!j)continue;if(!/^[a-z_][a-z0-9_]*$/i.test(M))continue;let m=R.get(M);if(m)T=T.where(m,"=",j)}let U=Q.searchParams.get("search");if(U&&D.length>0){let M=D.slice(0,5);T=T.where((j)=>{for(let m of M)j=j.orWhere(I(m),"like",`%${U}%`);return j})}let A=Q.searchParams.get("fields");if(A){let M=A.split(",").map((j)=>j.trim()).filter((j)=>/^[a-z_][a-z0-9_]*$/i.test(j)).map((j)=>I(j));if(M.length>0)T=T.select(M)}let C=!!Z.traits?.useSoftDeletes,O=Q.searchParams.get("withTrashed")==="true",g=Q.searchParams.get("onlyTrashed")==="true";if(C&&!O)T=g?T.whereNotNull("deleted_at"):T.whereNull("deleted_at");let x=y?await o(Z,await t(X),X):{enforced:!1,value:null,field:"",bypass:!1};if(x.enforced&&!x.bypass){if(x.value==null||Array.isArray(x.value)&&x.value.length===0){let M=T$(Q,L,B,0,!1,void 0);return new Response(JSON.stringify({data:[],...M,meta:$$(Q,L,B,0,!1,void 0)}),{status:200,headers:{"Content-Type":"application/json","Cache-Control":"private, no-store",Vary:"Authorization"}})}T=Array.isArray(x.value)?T.where(x.field,"in",x.value):T.where(x.field,"=",x.value)}let c=await T.limit(B+1).offset(H).get()||[],b=c.length>B,s=(b?c.slice(0,B):c).map((M)=>l(r(M,Z),N)),_$=Q.searchParams.get("include");if(_$)s=await g$(s,Z,_$,D$);let m$=Q.searchParams.get("with_count")==="true",n;if(m$)try{let M=S.selectFrom(K);if(x.enforced&&!x.bypass&&x.value!=null)M=Array.isArray(x.value)?M.where(x.field,"in",x.value):M.where(x.field,"=",x.value);let j=await M.count(),m=typeof j==="number"?j:Number(j?.count??j);if(Number.isFinite(m))n=m}catch{}let a={"Content-Type":"application/json"};if(n!==void 0&&!Number.isNaN(n))a["X-Total-Count"]=String(n);a["Cache-Control"]=x.enforced&&!x.bypass?"private, no-store":"public, max-age=15, must-revalidate",a.Vary="Authorization";let p$=T$(Q,L,B,s.length,b,n);return new Response(JSON.stringify({data:s,...p$,meta:$$(Q,L,B,s.length,b,n)}),{status:200,headers:a})}catch(Q){if(Q instanceof q){let L={error:Q.message};if(Q.details!==void 0)L.details=Q.details;return V(L,Q.status||400)}return V({error:`Failed to fetch ${G}`,detail:String(Q)},500)}}));if(W.includes("show")&&!u("GET",`${Y}/{id}`))P(h.get(`${Y}/{id}`,async(X)=>{try{let Q=J$(X.params?.id);if(Q==null)return V({error:"Invalid ID parameter"},400);let L=await S.selectFrom(K).where({id:Q}).executeTakeFirst();if(!L)return V({error:`${$} not found`},404);let B=new URL(X.url);if(Z.traits?.useSoftDeletes&&L.deleted_at&&B.searchParams.get("withTrashed")!=="true")return V({error:`${$} not found`},404);let H=y?await o(Z,await t(X),X):{enforced:!1,value:null,field:"",bypass:!1};if(H.enforced&&!H.bypass){if(H.value==null||!d(L[H.field],H.value))return V({error:`${$} not found`},404)}let _=l(r(L,Z),N),T=B.searchParams.get("include");if(T){let[O]=await g$([_],Z,T,D$);_=O}let k=_?.updated_at||_?.created_at,U=k?`W/"${_.id}-${String(k)}"`:void 0,A=X.headers?.get?.("if-none-match");if(U&&A&&A===U)return new Response(null,{status:304,headers:{ETag:U}});let C={"Content-Type":"application/json"};if(U)C.ETag=U;return C["Cache-Control"]=H.enforced&&!H.bypass?"private, no-store":"public, max-age=30, must-revalidate",C.Vary="Authorization",new Response(JSON.stringify({data:_}),{status:200,headers:C})}catch(Q){if(Q instanceof q){let L={error:Q.message};if(Q.details!==void 0)L.details=Q.details;return V(L,Q.status||400)}return V({error:`Failed to fetch ${$}`,detail:String(Q)},500)}}));if(W.includes("store")&&!u("POST",Y))P(h.post(Y,async(X)=>{try{let Q=await x$(X),L=X$(Q,N),B=L$(L,D),H=await t(X);if(H){let O=await b$(Z,"creating",H,X);for(let[g,x]of Object.entries(O))if(x!==void 0&&x!==null&&B[g]===void 0)B[g]=x}let _=await o(Z,H,X);if(_.enforced&&!_.bypass){if(!H)return V({error:"Auth required"},401);let O=I$(B,_.field,_.value);if(O.error)return V({error:O.error},403);B=O.data}if(Object.keys(B).length===0)return V({error:"No fillable fields provided"},422);let T=V$(B,Z,"creating");if(!T.valid)return V({success:!1,message:"Validation failed",errors:T.errors},422);if(Z.traits?.useTimestamps!==!1){let O=new Date().toISOString();B.created_at=O,B.updated_at=O}let k=await y$(B,Z),U=K$(c$(k,Z)),A=await S.insertInto(K).values(U).execute(),C=U;try{let O=A?.lastInsertRowid??A?.insertId??A;if(O){let g=await S.selectFrom(K).where({id:O}).executeTakeFirst();if(g)C=g}}catch{}return V({data:l(r(C,Z),N)},201)}catch(Q){let{status:L,body:B}=Q$(Q,$,"create");return V(B,L)}}),F);if(W.includes("update")){let X=async(Q)=>{try{let L=J$(Q.params?.id);if(L==null)return V({error:"Invalid ID parameter"},400);let B=await x$(Q),H=X$(B,N),_=L$(H,D),T=await t(Q);if(T){let x=await b$(Z,"updating",T,Q);for(let[c,b]of Object.entries(x))if(b!==void 0&&b!==null&&_[c]===void 0)_[c]=b}if(Object.keys(_).length===0)return V({error:"No fillable fields provided"},422);let k=V$(_,Z,"updating");if(!k.valid)return V({success:!1,message:"Validation failed",errors:k.errors},422);let U=await S.selectFrom(K).where({id:L}).executeTakeFirst();if(!U)return V({error:`${$} not found`},404);let A=await o(Z,T,Q);if(A.enforced&&!A.bypass){if(!T)return V({error:"Auth required"},401);let x=U[A.field];if(!d(x,A.value))return V({error:`Not your ${$}`},403);let c=Object.keys(_).find((b)=>I(b)===I(A.field));if(c!==void 0&&!d(_[c],A.value))return V({error:`Cannot reassign ${$} ownership`},403)}if(Z.traits?.useTimestamps!==!1)_.updated_at=new Date().toISOString();let C=await y$(_,Z),O=K$(c$(C,Z));await S.updateTable(K).set(O).where({id:L}).execute();let g={...U,...O};try{let x=await S.selectFrom(K).where({id:L}).executeTakeFirst();if(x)g=x}catch{}return V({data:l(r(g,Z),N)})}catch(L){let{status:B,body:H}=Q$(L,$,"update");return V(H,B)}};if(!u("PUT",`${Y}/{id}`))P(h.put(`${Y}/{id}`,X),F);if(!u("PATCH",`${Y}/{id}`))P(h.patch(`${Y}/{id}`,X),F)}let E=!!Z.traits?.useSoftDeletes;if(W.includes("destroy")&&!u("DELETE",`${Y}/{id}`))P(h.delete(`${Y}/{id}`,async(X)=>{try{let Q=J$(X.params?.id);if(Q==null)return V({error:"Invalid ID parameter"},400);let L=await S.selectFrom(K).where({id:Q}).executeTakeFirst();if(!L)return V({error:`${$} not found`},404);let B=await t(X),H=await o(Z,B,X);if(H.enforced&&!H.bypass){if(!B)return V({error:"Auth required"},401);let _=L[H.field];if(!d(_,H.value))return V({error:`Not your ${$}`},403)}if(E){let _=new Date().toISOString();await S.updateTable(K).set({deleted_at:_,updated_at:_}).where({id:Q}).execute()}else await S.deleteFrom(K).where({id:Q}).execute();return new Response(null,{status:204})}catch(Q){if(Q instanceof q){let L={error:Q.message};if(Q.details!==void 0)L.details=Q.details;return V(L,Q.status||400)}return V({error:`Failed to delete ${$}`,detail:String(Q)},500)}}),F);if(W.includes("destroy")&&!u("POST",`${Y}/bulk-delete`))P(h.post(`${Y}/bulk-delete`,async(X)=>{try{let L=(await x$(X))?.ids;if(!Array.isArray(L)||L.length===0)return V({error:"An array of IDs is required"},422);if(L.length>100)return V({error:"Cannot delete more than 100 records at once"},422);let B=[],H=[];for(let U of L){let A=J$(U);if(A!=null)B.push(A);else H.push(U)}if(H.length>0)return V({error:"Invalid IDs in batch",invalid:H},422);let _=await t(X),T=await o(Z,_,X);if(T.enforced&&!T.bypass){if(!_)return V({error:"Auth required"},401);if(T.value==null)return V({error:"Caller has no ownership identity"},403);let U=await S.selectFrom(K).select(["id",T.field]).execute(),A=new Set(U.filter((O)=>d(O[T.field],T.value)).map((O)=>String(O.id))),C=B.filter((O)=>!A.has(String(O)));if(C.length>0)return V({error:`Cannot delete ${$} you don't own`,ids:C},403)}let k=new Date().toISOString();for(let U of B)if(E)await S.updateTable(K).set({deleted_at:k,updated_at:k}).where({id:U}).execute();else await S.deleteFrom(K).where({id:U}).execute();return V({message:`Successfully deleted ${B.length} ${G}`})}catch(Q){if(Q instanceof q){let L={error:Q.message};if(Q.details!==void 0)L.details=Q.details;return V(L,Q.status||400)}return V({error:`Failed to bulk delete ${G}`,detail:String(Q)},500)}}),F)}var jZ=h;export{jZ as default};
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/orm",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.
|
|
5
|
+
"version": "0.72.0",
|
|
6
6
|
"description": "The Stacks ORM integration",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -67,9 +67,9 @@
|
|
|
67
67
|
"bun-query-builder": "^0.2.38"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"@stacksjs/config": "0.
|
|
70
|
+
"@stacksjs/config": "0.72.0",
|
|
71
71
|
"better-dx": "^0.2.23",
|
|
72
|
-
"@stacksjs/query-builder": "0.
|
|
73
|
-
"@stacksjs/types": "0.
|
|
72
|
+
"@stacksjs/query-builder": "0.72.0",
|
|
73
|
+
"@stacksjs/types": "0.72.0"
|
|
74
74
|
}
|
|
75
75
|
}
|