@stacksjs/api 0.70.160 → 0.70.162

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.
@@ -1,3 +1,4 @@
1
+ import type { SchemaObject } from './generate-types';
1
2
  /**
2
3
  * Build an OpenAPI 3.0 spec from the live route registry.
3
4
  *
@@ -13,19 +14,19 @@
13
14
  * but omits a request body schema — that's still useful for clients
14
15
  * that just want to know what endpoints exist.
15
16
  */
16
- export declare function generateOpenApi(): Promise<OpenApiSpec>;
17
+ export declare function generateOpenApi(options?: { write?: boolean }): Promise<OpenApiSpec>;
17
18
  declare interface OpenApiPathItem {
18
19
  [method: string]: {
19
20
  summary?: string
20
21
  operationId?: string
21
22
  parameters?: Array<{ name: string, in: string, required: boolean, schema: { type: string } }>
22
- responses: Record<string, { description: string, content?: Record<string, unknown> }>
23
- requestBody?: { content: Record<string, unknown>, required?: boolean }
23
+ responses: Record<string, { description: string, content?: Record<string, { schema?: SchemaObject }> }>
24
+ requestBody?: { content: Record<string, { schema?: SchemaObject }>, required?: boolean }
24
25
  }
25
26
  }
26
27
  declare interface OpenApiSpec {
27
28
  openapi: string
28
29
  info: { title: string, version: string }
29
30
  paths: Record<string, OpenApiPathItem>
30
- components: { schemas: Record<string, unknown> }
31
+ components: { schemas: Record<string, SchemaObject> }
31
32
  }
