@stacksjs/orm 0.72.57 → 0.72.61
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/index.js +22 -22
- package/dist/routes.js +1 -1
- package/package.json +5 -5
package/dist/routes.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
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 - 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};
|
|
2
|
+
var He=Object.defineProperty;var Je=(e)=>e;function qe(e,t){this[e]=Je.bind(null,t)}var lt=(e,t)=>{for(var n in t)He(e,n,{get:t[n],enumerable:!0,configurable:!0,set:qe.bind(t,n)})};var ct=(e,t)=>()=>(e&&(t=e(e=0)),t);var we=import.meta.require;import{route as F}from"@stacksjs/router";import{env as z}from"@stacksjs/env";import{projectPath as Fe,storagePath as st}from"@stacksjs/path";import{createQueryBuilder as at,defaultConfig as Pe,setConfig as Ee}from"@stacksjs/query-builder";import{HttpError as U}from"@stacksjs/error-handling";import{log as se}from"@stacksjs/logging";function Ve(e){let t=e;return t?.code==="SQLITE_CONSTRAINT_UNIQUE"||t?.code==="SQLITE_CONSTRAINT"||t?.code==="23505"||t?.errno===1062||/unique|duplicate/i.test(t?.message??"")}function ie(e,t,n){let r=e;if(e instanceof Error&&typeof r.status==="number"&&Number.isInteger(r.status)&&r.status>=400&&r.status<600){let s={error:e.message};if(r.details!==void 0)s.details=r.details;return{status:r.status,body:s}}if(Ve(e))return{status:409,body:{error:`${t} already exists`}};return{status:500,body:{error:`Failed to ${n} ${t}`,detail:String(e)}}}function k(e){return e.replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}function ue(e){let t={};for(let[n,r]of Object.entries(e))t[k(n)]=r;return t}function Re(e,t){let n=String(t||"").replace(/^\/+|\/+$/g,""),r=String(e).replace(/^\/+/,"");return`/api/${n?`${n}/`:""}${r}`}function ke(e){if(!e)return null;let t=e.attributes??{};if(Object.prototype.hasOwnProperty.call(t,"teamId")||Object.prototype.hasOwnProperty.call(t,"team_id"))return"team_id";return e.belongsTo?.some((n)=>n==="Team")?"team_id":null}function Se(e,t,n){let r=Object.keys(e).find((a)=>k(a)===k(t));if(Array.isArray(n)){if(r===void 0)return{data:e,error:"Ownership value is required"};if(!n.some((a)=>String(a)===String(e[r])))return{data:e,error:"Ownership value is not available to this caller"};return{data:{...e,[t]:e[r]}}}if(n===null||n===void 0)return{data:e,error:"Caller has no ownership identity"};let s={...e};for(let a of Object.keys(s))if(k(a)===k(t))delete s[a];return s[t]=n,{data:s}}function _e(e){if(!e)return[];let t=Object.entries(e.attributes??{}).filter(([,n])=>n?.fillable===!0).map(([n])=>n);for(let n of e.belongsTo??[]){if(typeof n!=="string"||!n.trim())continue;let r=k(n.trim()).split("_").filter(Boolean);if(r.length===0)continue;let s=`${r[0]}${r.slice(1).map((a)=>`${a[0]?.toUpperCase()}${a.slice(1)}`).join("")}Id`;t.push(s)}return[...new Set(t)]}function le(e,t){if(!e||t.length===0)return{};let n={};for(let r of t){if(r in e){n[r]=e[r];continue}let s=k(r);if(s!==r&&s in e)n[r]=e[s]}return n}function Qe(e,t){if(e?.name!=="date"||t instanceof Date||typeof t!=="string")return t;let n=/^(\d{4})-(\d{2})-(\d{2})$/.exec(t);if(!n)return t;let r=Number(n[1]),s=Number(n[2]),a=Number(n[3]),i=new Date(Date.UTC(r,s-1,a));if(i.getUTCFullYear()!==r||i.getUTCMonth()!==s-1||i.getUTCDate()!==a)return t;return i}function ce(e,t){if(!t.length)return e;let n={...e};for(let r of t)delete n[r],delete n[k(r)];return n}function V(e,t){if(!e||t.length===0)return e;let n={...e};for(let r of t)delete n[r],delete n[k(r)];return n}var Xe=["id","uuid","created_at","updated_at","deleted_at"];function Oe(e,t){let n=new Map;for(let r of[...Object.keys(e??{}),...Xe]){let s=k(r);if(!/^\w+$/.test(s))continue;n.set(r,s),n.set(s,s)}for(let r of t)n.delete(r),n.delete(k(r));return n}function xe(e,t,n){if(!t)return e;let r=String(t).split(",").map((a)=>a.trim()).filter(Boolean),s=e;for(let a of r){let i=a.startsWith("-"),p=i?a.slice(1):a;if(!/^\w+$/.test(p))continue;let w=n.get(p);if(!w)continue;s=s.orderBy(w,i?"desc":"asc")}return s}var Ge={string:{get:(e)=>e!=null?String(e):null,set:(e)=>e!=null?String(e):null},number:{get:(e)=>e!=null?Number(e):null,set:(e)=>e!=null?Number(e):null},integer:{get:(e)=>e!=null?Math.trunc(Number(e)):null,set:(e)=>e!=null?Math.trunc(Number(e)):null},float:{get:(e)=>e!=null?Number.parseFloat(String(e)):null,set:(e)=>e!=null?Number.parseFloat(String(e)):null},boolean:{get:(e)=>e===1||e==="1"||e===!0||e==="true",set:(e)=>e===!0||e===1||e==="1"||e==="true"?1:0},json:{get:(e)=>e==null?null:typeof e==="string"?Ke(e):e,set:(e)=>e==null?null:typeof e==="string"?e:JSON.stringify(e)},datetime:{get:(e)=>e?new Date(e):null,set:(e)=>e instanceof Date?e.toISOString():e},date:{get:(e)=>e?new Date(e):null,set:(e)=>e instanceof Date?e.toISOString().split("T")[0]:e},array:{get:(e)=>e==null?[]:Array.isArray(e)?e:typeof e==="string"?Ye(e):[],set:(e)=>e==null?null:Array.isArray(e)?JSON.stringify(e):e}};function Ke(e){try{return JSON.parse(e)}catch{return e}}function Ye(e){try{return JSON.parse(e)}catch{return[]}}function de(e,t,n){if(!e||typeof e!=="object"||!t||Object.keys(t).length===0)return e;let r={...e};for(let[s,a]of Object.entries(t)){let i=typeof a==="string"?Ge[a]:a;if(!i||typeof i[n]!=="function")continue;if(Object.prototype.hasOwnProperty.call(r,s))r[s]=i[n](r[s]);let p=k(s);if(p!==s&&Object.prototype.hasOwnProperty.call(r,p))r[p]=i[n](r[p])}return r}function fe(e,t,n){let r=t?.attributes??{},s={};for(let[a,i]of Object.entries(r)){let p=i?.validation?.rule;if(!p||typeof p.validate!=="function")continue;let w=Object.prototype.hasOwnProperty.call(e,a);if(!w&&n==="updating")continue;let c=i!==null&&typeof i==="object"&&Object.prototype.hasOwnProperty.call(i,"default"),E=w?e[a]:c?i.default:void 0,C=Qe(p,E),A=p.validate(C);if(!A?.valid&&Array.isArray(A?.errors)&&A.errors.length>0)s[a]=A.errors.map((B)=>i?.validation?.message?.[B?.code]??B?.message??"invalid")}return Object.keys(s).length===0?{valid:!0}:{valid:!1,errors:s}}function ge(e){return e.replace(/\{[^}]*\}/g,"{}").replace(/:[^/]+/g,"{}")}function oe(e){if(Array.isArray(e))return e.filter((t)=>typeof t==="string"&&t.length>0);return typeof e==="string"&&e?[e]:[]}function Te(e){let t=typeof e==="object"&&e!==null&&"middleware"in e,n=e?.middleware;if(!t)return{read:["auth"],write:["auth"],declared:!1};if(n&&typeof n==="object"&&!Array.isArray(n)){let s=n;return{read:"read"in s?oe(s.read):["auth"],write:"write"in s?oe(s.write):["auth"],declared:!0}}let r=oe(n);return{read:r,write:r,declared:!0}}var be=15,Ze=100;function Ae(e){let t=Number.parseInt(e.get("page")||String(1),10),n=Number.isFinite(t)?Math.max(1,t):1,r=Number.parseInt(e.get("per_page")||String(be),10),s=Math.min(Number.isFinite(r)?Math.max(1,r):be,Ze);return{page:n,perPage:s,offset:(n-1)*s}}function ee(e,t){let n=new URL(e.toString());return n.searchParams.set("page",String(t)),`${n.pathname}${n.search}`}function te(e,t,n,r,s,a){let i=(t-1)*n,p=r===0,w={page:t,per_page:n,from:p?null:i+1,to:p?null:i+r,has_more_pages:s,prev_page_url:t>1?ee(e,t-1):null,next_page_url:s?ee(e,t+1):null};if(a!==void 0&&!Number.isNaN(a)){let c=Math.max(1,Math.ceil(a/n));w.total=a,w.last_page=c,w.first_page_url=ee(e,1),w.last_page_url=ee(e,c)}return w}function pe(e,t,n,r,s,a){let{page:i,...p}=te(e,t,n,r,s,a);return{current_page:i,...p}}import{readdirSync as et}from"fs";import{basename as tt,extname as $e,join as nt}from"path";function rt(e){let t=[],n=(r)=>{let s;try{s=et(r,{withFileTypes:!0})}catch{return}for(let a of s){let i=nt(r,a.name);if(a.isDirectory()){n(i);continue}if(![".ts",".js"].includes($e(a.name)))continue;if(a.name.startsWith(".")||a.name.startsWith("index"))continue;t.push(i)}};return n(e),t.sort()}async function Ne(e,t,n){for(let r of rt(e))try{let s=$e(r),a=await import(`${r}?t=${Date.now()}`),i=a.default??a,p=i.name??tt(r,s);t[p]={...i,name:p}}catch(s){n?.(r,s)}}async function Ie(e){let t={};return await Ne(e.defaultsRoot,t,e.onImportError),await Ne(e.userRoot,t,e.onImportError),t}var ot=Fe("config/qb.ts");try{let e=(await import(ot)).default;Ee(e??Pe)}catch{se.debug("[orm] No config/qb.ts override found - deriving config from DB_CONNECTION");let e=z.DB_CONNECTION||"sqlite";Ee({...Pe,dialect:e,database:e==="sqlite"?{database:z.DB_DATABASE_PATH||"database/stacks.sqlite"}:{database:z.DB_DATABASE||"stacks",host:z.DB_HOST||"127.0.0.1",port:z.DB_PORT||(e==="postgres"?5432:3306),username:z.DB_USERNAME||(e==="postgres"?"postgres":"root"),password:z.DB_PASSWORD||""}})}var ye=await Ie({defaultsRoot:st("framework/defaults/app/Models"),userRoot:Fe("app/Models"),onImportError:(e,t)=>se.warn(`[orm] Could not load model ${e}: ${t.message}`)}),T=at();function H(e,t){let n=ge(t);return F.routes.some((r)=>r.method===e&&ge(String(r.path??""))===n)}function Ue(e){if(!e.attributes)return[];return Object.entries(e.attributes).filter(([t,n])=>n.hidden===!0).map(([t])=>t)}function Ce(e){if(e.endsWith("y")&&!/[aeiou]y$/i.test(e))return`${e.slice(0,-1)}ies`;if(/(?:s|x|z|ch|sh)$/i.test(e))return`${e}es`;return`${e}s`}async function De(e,t,n,r){if(!e.length)return e;let s=n.split(",").map((c)=>c.trim()).filter(Boolean);if(!s.length)return e;let a=Array.isArray(t.belongsTo)?t.belongsTo:[],i=Array.isArray(t.hasMany)?t.hasMany:[],p=Array.isArray(t.hasOne)?t.hasOne:[],w=new Map;for(let c of a)w.set(k(c),{kind:"belongsTo",modelName:c});for(let c of p)w.set(k(c),{kind:"hasOne",modelName:c});for(let c of i)w.set(Ce(k(c)),{kind:"hasMany",modelName:c});for(let c of s){let E=w.get(c);if(!E)continue;let C=r[E.modelName];if(!C)continue;let A=C.table||Ce(k(E.modelName)),B=Ue(C),ae=(L)=>V(Y(L,C),B);if(E.kind==="belongsTo"||E.kind==="hasOne"){let L=`${k(E.modelName)}_id`,j=[...new Set(e.map((_)=>_[L]).filter((_)=>_!=null))];if(!j.length){for(let _ of e)_[c]=null;continue}let J=await T.selectFrom(A).whereIn("id",j).get(),I=new Map;for(let _ of J??[])I.set(String(_.id),ae(_));for(let _ of e)_[c]=I.get(String(_[L]))??null}else{let L=String(t.name??""),j=`${k(L)}_id`,J=[...new Set(e.map((l)=>l.id).filter((l)=>l!=null))];if(!J.length){for(let l of e)l[c]=[];continue}let I=await T.selectFrom(A).whereIn(j,J).get(),_=new Map;for(let l of I??[]){let o=String(l[j]),u=_.get(o)??[];u.push(ae(l)),_.set(o,u)}for(let l of e)l[c]=_.get(String(l.id))??[]}}return e}async function je(e,t){let n=t?.set;if(!n||typeof n!=="object")return e;let r={...e};for(let[s,a]of Object.entries(n)){if(typeof a!=="function"||!(s in r))continue;try{r[s]=await a(r)}catch{}}return r}function Me(e,t){return de(e,t?.casts,"set")}function Y(e,t){return de(e,t?.casts,"get")}function d(e,t=200){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}var ne=1048576;async function me(e){if(Number(e.headers?.get?.("content-length")??0)>ne)throw new U(413,`Request body exceeds ${ne}-byte limit`);if(e.jsonBody&&typeof e.jsonBody==="object")return e.jsonBody;if(e.formBody&&typeof e.formBody==="object")return e.formBody;try{let n=await e.clone().text();if(n.length>ne)throw new U(413,`Request body exceeds ${ne}-byte limit`);if(!n)return{};let r=JSON.parse(n);return r&&typeof r==="object"&&!Array.isArray(r)?r:{}}catch(n){if(n instanceof U)throw n;throw new U(400,`Invalid JSON body: ${n.message}`)}}function re(e){if(e==null)return null;if(typeof e==="number")return Number.isFinite(e)&&e>0?e:null;if(typeof e==="string"){let t=e.trim();if(!t)return null;if(/^\d+$/.test(t)){let n=Number(t);return Number.isFinite(n)&&n>0?n:null}return t}return null}function Be(e){let t=e.bearerToken;if(typeof t==="function"){let r=t.call(e);if(r)return r}let n=e.headers?.get?.("authorization")||e.headers?.get?.("Authorization")||"";if(typeof n==="string"&&n.startsWith("Bearer "))return n.substring(7);return null}async function Q(e){let t=e._authenticatedUser;if(t)return t;let n=Be(e);if(!n)return null;try{let{Auth:r}=await import("@stacksjs/auth"),s=await r.getUserFromToken(n);if(s)e._authenticatedUser=s;return s||null}catch{return null}}function K(e,t){if(e==null||t==null)return!1;if(Array.isArray(t))return t.some((n)=>String(n)===String(e));return String(e)===String(t)}function it(e){let t=Be(e),n=e.headers?.get?.("cookie")||"";return{bearerToken:()=>t,cookies:{get:(r)=>{for(let s of n.split(";")){let a=s.indexOf("=");if(a===-1)continue;if(s.slice(0,a).trim()===r)return decodeURIComponent(s.slice(a+1).trim())}return null}}}}function Le(e){if(e?.ownership)return e.ownership;let t=ke(e);if(!t)return null;return{field:t,resolve:async(n,r)=>{let{resolveAuthenticatedTeamId:s}=await import("@stacksjs/auth");return s(it(r))}}}async function X(e,t,n){let r=Le(e);if(!r||!r.field||typeof r.resolve!=="function")return{enforced:!1,value:null,field:"",bypass:!1};let s=typeof r.bypass==="function"?!!r.bypass(t,n):!1,a=null;try{a=await r.resolve(t,n)}catch{a=null}return{enforced:!0,value:a,field:String(r.field),bypass:s}}async function ve(e,t,n,r){let s=e?.authedFill?.[t];if(!s)return{};if(typeof s==="function")try{let a=await s(n,r);return a&&typeof a==="object"?a:{}}catch{return{}}if(typeof s==="object"){let a={};for(let[i,p]of Object.entries(s))try{a[i]=typeof p==="function"?await p(n,r):p}catch{}return a}return{}}for(let[e,t]of Object.entries(ye)){let n=t.traits?.useApi;if(!n)continue;let r=typeof n==="object"?n:{},s=r.uri||t.table||e.toLowerCase()+"s",a=r.routes||["index","show","store","update","destroy"],i=t.table||s,p=_e(t),w=Ue(t),c=Re(s,r.prefix),E=Oe(t.attributes,w),{read:C,write:A,declared:B}=Te(n);if(["store","update","destroy"].some((l)=>a.includes(l))&&B&&A.length===0)se.warn(`[orm] ${e}: registering UNAUTHENTICATED mutating routes at ${c} (explicit \`middleware: []\` opt-out)`);if(["index","show"].some((l)=>a.includes(l))&&B&&C.length===0)se.debug(`[orm] ${e}: registering public read routes at ${c} (declared \`middleware.read: []\`)`);let j=!!Le(t),J=j&&!C.includes("auth")?["auth",...C]:C,I=(l,o=J)=>{let u=l;for(let f of o)if(u&&typeof u.middleware==="function")u=u.middleware(f);return u};if(a.includes("index")&&!H("GET",c))I(F.get(c,async(l)=>{try{let o=new URL(l.url),{page:u,perPage:f,offset:h}=Ae(o.searchParams),m=o.searchParams.get("sort"),g=T.selectFrom(i);g=xe(g,m,E);let P=new Set(["page","per_page","sort","fields","search","include","limit","offset","with_count","withTrashed","onlyTrashed"]);for(let[O,x]of o.searchParams.entries()){if(P.has(O)||!x)continue;if(!/^[a-z_][a-z0-9_]*$/i.test(O))continue;let W=E.get(O);if(W)g=g.where(W,"=",x)}let R=o.searchParams.get("search");if(R&&p.length>0){let O=p.slice(0,5);g=g.where((x)=>{for(let W of O)x=x.orWhere(k(W),"like",`%${R}%`);return x})}let S=o.searchParams.get("fields");if(S){let O=S.split(",").map((x)=>x.trim()).filter((x)=>/^[a-z_][a-z0-9_]*$/i.test(x)).map((x)=>k(x));if(O.length>0)g=g.select(O)}let N=!!t.traits?.useSoftDeletes,b=o.searchParams.get("withTrashed")==="true",D=o.searchParams.get("onlyTrashed")==="true";if(N&&!b)g=D?g.whereNotNull("deleted_at"):g.whereNull("deleted_at");let y=j?await X(t,await Q(l),l):{enforced:!1,value:null,field:"",bypass:!1};if(y.enforced&&!y.bypass){if(y.value==null||Array.isArray(y.value)&&y.value.length===0){let O=pe(o,u,f,0,!1,void 0);return new Response(JSON.stringify({data:[],...O,meta:te(o,u,f,0,!1,void 0)}),{status:200,headers:{"Content-Type":"application/json","Cache-Control":"private, no-store",Vary:"Authorization"}})}g=Array.isArray(y.value)?g.where(y.field,"in",y.value):g.where(y.field,"=",y.value)}let M=await g.limit(f+1).offset(h).get()||[],v=M.length>f,G=(v?M.slice(0,f):M).map((O)=>V(Y(O,t),w)),he=o.searchParams.get("include");if(he)G=await De(G,t,he,ye);let We=o.searchParams.get("with_count")==="true",q;if(We)try{let O=T.selectFrom(i);if(y.enforced&&!y.bypass&&y.value!=null)O=Array.isArray(y.value)?O.where(y.field,"in",y.value):O.where(y.field,"=",y.value);let x=await O.count(),W=typeof x==="number"?x:Number(x?.count??x);if(Number.isFinite(W))q=W}catch{}let Z={"Content-Type":"application/json"};if(q!==void 0&&!Number.isNaN(q))Z["X-Total-Count"]=String(q);Z["Cache-Control"]=y.enforced&&!y.bypass?"private, no-store":"public, max-age=15, must-revalidate",Z.Vary="Authorization";let ze=pe(o,u,f,G.length,v,q);return new Response(JSON.stringify({data:G,...ze,meta:te(o,u,f,G.length,v,q)}),{status:200,headers:Z})}catch(o){if(o instanceof U){let u={error:o.message};if(o.details!==void 0)u.details=o.details;return d(u,o.status||400)}return d({error:`Failed to fetch ${s}`,detail:String(o)},500)}}));if(a.includes("show")&&!H("GET",`${c}/{id}`))I(F.get(`${c}/{id}`,async(l)=>{try{let o=re(l.params?.id);if(o==null)return d({error:"Invalid ID parameter"},400);let u=await T.selectFrom(i).where({id:o}).executeTakeFirst();if(!u)return d({error:`${e} not found`},404);let f=new URL(l.url);if(t.traits?.useSoftDeletes&&u.deleted_at&&f.searchParams.get("withTrashed")!=="true")return d({error:`${e} not found`},404);let h=j?await X(t,await Q(l),l):{enforced:!1,value:null,field:"",bypass:!1};if(h.enforced&&!h.bypass){if(h.value==null||!K(u[h.field],h.value))return d({error:`${e} not found`},404)}let m=V(Y(u,t),w),g=f.searchParams.get("include");if(g){let[b]=await De([m],t,g,ye);m=b}let P=m?.updated_at||m?.created_at,R=P?`W/"${m.id}-${String(P)}"`:void 0,S=l.headers?.get?.("if-none-match");if(R&&S&&S===R)return new Response(null,{status:304,headers:{ETag:R}});let N={"Content-Type":"application/json"};if(R)N.ETag=R;return N["Cache-Control"]=h.enforced&&!h.bypass?"private, no-store":"public, max-age=30, must-revalidate",N.Vary="Authorization",new Response(JSON.stringify({data:m}),{status:200,headers:N})}catch(o){if(o instanceof U){let u={error:o.message};if(o.details!==void 0)u.details=o.details;return d(u,o.status||400)}return d({error:`Failed to fetch ${e}`,detail:String(o)},500)}}));if(a.includes("store")&&!H("POST",c))I(F.post(c,async(l)=>{try{let o=await me(l),u=ce(o,w),f=le(u,p),h=await Q(l);if(h){let b=await ve(t,"creating",h,l);for(let[D,y]of Object.entries(b))if(y!==void 0&&y!==null&&f[D]===void 0)f[D]=y}let m=await X(t,h,l);if(m.enforced&&!m.bypass){if(!h)return d({error:"Auth required"},401);let b=Se(f,m.field,m.value);if(b.error)return d({error:b.error},403);f=b.data}if(Object.keys(f).length===0)return d({error:"No fillable fields provided"},422);let g=fe(f,t,"creating");if(!g.valid)return d({success:!1,message:"Validation failed",errors:g.errors},422);if(t.traits?.useTimestamps!==!1){let b=new Date().toISOString();f.created_at=b,f.updated_at=b}let P=await je(f,t),R=ue(Me(P,t)),S=await T.insertInto(i).values(R).execute(),N=R;try{let b=S?.lastInsertRowid??S?.insertId??S;if(b){let D=await T.selectFrom(i).where({id:b}).executeTakeFirst();if(D)N=D}}catch{}return d({data:V(Y(N,t),w)},201)}catch(o){let{status:u,body:f}=ie(o,e,"create");return d(f,u)}}),A);if(a.includes("update")){let l=async(o)=>{try{let u=re(o.params?.id);if(u==null)return d({error:"Invalid ID parameter"},400);let f=await me(o),h=ce(f,w),m=le(h,p),g=await Q(o);if(g){let y=await ve(t,"updating",g,o);for(let[M,v]of Object.entries(y))if(v!==void 0&&v!==null&&m[M]===void 0)m[M]=v}if(Object.keys(m).length===0)return d({error:"No fillable fields provided"},422);let P=fe(m,t,"updating");if(!P.valid)return d({success:!1,message:"Validation failed",errors:P.errors},422);let R=await T.selectFrom(i).where({id:u}).executeTakeFirst();if(!R)return d({error:`${e} not found`},404);let S=await X(t,g,o);if(S.enforced&&!S.bypass){if(!g)return d({error:"Auth required"},401);let y=R[S.field];if(!K(y,S.value))return d({error:`Not your ${e}`},403);let M=Object.keys(m).find((v)=>k(v)===k(S.field));if(M!==void 0&&!K(m[M],S.value))return d({error:`Cannot reassign ${e} ownership`},403)}if(t.traits?.useTimestamps!==!1)m.updated_at=new Date().toISOString();let N=await je(m,t),b=ue(Me(N,t));await T.updateTable(i).set(b).where({id:u}).execute();let D={...R,...b};try{let y=await T.selectFrom(i).where({id:u}).executeTakeFirst();if(y)D=y}catch{}return d({data:V(Y(D,t),w)})}catch(u){let{status:f,body:h}=ie(u,e,"update");return d(h,f)}};if(!H("PUT",`${c}/{id}`))I(F.put(`${c}/{id}`,l),A);if(!H("PATCH",`${c}/{id}`))I(F.patch(`${c}/{id}`,l),A)}let _=!!t.traits?.useSoftDeletes;if(a.includes("destroy")&&!H("DELETE",`${c}/{id}`))I(F.delete(`${c}/{id}`,async(l)=>{try{let o=re(l.params?.id);if(o==null)return d({error:"Invalid ID parameter"},400);let u=await T.selectFrom(i).where({id:o}).executeTakeFirst();if(!u)return d({error:`${e} not found`},404);let f=await Q(l),h=await X(t,f,l);if(h.enforced&&!h.bypass){if(!f)return d({error:"Auth required"},401);let m=u[h.field];if(!K(m,h.value))return d({error:`Not your ${e}`},403)}if(_){let m=new Date().toISOString();await T.updateTable(i).set({deleted_at:m,updated_at:m}).where({id:o}).execute()}else await T.deleteFrom(i).where({id:o}).execute();return new Response(null,{status:204})}catch(o){if(o instanceof U){let u={error:o.message};if(o.details!==void 0)u.details=o.details;return d(u,o.status||400)}return d({error:`Failed to delete ${e}`,detail:String(o)},500)}}),A);if(a.includes("destroy")&&!H("POST",`${c}/bulk-delete`))I(F.post(`${c}/bulk-delete`,async(l)=>{try{let u=(await me(l))?.ids;if(!Array.isArray(u)||u.length===0)return d({error:"An array of IDs is required"},422);if(u.length>100)return d({error:"Cannot delete more than 100 records at once"},422);let f=[],h=[];for(let R of u){let S=re(R);if(S!=null)f.push(S);else h.push(R)}if(h.length>0)return d({error:"Invalid IDs in batch",invalid:h},422);let m=await Q(l),g=await X(t,m,l);if(g.enforced&&!g.bypass){if(!m)return d({error:"Auth required"},401);if(g.value==null)return d({error:"Caller has no ownership identity"},403);let R=await T.selectFrom(i).select(["id",g.field]).execute(),S=new Set(R.filter((b)=>K(b[g.field],g.value)).map((b)=>String(b.id))),N=f.filter((b)=>!S.has(String(b)));if(N.length>0)return d({error:`Cannot delete ${e} you don't own`,ids:N},403)}let P=new Date().toISOString();for(let R of f)if(_)await T.updateTable(i).set({deleted_at:P,updated_at:P}).where({id:R}).execute();else await T.deleteFrom(i).where({id:R}).execute();return d({message:`Successfully deleted ${f.length} ${s}`})}catch(o){if(o instanceof U){let u={error:o.message};if(o.details!==void 0)u.details=o.details;return d(u,o.status||400)}return d({error:`Failed to bulk delete ${s}`,detail:String(o)},500)}}),A)}var xt=F;export{xt 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.72.
|
|
5
|
+
"version": "0.72.61",
|
|
6
6
|
"description": "The Stacks ORM integration",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -63,13 +63,13 @@
|
|
|
63
63
|
"prepublishOnly": "bun run build"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@stacksjs/ts-validation": "^0.5.
|
|
66
|
+
"@stacksjs/ts-validation": "^0.5.6",
|
|
67
67
|
"bun-query-builder": "^0.2.53"
|
|
68
68
|
},
|
|
69
69
|
"devDependencies": {
|
|
70
|
-
"@stacksjs/config": "0.72.
|
|
70
|
+
"@stacksjs/config": "0.72.61",
|
|
71
71
|
"better-dx": "^0.2.24",
|
|
72
|
-
"@stacksjs/query-builder": "0.72.
|
|
73
|
-
"@stacksjs/types": "0.72.
|
|
72
|
+
"@stacksjs/query-builder": "0.72.61",
|
|
73
|
+
"@stacksjs/types": "0.72.61"
|
|
74
74
|
}
|
|
75
75
|
}
|