@@ -0,0 +1,27 @@
1
+ export declare function schemaType(schema?: SchemaObject): string;
2
+ export declare function renderOpenApiTypes(document: OpenApiDocument): string;
3
+ export declare interface SchemaObject {
4
+ [key: string]: unknown
5
+ type?: string
6
+ enum?: unknown[]
7
+ properties?: Record<string, SchemaObject>
8
+ required?: string[]
9
+ items?: SchemaObject
10
+ additionalProperties?: boolean | SchemaObject
11
+ }
12
+ declare interface OpenApiParameter {
13
+ name: string
14
+ in: string
15
+ required?: boolean
16
+ schema?: SchemaObject
17
+ }
18
+ declare interface OpenApiOperation {
19
+ operationId?: string
20
+ parameters?: OpenApiParameter[]
21
+ requestBody?: { required?: boolean, content?: Record<string, { schema?: SchemaObject }> }
22
+ responses?: Record<string, { content?: Record<string, { schema?: SchemaObject }> }>
23
+ }
24
+ export declare interface OpenApiDocument {
25
+ paths?: Record<string, Record<string, OpenApiOperation>>
26
+ components?: { schemas?: Record<string, SchemaObject> }
27
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './fetcher';
2
2
  export * from './generate-openapi';
3
+ export * from './generate-types';
3
4
  export * from './resource';
package/dist/index.js CHANGED
@@ -1,2 +1,32 @@
1
1
  // @bun
2
- var rZ=Object.defineProperty;var aZ=(Z)=>Z;function eZ(Z,$){this[Z]=aZ.bind(null,$)}var NZ=(Z,$)=>{for(var z in $)rZ(Z,z,{get:$[z],enumerable:!0,configurable:!0,set:eZ.bind($,z)})};var zZ=(Z,$)=>()=>(Z&&($=Z(Z=0)),$);var p=import.meta.require;var IZ;var WZ=zZ(()=>{IZ={api:"api",v1:{path:"v1",prefix:"v1"}}});var DZ={};NZ(DZ,{default:()=>IZ});var SZ=zZ(()=>{WZ();WZ()});function Z0(Z){let $=Z;return $?.code==="SQLITE_CONSTRAINT_UNIQUE"||$?.code==="SQLITE_CONSTRAINT"||$?.code==="23505"||$?.errno===1062||/unique|duplicate/i.test($?.message??"")}function XZ(Z,$,z){let G=Z;if(Z instanceof Error&&typeof G.status==="number"&&Number.isInteger(G.status)&&G.status>=400&&G.status<600){let J={error:Z.message};if(G.details!==void 0)J.details=G.details;return{status:G.status,body:J}}if(Z0(Z))return{status:409,body:{error:`${$} already exists`}};return{status:500,body:{error:`Failed to ${z} ${$}`,detail:String(Z)}}}function M(Z){return Z.replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}function YZ(Z){let $={};for(let[z,G]of Object.entries(Z))$[M(z)]=G;return $}function TZ(Z,$){if(!Z||$.length===0)return{};let z={};for(let G of $){if(G in Z){z[G]=Z[G];continue}let J=M(G);if(J!==G&&J in Z)z[G]=Z[J]}return z}function BZ(Z,$){if(!$.length)return Z;let z={...Z};for(let G of $)delete z[G],delete z[M(G)];return z}function o(Z,$){if(!Z||$.length===0)return Z;let z={...Z};for(let G of $)delete z[G],delete z[M(G)];return z}function VZ(Z,$){let z=new Map;for(let G of[...Object.keys(Z??{}),...$0]){let J=M(G);if(!/^\w+$/.test(J))continue;z.set(G,J),z.set(J,J)}for(let G of $)z.delete(G),z.delete(M(G));return z}function FZ(Z,$,z){if(!$)return Z;let G=String($).split(",").map((L)=>L.trim()).filter(Boolean),J=Z;for(let L of G){let K=L.startsWith("-"),X=K?L.slice(1):L;if(!/^\w+$/.test(X))continue;let B=z.get(X);if(!B)continue;J=J.orderBy(B,K?"desc":"asc")}return J}function G0(Z){try{return JSON.parse(Z)}catch{return Z}}function J0(Z){try{return JSON.parse(Z)}catch{return[]}}function xZ(Z,$,z){if(!Z||typeof Z!=="object"||!$||Object.keys($).length===0)return Z;let G={...Z};for(let[J,L]of Object.entries($)){let K=typeof L==="string"?z0[L]:L;if(!K||typeof K[z]!=="function")continue;if(Object.prototype.hasOwnProperty.call(G,J))G[J]=K[z](G[J]);let X=M(J);if(X!==J&&Object.prototype.hasOwnProperty.call(G,X))G[X]=K[z](G[X])}return G}function MZ(Z){let $=typeof Z==="object"&&Z!==null&&"middleware"in Z,z=Z?.middleware,G=Array.isArray(z)?z.filter((J)=>typeof J==="string"&&J.length>0):typeof z==="string"&&z?[z]:[];return{read:G,write:$?G:["auth"],declared:$}}function CZ(Z){let $=Number.parseInt(Z.get("page")||String(1),10),z=Number.isFinite($)?Math.max(1,$):1,G=Number.parseInt(Z.get("per_page")||String(jZ),10),J=Math.min(Number.isFinite(G)?Math.max(1,G):jZ,L0);return{page:z,perPage:J,offset:(z-1)*J}}function GZ(Z,$){let z=new URL(Z.toString());return z.searchParams.set("page",String($)),`${z.pathname}${z.search}`}function JZ(Z,$,z,G,J,L){let K=($-1)*z,X=G===0,B={page:$,per_page:z,from:X?null:K+1,to:X?null:K+G,has_more_pages:J,prev_page_url:$>1?GZ(Z,$-1):null,next_page_url:J?GZ(Z,$+1):null};if(L!==void 0&&!Number.isNaN(L)){let W=Math.max(1,Math.ceil(L/z));B.total=L,B.last_page=W,B.first_page_url=GZ(Z,1),B.last_page_url=GZ(Z,W)}return B}function HZ(Z,$,z,G,J,L){let{page:K,...X}=JZ(Z,$,z,G,J,L);return{current_page:K,...X}}var $0,z0,jZ=15,L0=100;var kZ=zZ(()=>{$0=["id","uuid","created_at","updated_at","deleted_at"];z0={string:{get:(Z)=>Z!=null?String(Z):null,set:(Z)=>Z!=null?String(Z):null},number:{get:(Z)=>Z!=null?Number(Z):null,set:(Z)=>Z!=null?Number(Z):null},integer:{get:(Z)=>Z!=null?Math.trunc(Number(Z)):null,set:(Z)=>Z!=null?Math.trunc(Number(Z)):null},float:{get:(Z)=>Z!=null?Number.parseFloat(String(Z)):null,set:(Z)=>Z!=null?Number.parseFloat(String(Z)):null},boolean:{get:(Z)=>Z===1||Z==="1"||Z===!0||Z==="true",set:(Z)=>Z===!0||Z===1||Z==="1"||Z==="true"?1:0},json:{get:(Z)=>Z==null?null:typeof Z==="string"?G0(Z):Z,set:(Z)=>Z==null?null:typeof Z==="string"?Z:JSON.stringify(Z)},datetime:{get:(Z)=>Z?new Date(Z):null,set:(Z)=>Z instanceof Date?Z.toISOString():Z},date:{get:(Z)=>Z?new Date(Z):null,set:(Z)=>Z instanceof Date?Z.toISOString().split("T")[0]:Z},array:{get:(Z)=>Z==null?[]:Array.isArray(Z)?Z:typeof Z==="string"?J0(Z):[],set:(Z)=>Z==null?null:Array.isArray(Z)?JSON.stringify(Z):Z}}});var uZ={};NZ(uZ,{default:()=>T0});import{route as c}from"@stacksjs/router";import{env as n}from"@stacksjs/env";import{projectPath as hZ}from"@stacksjs/path";import{createQueryBuilder as K0,defaultConfig as PZ,setConfig as RZ}from"@stacksjs/query-builder";import{HttpError as i}from"@stacksjs/error-handling";import{log as cZ}from"@stacksjs/logging";function l(Z,$){return c.routes.some((z)=>z.method===Z&&z.path===$)}function W0(Z){if(!Z.attributes)return[];return Object.entries(Z.attributes).filter(([$,z])=>z.fillable===!0).map(([$])=>$)}function mZ(Z){if(!Z.attributes)return[];return Object.entries(Z.attributes).filter(([$,z])=>z.hidden===!0).map(([$])=>$)}function fZ(Z,$,z){let G=Z,J=$,L=z,K=J?.attributes??{},X={};for(let[B,W]of Object.entries(K)){let I=W?.validation?.rule;if(!I||typeof I.validate!=="function")continue;let N=Object.prototype.hasOwnProperty.call(G,B);if(!N&&L==="updating")continue;let R=N?G[B]:void 0,D=I.validate(R);if(!D?.valid&&Array.isArray(D?.errors)&&D.errors.length>0)X[B]=D.errors.map((S)=>W?.validation?.message?.[S?.code]??S?.message??"invalid")}return Object.keys(X).length===0?{valid:!0}:{valid:!1,errors:X}}function qZ(Z){if(Z.endsWith("y")&&!/[aeiou]y$/i.test(Z))return`${Z.slice(0,-1)}ies`;if(/(?:s|x|z|ch|sh)$/i.test(Z))return`${Z}es`;return`${Z}s`}async function yZ(Z,$,z,G){if(!Z.length)return Z;let J=z.split(",").map((W)=>W.trim()).filter(Boolean);if(!J.length)return Z;let L=Array.isArray($.belongsTo)?$.belongsTo:[],K=Array.isArray($.hasMany)?$.hasMany:[],X=Array.isArray($.hasOne)?$.hasOne:[],B=new Map;for(let W of L)B.set(M(W),{kind:"belongsTo",modelName:W});for(let W of X)B.set(M(W),{kind:"hasOne",modelName:W});for(let W of K)B.set(qZ(M(W)),{kind:"hasMany",modelName:W});for(let W of J){let I=B.get(W);if(!I)continue;let N=G[I.modelName];if(!N)continue;let R=N.table||qZ(M(I.modelName)),D=mZ(N),S=(b)=>o(e(b,N),D);if(I.kind==="belongsTo"||I.kind==="hasOne"){let b=`${M(I.modelName)}_id`,q=[...new Set(Z.map((T)=>T[b]).filter((T)=>T!=null))];if(!q.length){for(let T of Z)T[W]=null;continue}let f=await P.selectFrom(R).whereIn("id",q).get(),w=new Map;for(let T of f??[])w.set(String(T.id),S(T));for(let T of Z)T[W]=w.get(String(T[b]))??null}else{let b=String($.name??""),q=`${M(b)}_id`,f=[...new Set(Z.map((Q)=>Q.id).filter((Q)=>Q!=null))];if(!f.length){for(let Q of Z)Q[W]=[];continue}let w=await P.selectFrom(R).whereIn(q,f).get(),T=new Map;for(let Q of w??[]){let Y=String(Q[q]),x=T.get(Y)??[];x.push(S(Q)),T.set(Y,x)}for(let Q of Z)Q[W]=T.get(String(Q.id))??[]}}return Z}async function gZ(Z,$){let z=$?.set;if(!z||typeof z!=="object")return Z;let G={...Z};for(let[J,L]of Object.entries(z)){if(typeof L!=="function"||!(J in G))continue;try{G[J]=await L(G)}catch{}}return G}function wZ(Z,$){return xZ(Z,$?.casts,"set")}function e(Z,$){return xZ(Z,$?.casts,"get")}function H(Z,$=200){return new Response(JSON.stringify(Z),{status:$,headers:{"Content-Type":"application/json"}})}async function OZ(Z){if(Number(Z.headers?.get?.("content-length")??0)>LZ)throw new i(413,`Request body exceeds ${LZ}-byte limit`);if(Z.jsonBody&&typeof Z.jsonBody==="object")return Z.jsonBody;if(Z.formBody&&typeof Z.formBody==="object")return Z.formBody;try{let z=await Z.clone().text();if(z.length>LZ)throw new i(413,`Request body exceeds ${LZ}-byte limit`);if(!z)return{};let G=JSON.parse(z);return G&&typeof G==="object"&&!Array.isArray(G)?G:{}}catch(z){if(z instanceof i)throw z;throw new i(400,`Invalid JSON body: ${z.message}`)}}function KZ(Z){if(Z==null)return null;if(typeof Z==="number")return Number.isFinite(Z)&&Z>0?Z:null;if(typeof Z==="string"){let $=Z.trim();if(!$)return null;if(/^\d+$/.test($)){let z=Number($);return Number.isFinite(z)&&z>0?z:null}return $}return null}function pZ(Z){let $=Z.bearerToken;if(typeof $==="function"){let G=$.call(Z);if(G)return G}let z=Z.headers?.get?.("authorization")||Z.headers?.get?.("Authorization")||"";if(typeof z==="string"&&z.startsWith("Bearer "))return z.substring(7);return null}async function s(Z){let $=Z._authenticatedUser;if($)return $;let z=pZ(Z);if(!z)return null;try{let{Auth:G}=await import("@stacksjs/auth"),J=await G.getUserFromToken(z);if(J)Z._authenticatedUser=J;return J||null}catch{return null}}function r(Z,$){if(Z==null||$==null)return!1;if(Array.isArray($))return $.some((z)=>String(z)===String(Z));return String(Z)===String($)}function X0(Z){let $=Z?.attributes||{},z=(G)=>Object.prototype.hasOwnProperty.call($,G);return z("teamId")||z("team_id")?"team_id":null}function Y0(Z){let $=pZ(Z),z=Z.headers?.get?.("cookie")||"";return{bearerToken:()=>$,cookies:{get:(G)=>{for(let J of z.split(";")){let L=J.indexOf("=");if(L===-1)continue;if(J.slice(0,L).trim()===G)return decodeURIComponent(J.slice(L+1).trim())}return null}}}}function iZ(Z){if(Z?.ownership)return Z.ownership;let $=X0(Z);if(!$)return null;return{field:$,resolve:async(z,G)=>{let{resolveAuthenticatedTeamId:J}=await import("@stacksjs/auth");return J(Y0(G))}}}async function a(Z,$,z){let G=iZ(Z);if(!G||!G.field||typeof G.resolve!=="function")return{enforced:!1,value:null,field:"",bypass:!1};let J=typeof G.bypass==="function"?!!G.bypass($,z):!1,L=null;try{L=await G.resolve($,z)}catch{L=null}return{enforced:!0,value:L,field:String(G.field),bypass:J}}async function vZ(Z,$,z,G){let J=Z?.authedFill?.[$];if(!J)return{};if(typeof J==="function")try{let L=await J(z,G);return L&&typeof L==="object"?L:{}}catch{return{}}if(typeof J==="object"){let L={};for(let[K,X]of Object.entries(J))try{L[K]=typeof X==="function"?await X(z,G):X}catch{}return L}return{}}var Q0,bZ,QZ,P,LZ=1048576,T0;var nZ=zZ(async()=>{kZ();Q0=hZ("config/qb.ts");try{let Z=(await import(Q0)).default;RZ(Z??PZ)}catch{cZ.debug("[orm] No config/qb.ts override found \u2014 deriving config from DB_CONNECTION");let Z=n.DB_CONNECTION||"sqlite";RZ({...PZ,dialect:Z,database:Z==="sqlite"?{database:n.DB_DATABASE_PATH||"database/stacks.sqlite"}:{database:n.DB_DATABASE||"stacks",host:n.DB_HOST||"127.0.0.1",port:n.DB_PORT||(Z==="postgres"?5432:3306),username:n.DB_USERNAME||(Z==="postgres"?"postgres":"root"),password:n.DB_PASSWORD||""}})}bZ=hZ("app/Models"),QZ={};try{let{readdirSync:Z,statSync:$}=await import("fs"),{extname:z,basename:G}=await import("path"),J=Z(bZ);for(let L of J){let K=`${bZ}/${L}`;if($(K).isDirectory())continue;let B=z(K);if(![".ts",".js"].includes(B))continue;try{let W=await import(`${K}?t=${Date.now()}`),I=W.default??W,N=I.name??G(L,B);QZ[N]={...I,name:N}}catch{}}}catch{}P=K0();for(let[Z,$]of Object.entries(QZ)){let z=$.traits?.useApi;if(!z)continue;let G=typeof z==="object"?z:{},J=G.uri||$.table||Z.toLowerCase()+"s",L=G.routes||["index","show","store","update","destroy"],K=$.table||J,X=W0($),B=mZ($),W=`/api/${J}`,I=VZ($.attributes,B),{read:N,write:R,declared:D}=MZ(z);if(["store","update","destroy"].some((T)=>L.includes(T))&&D&&R.length===0)cZ.warn(`[orm] ${Z}: registering UNAUTHENTICATED mutating routes at ${W} (explicit \`middleware: []\` opt-out)`);let b=!!iZ($),q=b&&!N.includes("auth")?["auth",...N]:N,f=(T,Q=q)=>{let Y=T;for(let x of Q)if(Y&&typeof Y.middleware==="function")Y=Y.middleware(x);return Y};if(L.includes("index")&&!l("GET",W))f(c.get(W,async(T)=>{try{let Q=new URL(T.url),{page:Y,perPage:x,offset:A}=CZ(Q.searchParams),U=Q.searchParams.get("sort"),O=P.selectFrom(K);O=FZ(O,U,I);let y=new Set(["page","per_page","sort","fields","search","include","limit","offset","with_count","withTrashed","onlyTrashed"]);for(let[C,k]of Q.searchParams.entries()){if(y.has(C)||!k)continue;if(!/^[a-z_][a-z0-9_]*$/i.test(C))continue;let u=I.get(C);if(u)O=O.where(u,"=",k)}let E=Q.searchParams.get("search");if(E&&X.length>0){let C=X.slice(0,5);O=O.where((k)=>{for(let u of C)k=k.orWhere(M(u),"like",`%${E}%`);return k})}let j=Q.searchParams.get("fields");if(j){let C=j.split(",").map((k)=>k.trim()).filter((k)=>/^[a-z_][a-z0-9_]*$/i.test(k)).map((k)=>M(k));if(C.length>0)O=O.select(C)}let V=!!$.traits?.useSoftDeletes,F=Q.searchParams.get("withTrashed")==="true",m=Q.searchParams.get("onlyTrashed")==="true";if(V&&!F)O=m?O.whereNotNull("deleted_at"):O.whereNull("deleted_at");let _=b?await a($,await s(T),T):{enforced:!1,value:null,field:"",bypass:!1};if(_.enforced&&!_.bypass){if(_.value==null||Array.isArray(_.value)&&_.value.length===0){let C=HZ(Q,Y,x,0,!1,void 0);return new Response(JSON.stringify({data:[],...C,meta:JZ(Q,Y,x,0,!1,void 0)}),{status:200,headers:{"Content-Type":"application/json","Cache-Control":"private, no-store",Vary:"Authorization"}})}O=Array.isArray(_.value)?O.where(_.field,"in",_.value):O.where(_.field,"=",_.value)}let v=await O.limit(x+1).offset(A).get()||[],h=v.length>x,t=(h?v.slice(0,x):v).map((C)=>o(e(C,$),B)),_Z=Q.searchParams.get("include");if(_Z)t=await yZ(t,$,_Z,QZ);let sZ=Q.searchParams.get("with_count")==="true",d;if(sZ)try{let C=P.selectFrom(K);if(_.enforced&&!_.bypass&&_.value!=null)C=Array.isArray(_.value)?C.where(_.field,"in",_.value):C.where(_.field,"=",_.value);let k=await C.count(),u=typeof k==="number"?k:Number(k?.count??k);if(Number.isFinite(u))d=u}catch{}let $Z={"Content-Type":"application/json"};if(d!==void 0&&!Number.isNaN(d))$Z["X-Total-Count"]=String(d);$Z["Cache-Control"]=_.enforced&&!_.bypass?"private, no-store":"public, max-age=15, must-revalidate",$Z.Vary="Authorization";let tZ=HZ(Q,Y,x,t.length,h,d);return new Response(JSON.stringify({data:t,...tZ,meta:JZ(Q,Y,x,t.length,h,d)}),{status:200,headers:$Z})}catch(Q){if(Q instanceof i){let Y={error:Q.message};if(Q.details!==void 0)Y.details=Q.details;return H(Y,Q.status||400)}return H({error:`Failed to fetch ${J}`,detail:String(Q)},500)}}));if(L.includes("show")&&!l("GET",`${W}/{id}`))f(c.get(`${W}/{id}`,async(T)=>{try{let Q=KZ(T.params?.id);if(Q==null)return H({error:"Invalid ID parameter"},400);let Y=await P.selectFrom(K).where({id:Q}).executeTakeFirst();if(!Y)return H({error:`${Z} not found`},404);let x=new URL(T.url);if($.traits?.useSoftDeletes&&Y.deleted_at&&x.searchParams.get("withTrashed")!=="true")return H({error:`${Z} not found`},404);let A=b?await a($,await s(T),T):{enforced:!1,value:null,field:"",bypass:!1};if(A.enforced&&!A.bypass){if(A.value==null||!r(Y[A.field],A.value))return H({error:`${Z} not found`},404)}let U=o(e(Y,$),B),O=x.searchParams.get("include");if(O){let[F]=await yZ([U],$,O,QZ);U=F}let y=U?.updated_at||U?.created_at,E=y?`W/"${U.id}-${String(y)}"`:void 0,j=T.headers?.get?.("if-none-match");if(E&&j&&j===E)return new Response(null,{status:304,headers:{ETag:E}});let V={"Content-Type":"application/json"};if(E)V.ETag=E;return V["Cache-Control"]=A.enforced&&!A.bypass?"private, no-store":"public, max-age=30, must-revalidate",V.Vary="Authorization",new Response(JSON.stringify({data:U}),{status:200,headers:V})}catch(Q){if(Q instanceof i){let Y={error:Q.message};if(Q.details!==void 0)Y.details=Q.details;return H(Y,Q.status||400)}return H({error:`Failed to fetch ${Z}`,detail:String(Q)},500)}}));if(L.includes("store")&&!l("POST",W))f(c.post(W,async(T)=>{try{let Q=await OZ(T),Y=BZ(Q,B),x=TZ(Y,X),A=await s(T);if(A){let V=await vZ($,"creating",A,T);for(let[F,m]of Object.entries(V))if(m!==void 0&&m!==null&&x[F]===void 0)x[F]=m}if(Object.keys(x).length===0)return H({error:"No fillable fields provided"},422);let U=fZ(x,$,"creating");if(!U.valid)return H({error:"Validation failed",errors:U.errors},422);if($.traits?.useTimestamps!==!1){let V=new Date().toISOString();x.created_at=V,x.updated_at=V}let O=await gZ(x,$),y=YZ(wZ(O,$)),E=await P.insertInto(K).values(y).execute(),j=y;try{let V=E?.lastInsertRowid??E?.insertId??E;if(V){let F=await P.selectFrom(K).where({id:V}).executeTakeFirst();if(F)j=F}}catch{}return H({data:o(e(j,$),B)},201)}catch(Q){let{status:Y,body:x}=XZ(Q,Z,"create");return H(x,Y)}}),R);if(L.includes("update")){let T=async(Q)=>{try{let Y=KZ(Q.params?.id);if(Y==null)return H({error:"Invalid ID parameter"},400);let x=await OZ(Q),A=BZ(x,B),U=TZ(A,X),O=await s(Q);if(O){let _=await vZ($,"updating",O,Q);for(let[v,h]of Object.entries(_))if(h!==void 0&&h!==null&&U[v]===void 0)U[v]=h}if(Object.keys(U).length===0)return H({error:"No fillable fields provided"},422);let y=fZ(U,$,"updating");if(!y.valid)return H({error:"Validation failed",errors:y.errors},422);let E=await P.selectFrom(K).where({id:Y}).executeTakeFirst();if(!E)return H({error:`${Z} not found`},404);let j=await a($,O,Q);if(j.enforced&&!j.bypass){if(!O)return H({error:"Auth required"},401);let _=E[j.field];if(!r(_,j.value))return H({error:`Not your ${Z}`},403);let v=Object.keys(U).find((h)=>M(h)===M(j.field));if(v!==void 0&&!r(U[v],j.value))return H({error:`Cannot reassign ${Z} ownership`},403)}if($.traits?.useTimestamps!==!1)U.updated_at=new Date().toISOString();let V=await gZ(U,$),F=YZ(wZ(V,$));await P.updateTable(K).set(F).where({id:Y}).execute();let m={...E,...F};try{let _=await P.selectFrom(K).where({id:Y}).executeTakeFirst();if(_)m=_}catch{}return H({data:o(e(m,$),B)})}catch(Y){let{status:x,body:A}=XZ(Y,Z,"update");return H(A,x)}};if(!l("PUT",`${W}/{id}`))f(c.put(`${W}/{id}`,T),R);if(!l("PATCH",`${W}/{id}`))f(c.patch(`${W}/{id}`,T),R)}let w=!!$.traits?.useSoftDeletes;if(L.includes("destroy")&&!l("DELETE",`${W}/{id}`))f(c.delete(`${W}/{id}`,async(T)=>{try{let Q=KZ(T.params?.id);if(Q==null)return H({error:"Invalid ID parameter"},400);let Y=await P.selectFrom(K).where({id:Q}).executeTakeFirst();if(!Y)return H({error:`${Z} not found`},404);let x=await s(T),A=await a($,x,T);if(A.enforced&&!A.bypass){if(!x)return H({error:"Auth required"},401);let U=Y[A.field];if(!r(U,A.value))return H({error:`Not your ${Z}`},403)}if(w){let U=new Date().toISOString();await P.updateTable(K).set({deleted_at:U,updated_at:U}).where({id:Q}).execute()}else await P.deleteFrom(K).where({id:Q}).execute();return new Response(null,{status:204})}catch(Q){if(Q instanceof i){let Y={error:Q.message};if(Q.details!==void 0)Y.details=Q.details;return H(Y,Q.status||400)}return H({error:`Failed to delete ${Z}`,detail:String(Q)},500)}}),R);if(L.includes("destroy")&&!l("POST",`${W}/bulk-delete`))f(c.post(`${W}/bulk-delete`,async(T)=>{try{let Y=(await OZ(T))?.ids;if(!Array.isArray(Y)||Y.length===0)return H({error:"An array of IDs is required"},422);if(Y.length>100)return H({error:"Cannot delete more than 100 records at once"},422);let x=[],A=[];for(let E of Y){let j=KZ(E);if(j!=null)x.push(j);else A.push(E)}if(A.length>0)return H({error:"Invalid IDs in batch",invalid:A},422);let U=await s(T),O=await a($,U,T);if(O.enforced&&!O.bypass){if(!U)return H({error:"Auth required"},401);if(O.value==null)return H({error:"Caller has no ownership identity"},403);let E=await P.selectFrom(K).select(["id",O.field]).execute(),j=new Set(E.filter((F)=>r(F[O.field],O.value)).map((F)=>String(F.id))),V=x.filter((F)=>!j.has(String(F)));if(V.length>0)return H({error:`Cannot delete ${Z} you don't own`,ids:V},403)}let y=new Date().toISOString();for(let E of x)if(w)await P.updateTable(K).set({deleted_at:y,updated_at:y}).where({id:E}).execute();else await P.deleteFrom(K).where({id:E}).execute();return H({message:`Successfully deleted ${x.length} ${J}`})}catch(Q){if(Q instanceof i){let Y={error:Q.message};if(Q.details!==void 0)Y.details=Q.details;return H(Y,Q.status||400)}return H({error:`Failed to bulk delete ${J}`,detail:String(Q)},500)}}),R)}T0=c});class AZ{data;status;headers;isOk;constructor(Z,$,z,G){this.data=Z;this.status=$;this.headers=z;this.isOk=G}ok(){return this.status===200}created(){return this.status===201}accepted(){return this.status===202}noContent(){return this.status===204}movedPermanently(){return this.status===301}found(){return this.status===302}badRequest(){return this.status===400}unauthorized(){return this.status===401}paymentRequired(){return this.status===402}forbidden(){return this.status===403}notFound(){return this.status===404}requestTimeout(){return this.status===408}conflict(){return this.status===409}unprocessableEntity(){return this.status===422}tooManyRequests(){return this.status===429}serverError(){return this.status===500}}class EZ{defaultHeaders={Accept:"application/json","Content-Type":"application/json"};queryParams;bodyData;isFormData=!1;customHeaders={};attachments=[];isMultipart=!1;digestAuth;withQueryParams(Z){return this.queryParams=Z,this}withHeaders(Z){return this.customHeaders={...this.customHeaders,...Z},this}accept(Z){return this.defaultHeaders.Accept=Z,this}acceptJson(){return this.accept("application/json")}withToken(Z){return this.customHeaders.Authorization=`Bearer ${Z}`,this}withBasicAuth(Z,$){let z=btoa(`${Z}:${$}`);return this.customHeaders.Authorization=`Basic ${z}`,this}withDigestAuth(Z,$){return this.digestAuth={username:Z,password:$},this}withBody(Z){return this.bodyData=Z,this}asForm(){return this.isFormData=!0,this.defaultHeaders["Content-Type"]="application/x-www-form-urlencoded",this}attach(Z,$,z,G){let J=typeof $==="string"?new Blob([$],{type:G?.["Content-Type"]||"text/plain"}):$;return this.attachments.push({name:Z,content:J,filename:z,headers:G}),this.isMultipart=!0,delete this.defaultHeaders["Content-Type"],this}getHeaders(){return{...this.defaultHeaders,...this.customHeaders}}addQueryParams(Z){if(!this.queryParams)return Z;let $=new URLSearchParams;Object.entries(this.queryParams).forEach(([J,L])=>{if(L!=null)$.append(J,String(L))});let z=$.toString();if(!z)return Z;let G=Z.includes("?");return Z+(G?"&":"?")+z}async formatBody(Z){let $=Z||this.bodyData;if(this.isMultipart){let z=new FormData;if($)Object.entries($).forEach(([G,J])=>{z.append(G,String(J))});for(let G of this.attachments)if(G.headers){let J=G.content instanceof Blob?new Blob([G.content],{type:G.headers["Content-Type"]}):G.content;z.append(G.name,J,G.filename)}else z.append(G.name,G.content,G.filename);return z}if(this.isFormData&&$){let z=new URLSearchParams;return Object.entries($).forEach(([G,J])=>{if(J!=null)z.append(G,String(J))}),z.toString()}return $?JSON.stringify($):void 0}resetState(){this.queryParams=void 0,this.bodyData=void 0,this.isFormData=!1,this.isMultipart=!1,this.customHeaders={},this.attachments=[],this.digestAuth=void 0,this.defaultHeaders["Content-Type"]="application/json"}async handleDigestAuth(Z,$,z,G){if(Z.status!==401||!this.digestAuth)return Z;let J=Z.headers.get("WWW-Authenticate");if(!J?.startsWith("Digest "))return Z;let L=J.substring(7).split(",").reduce((D,S)=>{let[b,q]=S.trim().split("=");if(b)D[b]=q?.replace(/["']/g,"")??"";return D},{}),K=await this.generateMD5(`${this.digestAuth.username}:${L.realm}:${this.digestAuth.password}`),X=await this.generateMD5(`${z}:${$}`),B="00000001",W=await this.generateMD5(Date.now().toString()).then((D)=>D.substring(0,8)),I=await this.generateMD5(`${K}:${L.nonce}:${B}:${W}:${L.qop}:${X}`),N={username:`"${this.digestAuth.username}"`,realm:`"${L.realm}"`,nonce:`"${L.nonce}"`,uri:`"${$}"`,algorithm:L.algorithm?`"${L.algorithm}"`:void 0,qop:`"${L.qop}"`,nc:B,cnonce:`"${W}"`,response:`"${I}"`,opaque:L.opaque?`"${L.opaque}"`:void 0},R=Object.entries(N).filter(([D,S])=>S!==void 0).map(([D,S])=>`${D}=${S}`).join(", ");return this.customHeaders.Authorization=`Digest ${R}`,fetch($,{method:z,headers:this.getHeaders(),body:G?this.formatBody(G):void 0})}async generateMD5(Z){let z=new TextEncoder().encode(Z),G=await crypto.subtle.digest("SHA-256",z);return Array.from(new Uint8Array(G)).map((L)=>L.toString(16).padStart(2,"0")).join("")}async request(Z,$,z){let G=this.addQueryParams(Z),J=await this.formatBody(z),L=await fetch(G,{method:$,headers:this.getHeaders(),body:J});if(this.digestAuth)L=await this.handleDigestAuth(L,G,$,z);let K=await L.json();return this.resetState(),new AZ(K,L.status,L.headers,L.ok)}async get(Z){return this.request(Z,"GET")}async post(Z,$){return this.request(Z,"POST",$)}async put(Z,$){return this.request(Z,"PUT",$)}async patch(Z,$){return this.request(Z,"PATCH",$)}async delete(Z){return this.request(Z,"DELETE")}}var _0=new EZ;import{path as B0}from"@stacksjs/path";function x0(Z){if(!Z||typeof Z!=="object")return{type:"string"};let $=Z,z=$._type??"string",G={type:z==="array"?"array":z};if(typeof $._min==="number")G[z==="string"?"minLength":"minimum"]=$._min;if(typeof $._max==="number")G[z==="string"?"maxLength":"maximum"]=$._max;if($._email)G.format="email";if($._url)G.format="uri";if($._uuid)G.format="uuid";if(Array.isArray($._enum))G.enum=$._enum;return G}async function H0(Z){if(typeof Z!=="string"||!Z.includes("Actions"))return null;try{let{path:$}=await import("@stacksjs/path"),z=[$.appPath(`${Z}.ts`),$.storagePath(`framework/defaults/app/${Z}.ts`)];for(let G of z)try{if(!await Bun.file(G).exists())continue;let K=(await import(G)).default;if(K&&typeof K==="object"&&"validations"in K){let X=K.validations;return X&&typeof X==="object"?X:null}return null}catch{}}catch{}return null}async function R0(){let{listRegisteredRoutes:Z}=await import("@stacksjs/router");try{let{loadRoutes:K}=await import("@stacksjs/router"),{default:X}=await Promise.resolve().then(() => (SZ(),DZ));await K(X)}catch(K){let X=K instanceof Error?K.message:String(K);console.warn(`[generateOpenApi] Failed to load routes/api.ts + framework routes: ${X}`)}try{await nZ().then(() => uZ)}catch(K){let X=K instanceof Error?K.message:String(K);console.warn(`[generateOpenApi] Failed to load useApi-generated ORM routes: ${X}`)}let $=Z(),z="Stacks API";try{let{config:K}=await import("@stacksjs/config");if(K.app?.name)z=`${K.app.name} API`}catch{}let G={openapi:"3.0.0",info:{title:z,version:"1.0.0"},paths:{},components:{schemas:{}}};for(let K of $){let X=K.path.replace(/(^|\/):(\w+)(?=$|\/)/g,"$1{$2}");if(!G.paths[X])G.paths[X]={};let B=[];for(let N of K.path.matchAll(/\{(\w+)\}/g))if(N[1])B.push(N[1]);for(let N of K.path.matchAll(/(?:^|\/):(\w+)(?=$|\/)/g))if(N[1])B.push(N[1]);let W=K.method.toLowerCase(),I={summary:K.name??K.path,operationId:K.name??`${W}_${X.replace(/[^a-z0-9]/gi,"_")}`,parameters:B.map((N)=>({name:N,in:"path",required:!0,schema:{type:"string"}})),responses:{200:{description:"Successful response",content:{"application/json":{schema:{type:"object"}}}},422:{description:"Validation failed"},500:{description:"Server error"}}};if(W!=="get"&&W!=="head"&&K.name){let R=`Actions/${K.name.split(".").map((S)=>S.charAt(0).toUpperCase()+S.slice(1)).join("")}Action`,D=await H0(R);if(D&&Object.keys(D).length>0){let S={type:"object",properties:{},required:[]},b=S.properties,q=S.required;for(let[f,w]of Object.entries(D)){let T=w?.rule;if(b[f]=x0(T),T?._required)q.push(f)}if(q.length===0)delete S.required;I.requestBody={required:q.length>0,content:{"application/json":{schema:S}}}}}G.paths[X][W]=I}let L=Bun.file(B0.frameworkPath("api/openapi.json")).writer();return L.write(JSON.stringify(G,null,2)),await L.end(),G}class g{static instance=new g;isMissing(){return!0}}class ZZ{data;constructor(Z){this.data=Z}}class lZ{condition;value;defaultValue;constructor(Z,$,z=new g){this.condition=Z;this.value=$;this.defaultValue=z}resolve(){return(typeof this.condition==="function"?this.condition():this.condition)?this.value:this.defaultValue}}class dZ{resource;additional={};request;static wrap="data";static additionalMeta={};constructor(Z){this.resource=Z}withRequest(Z){return this.request=Z,this}withAdditional(Z){return this.additional={...this.additional,...Z},this}resolve(Z){let $=this.toArray(Z||this.request);return this.filterAndResolve($)}toResponse(Z){let $=this.resolve(Z),z=this.constructor.wrap;if(z)return{[z]:$,...this.additional};return{...$,...this.additional}}toJson(Z){return JSON.stringify(this.toResponse(Z))}toJSON(){return this.toResponse()}static collection(Z){return new UZ(Z,this)}when(Z,$,z){if(typeof Z==="function"?Z():Z)return typeof $==="function"?$():$;return z!==void 0?z:g.instance}whenNotNull(Z,$){if(Z===null||Z===void 0)return g.instance;return $?$(Z):Z}whenLoaded(Z,$,z){let G=this.resource;if(!((Z in G)&&G[Z]!==void 0))return z!==void 0?z:g.instance;if($!==void 0)return typeof $==="function"?$():$;return G[Z]}whenCounted(Z,$){let z=this.resource,G=`${Z}_count`;if(G in z)return z[G];return $!==void 0?$:g.instance}merge(Z){return new ZZ(Z)}mergeWhen(Z,$){if(!(typeof Z==="function"?Z():Z))return g.instance;let G=typeof $==="function"?$():$;return new ZZ(G)}static MAX_RESOLVE_DEPTH=20;filterAndResolve(Z,$=0){if($>=dZ.MAX_RESOLVE_DEPTH)return Z;let z={};for(let[G,J]of Object.entries(Z)){if(J instanceof g)continue;if(J instanceof ZZ){Object.assign(z,this.filterAndResolve(J.data,$+1));continue}if(J instanceof lZ){let L=J.resolve();if(!(L instanceof g))z[G]=L;continue}if(J!==null&&typeof J==="object"&&!Array.isArray(J)&&!(J instanceof Date)){z[G]=this.filterAndResolve(J,$+1);continue}if(Array.isArray(J)){z[G]=J.filter((L)=>!(L instanceof g)).map((L)=>{if(L instanceof ZZ)return L.data;if(L!==null&&typeof L==="object"&&!(L instanceof Date))return this.filterAndResolve(L,$+1);return L});continue}z[G]=J}return z}static withoutWrapping(){this.wrap=null}static wrapWith(Z){this.wrap=Z}}class UZ{resources;ResourceClass;additional={};request;static wrap="data";constructor(Z,$){this.resources=Z,this.ResourceClass=$}withRequest(Z){return this.request=Z,this}withAdditional(Z){return this.additional={...this.additional,...Z},this}resolve(Z){let $=Z||this.request;return this.resources.map((z)=>{let G=new this.ResourceClass(z);if($)G.withRequest($);return G.resolve($)})}toResponse(Z){let $=this.resolve(Z),z=this.constructor.wrap;if(z)return{[z]:$,...this.additional};return{data:$,...this.additional}}toJson(Z){return JSON.stringify(this.toResponse(Z))}count(){return this.resources.length}isEmpty(){return this.resources.length===0}isNotEmpty(){return this.resources.length>0}}class oZ extends UZ{meta;links;constructor(Z,$){super(Z.data,$);this.meta=Z.meta,this.links=Z.links}static fromPagination(Z,$,z){let{currentPage:G,perPage:J,total:L,baseUrl:K=""}=z,X=Math.ceil(L/J),B=L>0?(G-1)*J+1:null,W=L>0?Math.min(G*J,L):null;return new oZ({data:Z,meta:{current_page:G,from:B,last_page:X,per_page:J,to:W,total:L},links:{first:`${K}?page=1`,last:`${K}?page=${X}`,prev:G>1?`${K}?page=${G-1}`:null,next:G<X?`${K}?page=${G+1}`:null}},$)}toResponse(Z){return{data:this.resolve(Z),meta:this.meta,links:this.links,...this.additional}}}function f0(Z,$){let z=$(Z);return{toResponse:()=>({data:z}),toJson:()=>JSON.stringify({data:z})}}function q0(Z,$){let z=Z.map($);return{toResponse:()=>({data:z}),toJson:()=>JSON.stringify({data:z})}}export{f0 as resource,R0 as generateOpenApi,_0 as fetcher,q0 as collection,UZ as ResourceCollection,oZ as PaginatedResourceCollection,g as MissingValue,ZZ as MergeValue,dZ as JsonResource,lZ as ConditionalValue};
2
+ var e$=Object.defineProperty;var $O=($)=>$;function OO($,O){this[$]=$O.bind(null,O)}var H$=($,O)=>{for(var J in O)e$($,J,{get:O[J],enumerable:!0,configurable:!0,set:OO.bind(O,J)})};var G$=($,O)=>()=>($&&(O=$($=0)),O);var m=import.meta.require;var D$;var W$=G$(()=>{D$={api:"api",v1:{path:"v1",prefix:"v1"}}});var E$={};H$(E$,{default:()=>D$});var I$=G$(()=>{W$();W$()});function JO($){let O=$;return O?.code==="SQLITE_CONSTRAINT_UNIQUE"||O?.code==="SQLITE_CONSTRAINT"||O?.code==="23505"||O?.errno===1062||/unique|duplicate/i.test(O?.message??"")}function X$($,O,J){let G=$;if($ instanceof Error&&typeof G.status==="number"&&Number.isInteger(G.status)&&G.status>=400&&G.status<600){let Z={error:$.message};if(G.details!==void 0)Z.details=G.details;return{status:G.status,body:Z}}if(JO($))return{status:409,body:{error:`${O} already exists`}};return{status:500,body:{error:`Failed to ${J} ${O}`,detail:String($)}}}function V($){return $.replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}function Y$($){let O={};for(let[J,G]of Object.entries($))O[V(J)]=G;return O}function B$($,O){if(!$||O.length===0)return{};let J={};for(let G of O){if(G in $){J[G]=$[G];continue}let Z=V(G);if(Z!==G&&Z in $)J[G]=$[Z]}return J}function T$($,O){if(!O.length)return $;let J={...$};for(let G of O)delete J[G],delete J[V(G)];return J}function o($,O){if(!$||O.length===0)return $;let J={...$};for(let G of O)delete J[G],delete J[V(G)];return J}function V$($,O){let J=new Map;for(let G of[...Object.keys($??{}),...GO]){let Z=V(G);if(!/^\w+$/.test(Z))continue;J.set(G,Z),J.set(Z,Z)}for(let G of O)J.delete(G),J.delete(V(G));return J}function M$($,O,J){if(!O)return $;let G=String(O).split(",").map((z)=>z.trim()).filter(Boolean),Z=$;for(let z of G){let L=z.startsWith("-"),Q=L?z.slice(1):z;if(!/^\w+$/.test(Q))continue;let B=J.get(Q);if(!B)continue;Z=Z.orderBy(B,L?"desc":"asc")}return Z}function zO($){try{return JSON.parse($)}catch{return $}}function LO($){try{return JSON.parse($)}catch{return[]}}function x$($,O,J){if(!$||typeof $!=="object"||!O||Object.keys(O).length===0)return $;let G={...$};for(let[Z,z]of Object.entries(O)){let L=typeof z==="string"?ZO[z]:z;if(!L||typeof L[J]!=="function")continue;if(Object.prototype.hasOwnProperty.call(G,Z))G[Z]=L[J](G[Z]);let Q=V(Z);if(Q!==Z&&Object.prototype.hasOwnProperty.call(G,Q))G[Q]=L[J](G[Q])}return G}function C$($){let O=typeof $==="object"&&$!==null&&"middleware"in $,J=$?.middleware,G=Array.isArray(J)?J.filter((Z)=>typeof Z==="string"&&Z.length>0):typeof J==="string"&&J?[J]:[];return{read:G,write:O?G:["auth"],declared:O}}function k$($){let O=Number.parseInt($.get("page")||String(1),10),J=Number.isFinite(O)?Math.max(1,O):1,G=Number.parseInt($.get("per_page")||String(F$),10),Z=Math.min(Number.isFinite(G)?Math.max(1,G):F$,KO);return{page:J,perPage:Z,offset:(J-1)*Z}}function Z$($,O){let J=new URL($.toString());return J.searchParams.set("page",String(O)),`${J.pathname}${J.search}`}function z$($,O,J,G,Z,z){let L=(O-1)*J,Q=G===0,B={page:O,per_page:J,from:Q?null:L+1,to:Q?null:L+G,has_more_pages:Z,prev_page_url:O>1?Z$($,O-1):null,next_page_url:Z?Z$($,O+1):null};if(z!==void 0&&!Number.isNaN(z)){let W=Math.max(1,Math.ceil(z/J));B.total=z,B.last_page=W,B.first_page_url=Z$($,1),B.last_page_url=Z$($,W)}return B}function j$($,O,J,G,Z,z){let{page:L,...Q}=z$($,O,J,G,Z,z);return{current_page:L,...Q}}var GO,ZO,F$=15,KO=100;var P$=G$(()=>{GO=["id","uuid","created_at","updated_at","deleted_at"];ZO={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"?zO($):$,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"?LO($):[],set:($)=>$==null?null:Array.isArray($)?JSON.stringify($):$}}});var u$={};H$(u$,{default:()=>TO});import{route as h}from"@stacksjs/router";import{env as u}from"@stacksjs/env";import{projectPath as h$}from"@stacksjs/path";import{createQueryBuilder as QO,defaultConfig as R$,setConfig as f$}from"@stacksjs/query-builder";import{HttpError as i}from"@stacksjs/error-handling";import{log as p$}from"@stacksjs/logging";function l($,O){return h.routes.some((J)=>J.method===$&&J.path===O)}function XO($){if(!$.attributes)return[];return Object.entries($.attributes).filter(([O,J])=>J.fillable===!0).map(([O])=>O)}function m$($){if(!$.attributes)return[];return Object.entries($.attributes).filter(([O,J])=>J.hidden===!0).map(([O])=>O)}function y$($,O,J){let G=$,Z=O,z=J,L=Z?.attributes??{},Q={};for(let[B,W]of Object.entries(L)){let D=W?.validation?.rule;if(!D||typeof D.validate!=="function")continue;let _=Object.prototype.hasOwnProperty.call(G,B);if(!_&&z==="updating")continue;let R=_?G[B]:void 0,S=D.validate(R);if(!S?.valid&&Array.isArray(S?.errors)&&S.errors.length>0)Q[B]=S.errors.map((b)=>W?.validation?.message?.[b?.code]??b?.message??"invalid")}return Object.keys(Q).length===0?{valid:!0}:{valid:!1,errors:Q}}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 q$($,O,J,G){if(!$.length)return $;let Z=J.split(",").map((W)=>W.trim()).filter(Boolean);if(!Z.length)return $;let z=Array.isArray(O.belongsTo)?O.belongsTo:[],L=Array.isArray(O.hasMany)?O.hasMany:[],Q=Array.isArray(O.hasOne)?O.hasOne:[],B=new Map;for(let W of z)B.set(V(W),{kind:"belongsTo",modelName:W});for(let W of Q)B.set(V(W),{kind:"hasOne",modelName:W});for(let W of L)B.set(g$(V(W)),{kind:"hasMany",modelName:W});for(let W of Z){let D=B.get(W);if(!D)continue;let _=G[D.modelName];if(!_)continue;let R=_.table||g$(V(D.modelName)),S=m$(_),b=(M)=>o($$(M,_),S);if(D.kind==="belongsTo"||D.kind==="hasOne"){let M=`${V(D.modelName)}_id`,C=[...new Set($.map((Y)=>Y[M]).filter((Y)=>Y!=null))];if(!C.length){for(let Y of $)Y[W]=null;continue}let y=await f.selectFrom(R).whereIn("id",C).get(),q=new Map;for(let Y of y??[])q.set(String(Y.id),b(Y));for(let Y of $)Y[W]=q.get(String(Y[M]))??null}else{let M=String(O.name??""),C=`${V(M)}_id`,y=[...new Set($.map((K)=>K.id).filter((K)=>K!=null))];if(!y.length){for(let K of $)K[W]=[];continue}let q=await f.selectFrom(R).whereIn(C,y).get(),Y=new Map;for(let K of q??[]){let X=String(K[C]),T=Y.get(X)??[];T.push(b(K)),Y.set(X,T)}for(let K of $)K[W]=Y.get(String(K.id))??[]}}return $}async function w$($,O){let J=O?.set;if(!J||typeof J!=="object")return $;let G={...$};for(let[Z,z]of Object.entries(J)){if(typeof z!=="function"||!(Z in G))continue;try{G[Z]=await z(G)}catch{}}return G}function c$($,O){return x$($,O?.casts,"set")}function $$($,O){return x$($,O?.casts,"get")}function x($,O=200){return new Response(JSON.stringify($),{status:O,headers:{"Content-Type":"application/json"}})}async function A$($){if(Number($.headers?.get?.("content-length")??0)>L$)throw new i(413,`Request body exceeds ${L$}-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>L$)throw new i(413,`Request body exceeds ${L$}-byte limit`);if(!J)return{};let G=JSON.parse(J);return G&&typeof G==="object"&&!Array.isArray(G)?G:{}}catch(J){if(J instanceof i)throw J;throw new i(400,`Invalid JSON body: ${J.message}`)}}function K$($){if($==null)return null;if(typeof $==="number")return Number.isFinite($)&&$>0?$:null;if(typeof $==="string"){let O=$.trim();if(!O)return null;if(/^\d+$/.test(O)){let J=Number(O);return Number.isFinite(J)&&J>0?J:null}return O}return null}function i$($){let O=$.bearerToken;if(typeof O==="function"){let G=O.call($);if(G)return G}let J=$.headers?.get?.("authorization")||$.headers?.get?.("Authorization")||"";if(typeof J==="string"&&J.startsWith("Bearer "))return J.substring(7);return null}async function d($){let O=$._authenticatedUser;if(O)return O;let J=i$($);if(!J)return null;try{let{Auth:G}=await import("@stacksjs/auth"),Z=await G.getUserFromToken(J);if(Z)$._authenticatedUser=Z;return Z||null}catch{return null}}function a($,O){if($==null||O==null)return!1;if(Array.isArray(O))return O.some((J)=>String(J)===String($));return String($)===String(O)}function YO($){let O=$?.attributes||{},J=(G)=>Object.prototype.hasOwnProperty.call(O,G);return J("teamId")||J("team_id")?"team_id":null}function BO($){let O=i$($),J=$.headers?.get?.("cookie")||"";return{bearerToken:()=>O,cookies:{get:(G)=>{for(let Z of J.split(";")){let z=Z.indexOf("=");if(z===-1)continue;if(Z.slice(0,z).trim()===G)return decodeURIComponent(Z.slice(z+1).trim())}return null}}}}function n$($){if($?.ownership)return $.ownership;let O=YO($);if(!O)return null;return{field:O,resolve:async(J,G)=>{let{resolveAuthenticatedTeamId:Z}=await import("@stacksjs/auth");return Z(BO(G))}}}async function e($,O,J){let G=n$($);if(!G||!G.field||typeof G.resolve!=="function")return{enforced:!1,value:null,field:"",bypass:!1};let Z=typeof G.bypass==="function"?!!G.bypass(O,J):!1,z=null;try{z=await G.resolve(O,J)}catch{z=null}return{enforced:!0,value:z,field:String(G.field),bypass:Z}}async function v$($,O,J,G){let Z=$?.authedFill?.[O];if(!Z)return{};if(typeof Z==="function")try{let z=await Z(J,G);return z&&typeof z==="object"?z:{}}catch{return{}}if(typeof Z==="object"){let z={};for(let[L,Q]of Object.entries(Z))try{z[L]=typeof Q==="function"?await Q(J,G):Q}catch{}return z}return{}}var WO,b$,Q$,f,L$=1048576,TO;var l$=G$(async()=>{P$();WO=h$("config/qb.ts");try{let $=(await import(WO)).default;f$($??R$)}catch{p$.debug("[orm] No config/qb.ts override found \u2014 deriving config from DB_CONNECTION");let $=u.DB_CONNECTION||"sqlite";f$({...R$,dialect:$,database:$==="sqlite"?{database:u.DB_DATABASE_PATH||"database/stacks.sqlite"}:{database:u.DB_DATABASE||"stacks",host:u.DB_HOST||"127.0.0.1",port:u.DB_PORT||($==="postgres"?5432:3306),username:u.DB_USERNAME||($==="postgres"?"postgres":"root"),password:u.DB_PASSWORD||""}})}b$=h$("app/Models"),Q$={};try{let{readdirSync:$,statSync:O}=await import("fs"),{extname:J,basename:G}=await import("path"),Z=$(b$);for(let z of Z){let L=`${b$}/${z}`;if(O(L).isDirectory())continue;let B=J(L);if(![".ts",".js"].includes(B))continue;try{let W=await import(`${L}?t=${Date.now()}`),D=W.default??W,_=D.name??G(z,B);Q$[_]={...D,name:_}}catch{}}}catch{}f=QO();for(let[$,O]of Object.entries(Q$)){let J=O.traits?.useApi;if(!J)continue;let G=typeof J==="object"?J:{},Z=G.uri||O.table||$.toLowerCase()+"s",z=G.routes||["index","show","store","update","destroy"],L=O.table||Z,Q=XO(O),B=m$(O),W=`/api/${Z}`,D=V$(O.attributes,B),{read:_,write:R,declared:S}=C$(J);if(["store","update","destroy"].some((Y)=>z.includes(Y))&&S&&R.length===0)p$.warn(`[orm] ${$}: registering UNAUTHENTICATED mutating routes at ${W} (explicit \`middleware: []\` opt-out)`);let M=!!n$(O),C=M&&!_.includes("auth")?["auth",..._]:_,y=(Y,K=C)=>{let X=Y;for(let T of K)if(X&&typeof X.middleware==="function")X=X.middleware(T);return X};if(z.includes("index")&&!l("GET",W))y(h.get(W,async(Y)=>{try{let K=new URL(Y.url),{page:X,perPage:T,offset:H}=k$(K.searchParams),A=K.searchParams.get("sort"),j=f.selectFrom(L);j=M$(j,A,D);let g=new Set(["page","per_page","sort","fields","search","include","limit","offset","with_count","withTrashed","onlyTrashed"]);for(let[k,P]of K.searchParams.entries()){if(g.has(k)||!P)continue;if(!/^[a-z_][a-z0-9_]*$/i.test(k))continue;let n=D.get(k);if(n)j=j.where(n,"=",P)}let U=K.searchParams.get("search");if(U&&Q.length>0){let k=Q.slice(0,5);j=j.where((P)=>{for(let n of k)P=P.orWhere(V(n),"like",`%${U}%`);return P})}let E=K.searchParams.get("fields");if(E){let k=E.split(",").map((P)=>P.trim()).filter((P)=>/^[a-z_][a-z0-9_]*$/i.test(P)).map((P)=>V(P));if(k.length>0)j=j.select(k)}let I=!!O.traits?.useSoftDeletes,F=K.searchParams.get("withTrashed")==="true",p=K.searchParams.get("onlyTrashed")==="true";if(I&&!F)j=p?j.whereNotNull("deleted_at"):j.whereNull("deleted_at");let N=M?await e(O,await d(Y),Y):{enforced:!1,value:null,field:"",bypass:!1};if(N.enforced&&!N.bypass){if(N.value==null||Array.isArray(N.value)&&N.value.length===0){let k=j$(K,X,T,0,!1,void 0);return new Response(JSON.stringify({data:[],...k,meta:z$(K,X,T,0,!1,void 0)}),{status:200,headers:{"Content-Type":"application/json","Cache-Control":"private, no-store",Vary:"Authorization"}})}j=Array.isArray(N.value)?j.where(N.field,"in",N.value):j.where(N.field,"=",N.value)}let c=await j.limit(T+1).offset(H).get()||[],v=c.length>T,r=(v?c.slice(0,T):c).map((k)=>o($$(k,O),B)),N$=K.searchParams.get("include");if(N$)r=await q$(r,O,N$,Q$);let r$=K.searchParams.get("with_count")==="true",t;if(r$)try{let k=f.selectFrom(L);if(N.enforced&&!N.bypass&&N.value!=null)k=Array.isArray(N.value)?k.where(N.field,"in",N.value):k.where(N.field,"=",N.value);let P=await k.count(),n=typeof P==="number"?P:Number(P?.count??P);if(Number.isFinite(n))t=n}catch{}let J$={"Content-Type":"application/json"};if(t!==void 0&&!Number.isNaN(t))J$["X-Total-Count"]=String(t);J$["Cache-Control"]=N.enforced&&!N.bypass?"private, no-store":"public, max-age=15, must-revalidate",J$.Vary="Authorization";let a$=j$(K,X,T,r.length,v,t);return new Response(JSON.stringify({data:r,...a$,meta:z$(K,X,T,r.length,v,t)}),{status:200,headers:J$})}catch(K){if(K instanceof i){let X={error:K.message};if(K.details!==void 0)X.details=K.details;return x(X,K.status||400)}return x({error:`Failed to fetch ${Z}`,detail:String(K)},500)}}));if(z.includes("show")&&!l("GET",`${W}/{id}`))y(h.get(`${W}/{id}`,async(Y)=>{try{let K=K$(Y.params?.id);if(K==null)return x({error:"Invalid ID parameter"},400);let X=await f.selectFrom(L).where({id:K}).executeTakeFirst();if(!X)return x({error:`${$} not found`},404);let T=new URL(Y.url);if(O.traits?.useSoftDeletes&&X.deleted_at&&T.searchParams.get("withTrashed")!=="true")return x({error:`${$} not found`},404);let H=M?await e(O,await d(Y),Y):{enforced:!1,value:null,field:"",bypass:!1};if(H.enforced&&!H.bypass){if(H.value==null||!a(X[H.field],H.value))return x({error:`${$} not found`},404)}let A=o($$(X,O),B),j=T.searchParams.get("include");if(j){let[F]=await q$([A],O,j,Q$);A=F}let g=A?.updated_at||A?.created_at,U=g?`W/"${A.id}-${String(g)}"`:void 0,E=Y.headers?.get?.("if-none-match");if(U&&E&&E===U)return new Response(null,{status:304,headers:{ETag:U}});let I={"Content-Type":"application/json"};if(U)I.ETag=U;return I["Cache-Control"]=H.enforced&&!H.bypass?"private, no-store":"public, max-age=30, must-revalidate",I.Vary="Authorization",new Response(JSON.stringify({data:A}),{status:200,headers:I})}catch(K){if(K instanceof i){let X={error:K.message};if(K.details!==void 0)X.details=K.details;return x(X,K.status||400)}return x({error:`Failed to fetch ${$}`,detail:String(K)},500)}}));if(z.includes("store")&&!l("POST",W))y(h.post(W,async(Y)=>{try{let K=await A$(Y),X=T$(K,B),T=B$(X,Q),H=await d(Y);if(H){let I=await v$(O,"creating",H,Y);for(let[F,p]of Object.entries(I))if(p!==void 0&&p!==null&&T[F]===void 0)T[F]=p}if(Object.keys(T).length===0)return x({error:"No fillable fields provided"},422);let A=y$(T,O,"creating");if(!A.valid)return x({error:"Validation failed",errors:A.errors},422);if(O.traits?.useTimestamps!==!1){let I=new Date().toISOString();T.created_at=I,T.updated_at=I}let j=await w$(T,O),g=Y$(c$(j,O)),U=await f.insertInto(L).values(g).execute(),E=g;try{let I=U?.lastInsertRowid??U?.insertId??U;if(I){let F=await f.selectFrom(L).where({id:I}).executeTakeFirst();if(F)E=F}}catch{}return x({data:o($$(E,O),B)},201)}catch(K){let{status:X,body:T}=X$(K,$,"create");return x(T,X)}}),R);if(z.includes("update")){let Y=async(K)=>{try{let X=K$(K.params?.id);if(X==null)return x({error:"Invalid ID parameter"},400);let T=await A$(K),H=T$(T,B),A=B$(H,Q),j=await d(K);if(j){let N=await v$(O,"updating",j,K);for(let[c,v]of Object.entries(N))if(v!==void 0&&v!==null&&A[c]===void 0)A[c]=v}if(Object.keys(A).length===0)return x({error:"No fillable fields provided"},422);let g=y$(A,O,"updating");if(!g.valid)return x({error:"Validation failed",errors:g.errors},422);let U=await f.selectFrom(L).where({id:X}).executeTakeFirst();if(!U)return x({error:`${$} not found`},404);let E=await e(O,j,K);if(E.enforced&&!E.bypass){if(!j)return x({error:"Auth required"},401);let N=U[E.field];if(!a(N,E.value))return x({error:`Not your ${$}`},403);let c=Object.keys(A).find((v)=>V(v)===V(E.field));if(c!==void 0&&!a(A[c],E.value))return x({error:`Cannot reassign ${$} ownership`},403)}if(O.traits?.useTimestamps!==!1)A.updated_at=new Date().toISOString();let I=await w$(A,O),F=Y$(c$(I,O));await f.updateTable(L).set(F).where({id:X}).execute();let p={...U,...F};try{let N=await f.selectFrom(L).where({id:X}).executeTakeFirst();if(N)p=N}catch{}return x({data:o($$(p,O),B)})}catch(X){let{status:T,body:H}=X$(X,$,"update");return x(H,T)}};if(!l("PUT",`${W}/{id}`))y(h.put(`${W}/{id}`,Y),R);if(!l("PATCH",`${W}/{id}`))y(h.patch(`${W}/{id}`,Y),R)}let q=!!O.traits?.useSoftDeletes;if(z.includes("destroy")&&!l("DELETE",`${W}/{id}`))y(h.delete(`${W}/{id}`,async(Y)=>{try{let K=K$(Y.params?.id);if(K==null)return x({error:"Invalid ID parameter"},400);let X=await f.selectFrom(L).where({id:K}).executeTakeFirst();if(!X)return x({error:`${$} not found`},404);let T=await d(Y),H=await e(O,T,Y);if(H.enforced&&!H.bypass){if(!T)return x({error:"Auth required"},401);let A=X[H.field];if(!a(A,H.value))return x({error:`Not your ${$}`},403)}if(q){let A=new Date().toISOString();await f.updateTable(L).set({deleted_at:A,updated_at:A}).where({id:K}).execute()}else await f.deleteFrom(L).where({id:K}).execute();return new Response(null,{status:204})}catch(K){if(K instanceof i){let X={error:K.message};if(K.details!==void 0)X.details=K.details;return x(X,K.status||400)}return x({error:`Failed to delete ${$}`,detail:String(K)},500)}}),R);if(z.includes("destroy")&&!l("POST",`${W}/bulk-delete`))y(h.post(`${W}/bulk-delete`,async(Y)=>{try{let X=(await A$(Y))?.ids;if(!Array.isArray(X)||X.length===0)return x({error:"An array of IDs is required"},422);if(X.length>100)return x({error:"Cannot delete more than 100 records at once"},422);let T=[],H=[];for(let U of X){let E=K$(U);if(E!=null)T.push(E);else H.push(U)}if(H.length>0)return x({error:"Invalid IDs in batch",invalid:H},422);let A=await d(Y),j=await e(O,A,Y);if(j.enforced&&!j.bypass){if(!A)return x({error:"Auth required"},401);if(j.value==null)return x({error:"Caller has no ownership identity"},403);let U=await f.selectFrom(L).select(["id",j.field]).execute(),E=new Set(U.filter((F)=>a(F[j.field],j.value)).map((F)=>String(F.id))),I=T.filter((F)=>!E.has(String(F)));if(I.length>0)return x({error:`Cannot delete ${$} you don't own`,ids:I},403)}let g=new Date().toISOString();for(let U of T)if(q)await f.updateTable(L).set({deleted_at:g,updated_at:g}).where({id:U}).execute();else await f.deleteFrom(L).where({id:U}).execute();return x({message:`Successfully deleted ${T.length} ${Z}`})}catch(K){if(K instanceof i){let X={error:K.message};if(K.details!==void 0)X.details=K.details;return x(X,K.status||400)}return x({error:`Failed to bulk delete ${Z}`,detail:String(K)},500)}}),R)}TO=h});class U${data;status;headers;isOk;constructor($,O,J,G){this.data=$;this.status=O;this.headers=J;this.isOk=G}ok(){return this.status===200}created(){return this.status===201}accepted(){return this.status===202}noContent(){return this.status===204}movedPermanently(){return this.status===301}found(){return this.status===302}badRequest(){return this.status===400}unauthorized(){return this.status===401}paymentRequired(){return this.status===402}forbidden(){return this.status===403}notFound(){return this.status===404}requestTimeout(){return this.status===408}conflict(){return this.status===409}unprocessableEntity(){return this.status===422}tooManyRequests(){return this.status===429}serverError(){return this.status===500}}class _${defaultHeaders={Accept:"application/json","Content-Type":"application/json"};queryParams;bodyData;isFormData=!1;customHeaders={};attachments=[];isMultipart=!1;digestAuth;withQueryParams($){return this.queryParams=$,this}withHeaders($){return this.customHeaders={...this.customHeaders,...$},this}accept($){return this.defaultHeaders.Accept=$,this}acceptJson(){return this.accept("application/json")}withToken($){return this.customHeaders.Authorization=`Bearer ${$}`,this}withBasicAuth($,O){let J=btoa(`${$}:${O}`);return this.customHeaders.Authorization=`Basic ${J}`,this}withDigestAuth($,O){return this.digestAuth={username:$,password:O},this}withBody($){return this.bodyData=$,this}asForm(){return this.isFormData=!0,this.defaultHeaders["Content-Type"]="application/x-www-form-urlencoded",this}attach($,O,J,G){let Z=typeof O==="string"?new Blob([O],{type:G?.["Content-Type"]||"text/plain"}):O;return this.attachments.push({name:$,content:Z,filename:J,headers:G}),this.isMultipart=!0,delete this.defaultHeaders["Content-Type"],this}getHeaders(){return{...this.defaultHeaders,...this.customHeaders}}addQueryParams($){if(!this.queryParams)return $;let O=new URLSearchParams;Object.entries(this.queryParams).forEach(([Z,z])=>{if(z!=null)O.append(Z,String(z))});let J=O.toString();if(!J)return $;let G=$.includes("?");return $+(G?"&":"?")+J}async formatBody($){let O=$||this.bodyData;if(this.isMultipart){let J=new FormData;if(O)Object.entries(O).forEach(([G,Z])=>{J.append(G,String(Z))});for(let G of this.attachments)if(G.headers){let Z=G.content instanceof Blob?new Blob([G.content],{type:G.headers["Content-Type"]}):G.content;J.append(G.name,Z,G.filename)}else J.append(G.name,G.content,G.filename);return J}if(this.isFormData&&O){let J=new URLSearchParams;return Object.entries(O).forEach(([G,Z])=>{if(Z!=null)J.append(G,String(Z))}),J.toString()}return O?JSON.stringify(O):void 0}resetState(){this.queryParams=void 0,this.bodyData=void 0,this.isFormData=!1,this.isMultipart=!1,this.customHeaders={},this.attachments=[],this.digestAuth=void 0,this.defaultHeaders["Content-Type"]="application/json"}async handleDigestAuth($,O,J,G){if($.status!==401||!this.digestAuth)return $;let Z=$.headers.get("WWW-Authenticate");if(!Z?.startsWith("Digest "))return $;let z=Z.substring(7).split(",").reduce((S,b)=>{let[M,C]=b.trim().split("=");if(M)S[M]=C?.replace(/["']/g,"")??"";return S},{}),L=await this.generateMD5(`${this.digestAuth.username}:${z.realm}:${this.digestAuth.password}`),Q=await this.generateMD5(`${J}:${O}`),B="00000001",W=await this.generateMD5(Date.now().toString()).then((S)=>S.substring(0,8)),D=await this.generateMD5(`${L}:${z.nonce}:${B}:${W}:${z.qop}:${Q}`),_={username:`"${this.digestAuth.username}"`,realm:`"${z.realm}"`,nonce:`"${z.nonce}"`,uri:`"${O}"`,algorithm:z.algorithm?`"${z.algorithm}"`:void 0,qop:`"${z.qop}"`,nc:B,cnonce:`"${W}"`,response:`"${D}"`,opaque:z.opaque?`"${z.opaque}"`:void 0},R=Object.entries(_).filter(([S,b])=>b!==void 0).map(([S,b])=>`${S}=${b}`).join(", ");return this.customHeaders.Authorization=`Digest ${R}`,fetch(O,{method:J,headers:this.getHeaders(),body:G?this.formatBody(G):void 0})}async generateMD5($){let J=new TextEncoder().encode($),G=await crypto.subtle.digest("SHA-256",J);return Array.from(new Uint8Array(G)).map((z)=>z.toString(16).padStart(2,"0")).join("")}async request($,O,J){let G=this.addQueryParams($),Z=await this.formatBody(J),z=await fetch(G,{method:O,headers:this.getHeaders(),body:Z});if(this.digestAuth)z=await this.handleDigestAuth(z,G,O,J);let L=await z.json();return this.resetState(),new U$(L,z.status,z.headers,z.ok)}async get($){return this.request($,"GET")}async post($,O){return this.request($,"POST",O)}async put($,O){return this.request($,"PUT",O)}async patch($,O){return this.request($,"PATCH",O)}async delete($){return this.request($,"DELETE")}}var EO=new _$;import{path as xO}from"@stacksjs/path";function jO($){if(!$||typeof $!=="object")return{type:"string"};let O=$,J=O._type??"string",G={type:J==="array"?"array":J};if(typeof O._min==="number")G[J==="string"?"minLength":"minimum"]=O._min;if(typeof O._max==="number")G[J==="string"?"maxLength":"maximum"]=O._max;if(O._email)G.format="email";if(O._url)G.format="uri";if(O._uuid)G.format="uuid";if(Array.isArray(O._enum))G.enum=O._enum;return G}async function AO($){if(typeof $!=="string"||!$.includes("Actions"))return null;try{let{path:O}=await import("@stacksjs/path"),J=[O.appPath(`${$}.ts`),O.storagePath(`framework/defaults/app/${$}.ts`)];for(let G of J)try{if(!await Bun.file(G).exists())continue;let L=(await import(G)).default;if(L&&typeof L==="object"&&"validations"in L){let Q=L.validations;return Q&&typeof Q==="object"?Q:null}return null}catch{}}catch{}return null}async function wO($={}){let{listRegisteredRoutes:O}=await import("@stacksjs/router");try{let{loadRoutes:L}=await import("@stacksjs/router"),{default:Q}=await Promise.resolve().then(() => (I$(),E$));await L(Q)}catch(L){let Q=L instanceof Error?L.message:String(L);console.warn(`[generateOpenApi] Failed to load routes/api.ts + framework routes: ${Q}`)}try{await l$().then(() => u$)}catch(L){let Q=L instanceof Error?L.message:String(L);console.warn(`[generateOpenApi] Failed to load useApi-generated ORM routes: ${Q}`)}let J=O(),G="Stacks API";try{let{config:L}=await import("@stacksjs/config");if(L.app?.name)G=`${L.app.name} API`}catch{}let Z={openapi:"3.0.0",info:{title:G,version:"1.0.0"},paths:{},components:{schemas:{}}},z=new Set;for(let L of J){let Q=L.path.replace(/(^|\/):(\w+)(?=$|\/)/g,"$1{$2}");if(!Z.paths[Q])Z.paths[Q]={};let B=[];for(let S of L.path.matchAll(/\{(\w+)\}/g))if(S[1])B.push(S[1]);for(let S of L.path.matchAll(/(?:^|\/):(\w+)(?=$|\/)/g))if(S[1])B.push(S[1]);let W=L.method.toLowerCase(),D=L.name??`${W}_${Q.replace(/[^a-z0-9]/gi,"_")}`,_=D;if(z.has(_)){_=`${D}_${W}`;let S=2;while(z.has(_))_=`${D}_${W}_${S++}`}z.add(_);let R={summary:L.name??L.path,operationId:_,parameters:B.map((S)=>({name:S,in:"path",required:!0,schema:{type:"string"}})),responses:{200:{description:"Successful response",content:{"application/json":{schema:{type:"object"}}}},422:{description:"Validation failed"},500:{description:"Server error"}}};if(W!=="get"&&W!=="head"&&L.name){let b=`Actions/${L.name.split(".").map((C)=>C.charAt(0).toUpperCase()+C.slice(1)).join("")}Action`,M=await AO(b);if(M&&Object.keys(M).length>0){let C={type:"object",properties:{},required:[]},y=C.properties,q=C.required;for(let[Y,K]of Object.entries(M)){let X=K?.rule;if(y[Y]=jO(X),X?._required)q.push(Y)}if(q.length===0)delete C.required;R.requestBody={required:q.length>0,content:{"application/json":{schema:C}}}}}Z.paths[Q][W]=R}if($.write!==!1){let Q=Bun.file(xO.frameworkPath("api/openapi.json")).writer();Q.write(JSON.stringify(Z,null,2)),await Q.end()}return Z}var SO=["get","put","post","delete","options","head","patch","trace"];function NO($){return typeof $==="string"?JSON.stringify($):String($)}function s($){if(!$)return"unknown";if($.enum?.length)return $.enum.map(NO).join(" | ");if($.type==="string")return"string";if($.type==="number"||$.type==="integer")return"number";if($.type==="boolean")return"boolean";if($.type==="null")return"null";if($.type==="array")return`Array<${s($.items)}>`;if($.type==="object"||$.properties||$.additionalProperties){let O=new Set($.required||[]),J=Object.entries($.properties||{}).map(([G,Z])=>`${JSON.stringify(G)}${O.has(G)?"":"?"}: ${s(Z)}`);if($.additionalProperties){let G=$.additionalProperties===!0?"unknown":s($.additionalProperties);J.push(`[key: string]: ${G}`)}return J.length?`{ ${J.join("; ")} }`:"Record<string, unknown>"}return"unknown"}function HO($=[]){return` parameters: {
3
+ ${["query","header","path","cookie"].map((J)=>{let G=$.filter((z)=>z.in===J);if(!G.length)return` ${J}?: never`;let Z=G.map((z)=>`${JSON.stringify(z.name)}${z.required?"":"?"}: ${s(z.schema)}`);return` ${J}${G.every((z)=>!z.required)?"?":""}: { ${Z.join("; ")} }`}).join(`
4
+ `)}
5
+ }`}function t$($){if(!$||!Object.keys($).length)return"never";return`{ ${Object.entries($).map(([O,J])=>`${JSON.stringify(O)}: ${s(J.schema)}`).join("; ")} }`}function UO($){let O=$.requestBody?`
6
+ requestBody${$.requestBody.required?"":"?"}: { content: ${t$($.requestBody.content)} }`:`
7
+ requestBody?: never`,J=Object.entries($.responses||{}).map(([G,Z])=>` ${JSON.stringify(G)}: { content: ${t$(Z.content)} }`);return`{
8
+ ${HO($.parameters)}${O}
9
+ responses: {
10
+ ${J.join(`
11
+ `)}
12
+ }
13
+ }`}function vO($){let O=Object.entries($.paths||{}).map(([G,Z])=>{let z=SO.map((L)=>{let Q=Z[L];return Q?` ${L}: ${UO(Q)}`:` ${L}?: never`});return` ${JSON.stringify(G)}: {
14
+ ${z.join(`
15
+ `)}
16
+ }`}),J=Object.entries($.components?.schemas||{}).map(([G,Z])=>` ${JSON.stringify(G)}: ${s(Z)}`);return`/**
17
+ * Generated from storage/framework/api/openapi.json by @stacksjs/api.
18
+ * Do not edit this file directly; run bun run docs:artifacts to regenerate it.
19
+ */
20
+
21
+ export interface paths {
22
+ ${O.join(`
23
+ `)}
24
+ }
25
+
26
+ export interface components {
27
+ schemas: {
28
+ ${J.join(`
29
+ `)}
30
+ }
31
+ }
32
+ `}class w{static instance=new w;isMissing(){return!0}}class O${data;constructor($){this.data=$}}class o${condition;value;defaultValue;constructor($,O,J=new w){this.condition=$;this.value=O;this.defaultValue=J}resolve(){return(typeof this.condition==="function"?this.condition():this.condition)?this.value:this.defaultValue}}class d${resource;additional={};request;static wrap="data";static additionalMeta={};constructor($){this.resource=$}withRequest($){return this.request=$,this}withAdditional($){return this.additional={...this.additional,...$},this}resolve($){let O=this.toArray($||this.request);return this.filterAndResolve(O)}toResponse($){let O=this.resolve($),J=this.constructor.wrap;if(J)return{[J]:O,...this.additional};return{...O,...this.additional}}toJson($){return JSON.stringify(this.toResponse($))}toJSON(){return this.toResponse()}static collection($){return new S$($,this)}when($,O,J){if(typeof $==="function"?$():$)return typeof O==="function"?O():O;return J!==void 0?J:w.instance}whenNotNull($,O){if($===null||$===void 0)return w.instance;return O?O($):$}whenLoaded($,O,J){let G=this.resource;if(!(($ in G)&&G[$]!==void 0))return J!==void 0?J:w.instance;if(O!==void 0)return typeof O==="function"?O():O;return G[$]}whenCounted($,O){let J=this.resource,G=`${$}_count`;if(G in J)return J[G];return O!==void 0?O:w.instance}merge($){return new O$($)}mergeWhen($,O){if(!(typeof $==="function"?$():$))return w.instance;let G=typeof O==="function"?O():O;return new O$(G)}static MAX_RESOLVE_DEPTH=20;filterAndResolve($,O=0){if(O>=d$.MAX_RESOLVE_DEPTH)return $;let J={};for(let[G,Z]of Object.entries($)){if(Z instanceof w)continue;if(Z instanceof O$){Object.assign(J,this.filterAndResolve(Z.data,O+1));continue}if(Z instanceof o$){let z=Z.resolve();if(!(z instanceof w))J[G]=z;continue}if(Z!==null&&typeof Z==="object"&&!Array.isArray(Z)&&!(Z instanceof Date)){J[G]=this.filterAndResolve(Z,O+1);continue}if(Array.isArray(Z)){J[G]=Z.filter((z)=>!(z instanceof w)).map((z)=>{if(z instanceof O$)return z.data;if(z!==null&&typeof z==="object"&&!(z instanceof Date))return this.filterAndResolve(z,O+1);return z});continue}J[G]=Z}return J}static withoutWrapping(){this.wrap=null}static wrapWith($){this.wrap=$}}class S${resources;ResourceClass;additional={};request;static wrap="data";constructor($,O){this.resources=$,this.ResourceClass=O}withRequest($){return this.request=$,this}withAdditional($){return this.additional={...this.additional,...$},this}resolve($){let O=$||this.request;return this.resources.map((J)=>{let G=new this.ResourceClass(J);if(O)G.withRequest(O);return G.resolve(O)})}toResponse($){let O=this.resolve($),J=this.constructor.wrap;if(J)return{[J]:O,...this.additional};return{data:O,...this.additional}}toJson($){return JSON.stringify(this.toResponse($))}count(){return this.resources.length}isEmpty(){return this.resources.length===0}isNotEmpty(){return this.resources.length>0}}class s$ extends S${meta;links;constructor($,O){super($.data,O);this.meta=$.meta,this.links=$.links}static fromPagination($,O,J){let{currentPage:G,perPage:Z,total:z,baseUrl:L=""}=J,Q=Math.ceil(z/Z),B=z>0?(G-1)*Z+1:null,W=z>0?Math.min(G*Z,z):null;return new s$({data:$,meta:{current_page:G,from:B,last_page:Q,per_page:Z,to:W,total:z},links:{first:`${L}?page=1`,last:`${L}?page=${Q}`,prev:G>1?`${L}?page=${G-1}`:null,next:G<Q?`${L}?page=${G+1}`:null}},O)}toResponse($){return{data:this.resolve($),meta:this.meta,links:this.links,...this.additional}}}function pO($,O){let J=O($);return{toResponse:()=>({data:J}),toJson:()=>JSON.stringify({data:J})}}function mO($,O){let J=$.map(O);return{toResponse:()=>({data:J}),toJson:()=>JSON.stringify({data:J})}}export{s as schemaType,pO as resource,vO as renderOpenApiTypes,wO as generateOpenApi,EO as fetcher,mO as collection,S$ as ResourceCollection,s$ as PaginatedResourceCollection,w as MissingValue,O$ as MergeValue,d$ as JsonResource,o$ as ConditionalValue};
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/api",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.70.160",
5
+ "version": "0.70.162",
6
6
  "description": "The Stacks array utilities.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -50,12 +50,12 @@
50
50
  ],
51
51
  "scripts": {
52
52
  "build": "bun build.ts",
53
- "generate-types": "open-api ./../../api/openapi.json --output ./../../api/api-types.ts",
53
+ "generate-types": "bun src/generate-types.ts",
54
54
  "typecheck": "bun tsc --noEmit",
55
55
  "prepublishOnly": "bun run build"
56
56
  },
57
57
  "devDependencies": {
58
58
  "better-dx": "^0.2.17",
59
- "@stacksjs/utils": "0.70.160"
59
+ "@stacksjs/utils": "0.70.162"
60
60
  }
61
61
  }