@stacksjs/api 0.74.19 → 0.74.21

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.
Files changed (2) hide show
  1. package/dist/index.js +15 -15
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -1,19 +1,19 @@
1
1
  // @bun
2
- var xt=Object.defineProperty;var Pt=(e)=>e;function jt(e,t){this[e]=Pt.bind(null,t)}var de=(e,t)=>{for(var n in t)xt(e,n,{get:t[n],enumerable:!0,configurable:!0,set:jt.bind(t,n)})};var K=(e,t)=>()=>(e&&(t=e(e=0)),t);var V=import.meta.require;var Me={};de(Me,{renderOpenApiTypes:()=>Nt,schemaType:()=>J});function Dt(e){return typeof e==="string"?JSON.stringify(e):String(e)}function J(e){if(!e)return"unknown";if(e.enum?.length)return e.enum.map(Dt).join(" | ");if(e.type==="string")return"string";if(e.type==="number"||e.type==="integer")return"number";if(e.type==="boolean")return"boolean";if(e.type==="null")return"null";if(e.type==="array")return`Array<${J(e.items)}>`;if(e.type==="object"||e.properties||e.additionalProperties){let t=new Set(e.required||[]),n=Object.entries(e.properties||{}).map(([r,s])=>`${JSON.stringify(r)}${t.has(r)?"":"?"}: ${J(s)}`);if(e.additionalProperties){let r=e.additionalProperties===!0?"unknown":J(e.additionalProperties);n.push(`[key: string]: ${r}`)}return n.length?`{ ${n.join("; ")} }`:"Record<string, unknown>"}return"unknown"}function qt(e=[]){return` parameters: {
3
- ${["query","header","path","cookie"].map((n)=>{let r=e.filter((o)=>o.in===n);if(!r.length)return` ${n}?: never`;let s=r.map((o)=>`${JSON.stringify(o.name)}${o.required?"":"?"}: ${J(o.schema)}`);return` ${n}${r.every((o)=>!o.required)?"?":""}: { ${s.join("; ")} }`}).join(`
2
+ var X=Object.defineProperty;var K=(e)=>e;function Y(e,t){this[e]=K.bind(null,t)}var ee=(e,t)=>{for(var n in t)X(e,n,{get:t[n],enumerable:!0,configurable:!0,set:Y.bind(t,n)})};var P=(e,t,n)=>()=>{if(e)try{t=e(e=0)}catch(r){n=[r]}if(n)throw n[0];return t};function ne(e){return typeof e==="string"?JSON.stringify(e):String(e)}function O(e){if(!e)return"unknown";if(e.enum?.length)return e.enum.map(ne).join(" | ");if(e.type==="string")return"string";if(e.type==="number"||e.type==="integer")return"number";if(e.type==="boolean")return"boolean";if(e.type==="null")return"null";if(e.type==="array")return`Array<${O(e.items)}>`;if(e.type==="object"||e.properties||e.additionalProperties){let t=new Set(e.required||[]),n=Object.entries(e.properties||{}).map(([r,o])=>`${JSON.stringify(r)}${t.has(r)?"":"?"}: ${O(o)}`);if(e.additionalProperties){let r=e.additionalProperties===!0?"unknown":O(e.additionalProperties);n.push(`[key: string]: ${r}`)}return n.length?`{ ${n.join("; ")} }`:"Record<string, unknown>"}return"unknown"}function re(e=[]){return` parameters: {
3
+ ${["query","header","path","cookie"].map((n)=>{let r=e.filter((s)=>s.in===n);if(!r.length)return` ${n}?: never`;let o=r.map((s)=>`${JSON.stringify(s.name)}${s.required?"":"?"}: ${O(s.schema)}`);return` ${n}${r.every((s)=>!s.required)?"?":""}: { ${o.join("; ")} }`}).join(`
4
4
  `)}
5
- }`}function Ee(e){if(!e||!Object.keys(e).length)return"never";return`{ ${Object.entries(e).map(([t,n])=>`${JSON.stringify(t)}: ${J(n.schema)}`).join("; ")} }`}function Ct(e){let t=e.requestBody?`
6
- requestBody${e.requestBody.required?"":"?"}: { content: ${Ee(e.requestBody.content)} }`:`
7
- requestBody?: never`,n=Object.entries(e.responses||{}).map(([r,s])=>` ${JSON.stringify(r)}: { content: ${Ee(s.content)} }`);return`{
8
- ${qt(e.parameters)}${t}
5
+ }`}function F(e){if(!e||!Object.keys(e).length)return"never";return`{ ${Object.entries(e).map(([t,n])=>`${JSON.stringify(t)}: ${O(n.schema)}`).join("; ")} }`}function se(e){let t=e.requestBody?`
6
+ requestBody${e.requestBody.required?"":"?"}: { content: ${F(e.requestBody.content)} }`:`
7
+ requestBody?: never`,n=Object.entries(e.responses||{}).map(([r,o])=>` ${JSON.stringify(r)}: { content: ${F(o.content)} }`);return`{
8
+ ${re(e.parameters)}${t}
9
9
  responses: {
10
10
  ${n.join(`
11
11
  `)}
12
12
  }
13
- }`}function Nt(e){let t=Object.entries(e.paths||{}).map(([r,s])=>{let o=vt.map((i)=>{let a=s[i];return a?` ${i}: ${Ct(a)}`:` ${i}?: never`});return` ${JSON.stringify(r)}: {
14
- ${o.join(`
13
+ }`}function M(e){let t=Object.entries(e.paths||{}).map(([r,o])=>{let s=te.map((a)=>{let c=o[a];return c?` ${a}: ${se(c)}`:` ${a}?: never`});return` ${JSON.stringify(r)}: {
14
+ ${s.join(`
15
15
  `)}
16
- }`}),n=Object.entries(e.components?.schemas||{}).map(([r,s])=>` ${JSON.stringify(r)}: ${J(s)}`);return`/**
16
+ }`}),n=Object.entries(e.components?.schemas||{}).map(([r,o])=>` ${JSON.stringify(r)}: ${O(o)}`);return`/**
17
17
  * Generated from storage/framework/api/openapi.json by @stacksjs/api.
18
18
  * Do not edit this file directly; run bun run docs:artifacts to regenerate it.
19
19
  */
@@ -29,13 +29,13 @@ ${n.join(`
29
29
  `)}
30
30
  }
31
31
  }
32
- `}var vt;var pe=K(()=>{vt=["get","put","post","delete","options","head","patch","trace"]});var Ue={};de(Ue,{methodName:()=>Fe,renderApiClient:()=>Ft});function Fe(e){let t=e.replace(/[{}]/g,"").split(/[^a-z0-9]+/i).filter(Boolean),n=t[0]?.toLowerCase()==="api"?t.slice(1):t[1]?.toLowerCase()==="api"?[t[0],...t.slice(2)]:t,[r,...s]=n;if(!r)return"call";let o=r.charAt(0).toLowerCase()+r.slice(1),i=s.map((d)=>d.charAt(0).toUpperCase()+d.slice(1)),a=[o,...i].join("");return/^[a-z_$]/i.test(a)?a:`call${a.charAt(0).toUpperCase()}${a.slice(1)}`}function Bt(e){let t=e.responses??{},n=Object.keys(t).find((o)=>o.startsWith("2"));if(!n)return"unknown";let r=t[n]?.content,s=r?.["application/json"]??Object.values(r??{})[0];return s?.schema?J(s.schema):"unknown"}function Et(e,t=" "){let n=e.filter(Boolean);if(!n.length)return"";return`${t}/**
32
+ `}var te;var v=P(()=>{te=["get","put","post","delete","options","head","patch","trace"]});function ie(e){let t=e.replace(/[{}]/g,"").split(/[^a-z0-9]+/i).filter(Boolean),n=t[0]?.toLowerCase()==="api"?t.slice(1):t[1]?.toLowerCase()==="api"?[t[0],...t.slice(2)]:t,[r,...o]=n;if(!r)return"call";let s=r.charAt(0).toLowerCase()+r.slice(1),a=o.map((p)=>p.charAt(0).toUpperCase()+p.slice(1)),c=[s,...a].join("");return/^[a-z_$]/i.test(c)?c:`call${c.charAt(0).toUpperCase()}${c.slice(1)}`}function ae(e){let t=e.responses??{},n=Object.keys(t).find((s)=>s.startsWith("2"));if(!n)return"unknown";let r=t[n]?.content,o=r?.["application/json"]??Object.values(r??{})[0];return o?.schema?O(o.schema):"unknown"}function ce(e,t=" "){let n=e.filter(Boolean);if(!n.length)return"";return`${t}/**
33
33
  ${n.map((r)=>`${t} * ${r}`).join(`
34
34
  `)}
35
35
  ${t} */
36
- `}function Mt(e,t,n,r){let s=n.parameters??[],o=s.filter((R)=>R.in==="path"),i=s.filter((R)=>R.in==="query"),a=n.requestBody?.content?.["application/json"]?.schema,d=Boolean(n.requestBody?.required),l=[];for(let R of[...o,...i]){let q=R.in==="path"||R.required;l.push(`${JSON.stringify(R.name)}${q?"":"?"}: ${J(R.schema)}`)}if(a)l.push(`body${d?"":"?"}: ${J(a)}`);let c=[...o,...i].every((R)=>R.in!=="path"&&!R.required)&&(!a||!d),p=l.length?`input${c?"?":""}: { ${l.join("; ")} }, `:"",w=i.length?`[${i.map((R)=>JSON.stringify(R.name)).join(", ")}]`:"[]";return`${Et([n.summary&&n.summary!==e?n.summary:`${t.toUpperCase()} ${e}`,n.description??""])} ${r}(${p}options?: RequestOptions): Promise<ApiResult<${Bt(n)}>> {
37
- return request(config, ${JSON.stringify(t.toUpperCase())}, ${JSON.stringify(e)}, ${l.length?"input ?? {}":"{}"}, ${w}, ${a?"true":"false"}, options)
38
- },`}function Ft(e,t={}){let n=t.name??"API",r=new Map,s=[];for(let[o,i]of Object.entries(e.paths??{}))for(let a of It){let d=i[a];if(!d)continue;let l=Fe(d.operationId??`${a}_${o}`),c=r.get(l)??0;r.set(l,c+1),s.push(Mt(o,a,d,c===0?l:`${l}${c+1}`))}return`/* eslint-disable */
36
+ `}function ue(e,t,n,r){let o=n.parameters??[],s=o.filter((d)=>d.in==="path"),a=o.filter((d)=>d.in==="query"),c=n.requestBody?.content?.["application/json"]?.schema,p=Boolean(n.requestBody?.required),l=[];for(let d of[...s,...a]){let b=d.in==="path"||d.required;l.push(`${JSON.stringify(d.name)}${b?"":"?"}: ${O(d.schema)}`)}if(c)l.push(`body${p?"":"?"}: ${O(c)}`);let i=[...s,...a].every((d)=>d.in!=="path"&&!d.required)&&(!c||!p),u=l.length?`input${i?"?":""}: { ${l.join("; ")} }, `:"",f=a.length?`[${a.map((d)=>JSON.stringify(d.name)).join(", ")}]`:"[]";return`${ce([n.summary&&n.summary!==e?n.summary:`${t.toUpperCase()} ${e}`,n.description??""])} ${r}(${u}options?: RequestOptions): Promise<ApiResult<${ae(n)}>> {
37
+ return request(config, ${JSON.stringify(t.toUpperCase())}, ${JSON.stringify(e)}, ${l.length?"input ?? {}":"{}"}, ${f}, ${c?"true":"false"}, options)
38
+ },`}function H(e,t={}){let n=t.name??"API",r=new Map,o=[];for(let[s,a]of Object.entries(e.paths??{}))for(let c of oe){let p=a[c];if(!p)continue;let l=ie(p.operationId??`${c}_${s}`),i=r.get(l)??0;r.set(l,i+1),o.push(ue(s,c,p,i===0?l:`${l}${i+1}`))}return`/* eslint-disable */
39
39
  /**
40
40
  * ${n} client, generated from the OpenAPI document.
41
41
  *
@@ -129,11 +129,11 @@ export function createClient(config: ClientConfig) {
129
129
  /** The configuration in use, so a caller can rebuild a variant of it. */
130
130
  config,
131
131
 
132
- ${s.join(`
132
+ ${o.join(`
133
133
 
134
134
  `)}
135
135
  }
136
136
  }
137
137
 
138
138
  export type Client = ReturnType<typeof createClient>
139
- `}var It;var ye=K(()=>{pe();It=["get","put","post","delete","options","head","patch"]});function Ut(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 be(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(Ut(e))return{status:409,body:{error:`${t} already exists`}};return{status:500,body:{error:`Failed to ${n} ${t}`,detail:String(e)}}}function x(e){return e.replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}function Re(e){let t={};for(let[n,r]of Object.entries(e))t[x(n)]=r;return t}function Le(e,t){let n=String(t||"").replace(/^\/+|\/+$/g,""),r=String(e).replace(/^\/+/,"");return`/api/${n?`${n}/`:""}${r}`}function Qe(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 We(e){if(!e)return null;let t=e.attributes??{};if(Object.prototype.hasOwnProperty.call(t,"userId")||Object.prototype.hasOwnProperty.call(t,"user_id"))return"user_id";return e.belongsTo?.some((n)=>n==="User")?"user_id":null}function ze(e){return e?.ownership===!1}function Ve(e,t,n){let r=Object.keys(e).find((o)=>x(o)===x(t));if(Array.isArray(n)){if(r===void 0)return{data:e,error:"Ownership value is required"};if(!n.some((o)=>String(o)===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 o of Object.keys(s))if(x(o)===x(t))delete s[o];return s[t]=n,{data:s}}function Ge(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=x(n.trim()).split("_").filter(Boolean);if(r.length===0)continue;let s=`${r[0]}${r.slice(1).map((o)=>`${o[0]?.toUpperCase()}${o.slice(1)}`).join("")}Id`;t.push(s)}return[...new Set(t)]}function ke(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=x(r);if(s!==r&&s in e)n[r]=e[s]}return n}function Jt(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]),o=Number(n[3]),i=new Date(Date.UTC(r,s-1,o));if(i.getUTCFullYear()!==r||i.getUTCMonth()!==s-1||i.getUTCDate()!==o)return t;return i}function Oe(e,t){if(!t.length)return e;let n={...e};for(let r of t)delete n[r],delete n[x(r)];return n}function ne(e,t){if(!e||t.length===0)return e;let n={...e};for(let r of t)delete n[r],delete n[x(r)];return n}function Xe(e,t){let n=new Map;for(let r of[...Object.keys(e??{}),...Ht]){let s=x(r);if(!/^\w+$/.test(s))continue;n.set(r,s),n.set(s,s)}for(let r of t)n.delete(r),n.delete(x(r));return n}function Ke(e,t,n){if(!t)return e;let r=String(t).split(",").map((o)=>o.trim()).filter(Boolean),s=e;for(let o of r){let i=o.startsWith("-"),a=i?o.slice(1):o;if(!/^\w+$/.test(a))continue;let d=n.get(a);if(!d)continue;s=s.orderBy(d,i?"desc":"asc")}return s}function Qt(e){try{return JSON.parse(e)}catch{return e}}function Wt(e){try{return JSON.parse(e)}catch{return[]}}function Se(e,t,n){if(!e||typeof e!=="object"||!t||Object.keys(t).length===0)return e;let r={...e};for(let[s,o]of Object.entries(t)){let i=typeof o==="string"?Lt[o]:o;if(!i||typeof i[n]!=="function")continue;if(Object.prototype.hasOwnProperty.call(r,s))r[s]=i[n](r[s]);let a=x(s);if(a!==s&&Object.prototype.hasOwnProperty.call(r,a))r[a]=i[n](r[a])}return r}function $e(e,t,n){let r=t?.attributes??{},s={};for(let[o,i]of Object.entries(r)){let a=i?.validation?.rule;if(!a||typeof a.validate!=="function")continue;let d=Object.prototype.hasOwnProperty.call(e,o);if(!d&&n==="updating")continue;let l=i!==null&&typeof i==="object"&&Object.prototype.hasOwnProperty.call(i,"default"),c=d?e[o]:l?i.default:void 0,p=Jt(a,c),w=a.validate(p);if(!w?.valid&&Array.isArray(w?.errors)&&w.errors.length>0)s[o]=w.errors.map((j)=>i?.validation?.message?.[j?.code]??j?.message??"invalid")}return Object.keys(s).length===0?{valid:!0}:{valid:!1,errors:s}}function Ze(e,t,n){let r=Je(n);return e.find((s)=>s.method===t&&Je(String(s.path??""))===r)}function Je(e){return e.replace(/\{[^}]*\}/g,"{}").replace(/:[^/]+/g,"{}")}function we(e){if(Array.isArray(e))return e.filter((t)=>typeof t==="string"&&t.length>0);return typeof e==="string"&&e?[e]:[]}function Ye(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?we(s.read):["auth"],write:"write"in s?we(s.write):["auth"],declared:!0}}let r=we(n);return{read:r,write:r,declared:!0}}function et(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(He),10),s=Math.min(Number.isFinite(r)?Math.max(1,r):He,zt);return{page:n,perPage:s,offset:(n-1)*s}}function fe(e,t){let n=new URL(e.toString());return n.searchParams.set("page",String(t)),`${n.pathname}${n.search}`}function ge(e,t,n,r,s,o){let i=(t-1)*n,a=r===0,d={page:t,per_page:n,from:a?null:i+1,to:a?null:i+r,has_more_pages:s,prev_page_url:t>1?fe(e,t-1):null,next_page_url:s?fe(e,t+1):null};if(o!==void 0&&!Number.isNaN(o)){let l=Math.max(1,Math.ceil(o/n));d.total=o,d.last_page=l,d.first_page_url=fe(e,1),d.last_page_url=fe(e,l)}return d}function Ae(e,t,n,r,s,o){let{page:i,...a}=ge(e,t,n,r,s,o);return{current_page:i,...a}}function Te(e,t){return(t??e??"").toString().trim().toLowerCase()==="warn"?"warn":"deny"}function tt(e,t){if(e.length===0)return null;let n=[...e].sort().join(", ");if(t==="deny")return`[orm] security.api.rowScoping is 'deny': NOT registering store/update/destroy for ${e.length} model(s) `+`with no row-level scoping \u2014 ${n}. Give a model an \`ownership\` config or a \`team_id\` column to restore its writes.`;return`[orm] ${e.length} model(s) publish mutating routes with no row-level scoping, so an authenticated caller can write any row \u2014 `+`${n}. Scope one with an \`ownership\` config or a \`team_id\` column; intended for public catalog tables. Set \`security.api.rowScoping: 'deny'\` (config/security.ts) to stop generating these routes instead.`}var Ht,Lt,He=15,zt=100;var _e=K(()=>{Ht=["id","uuid","created_at","updated_at","deleted_at"];Lt={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"?Qt(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"?Wt(e):[],set:(e)=>e==null?null:Array.isArray(e)?JSON.stringify(e):e}}});var ot={};de(ot,{loadModelRegistry:()=>xe,modelFiles:()=>st});import{readdirSync as Vt}from"fs";import{basename as Gt,extname as rt,join as Xt}from"path";function st(e){let t=[],n=(r)=>{let s;try{s=Vt(r,{withFileTypes:!0})}catch{return}for(let o of s){let i=Xt(r,o.name);if(o.isDirectory()){n(i);continue}if(![".ts",".js"].includes(rt(o.name)))continue;if(o.name.startsWith(".")||o.name.startsWith("index"))continue;t.push(i)}};return n(e),t.sort()}async function nt(e,t,n){for(let r of st(e))try{let s=rt(r),o=await import(`${r}?t=${Date.now()}`),i=o.default??o,a=i.name??Gt(r,s);t[a]={...i,name:a}}catch(s){n?.(r,s)}}async function xe(e){let t={};return await nt(e.defaultsRoot,t,e.onImportError),await nt(e.userRoot,t,e.onImportError),t}var Pe=()=>{};function je(e){if(e?.ownership===!1)return null;if(e?.ownership)return e.ownership;let t=Qe(e);if(t)return{field:t,resolve:async(r,s)=>{let{resolveAuthenticatedTeamId:o}=await import("@stacksjs/auth");return o(Kt(s))}};let n=We(e);if(n)return{field:n,resolve:async(r)=>r?.id??null};return null}function Kt(e){let t=e?.headers?.get?.("authorization"),n=t&&/^Bearer\s+/i.test(t)?t.replace(/^Bearer\s+/i,"").trim():null,r=e?.headers?.get?.("cookie")||"";return{bearerToken:()=>n,cookies:{get:(s)=>{for(let o of r.split(";")){let i=o.indexOf("=");if(i===-1)continue;if(o.slice(0,i).trim()===s)return decodeURIComponent(o.slice(i+1).trim())}return null}}}}var it=K(()=>{_e()});import Zt from"process";import{route as z}from"@stacksjs/router";import{env as Z}from"@stacksjs/env";import{projectPath as qe,storagePath as Yt}from"@stacksjs/path";import{createQueryBuilder as en,defaultConfig as at,setConfig as ct}from"@stacksjs/query-builder";import{HttpError as G}from"@stacksjs/error-handling";import{log as ee}from"@stacksjs/logging";function Y(e,t){let n=Ze(z.routes,e,t);if(!n)return!1;let r=String(n.path??"");return ee.info(`[orm] Skipping generated ${e} ${t} - already defined${r&&r!==t?` as ${r}`:""}.`),!0}function gt(e){if(!e.attributes)return[];return Object.entries(e.attributes).filter(([t,n])=>n.hidden===!0).map(([t])=>t)}function ut(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 lt(e,t,n,r){if(!e.length)return e;let s=n.split(",").map((l)=>l.trim()).filter(Boolean);if(!s.length)return e;let o=Array.isArray(t.belongsTo)?t.belongsTo:[],i=Array.isArray(t.hasMany)?t.hasMany:[],a=Array.isArray(t.hasOne)?t.hasOne:[],d=new Map;for(let l of o)d.set(x(l),{kind:"belongsTo",modelName:l});for(let l of a)d.set(x(l),{kind:"hasOne",modelName:l});for(let l of i)d.set(ut(x(l)),{kind:"hasMany",modelName:l});for(let l of s){let c=d.get(l);if(!c)continue;let p=r[c.modelName];if(!p)continue;let w=p.table||ut(x(c.modelName)),j=gt(p),R=(q)=>ne(ce(q,p),j);if(c.kind==="belongsTo"||c.kind==="hasOne"){let q=`${x(c.modelName)}_id`,T=[...new Set(e.map((P)=>P[q]).filter((P)=>P!=null))];if(!T.length){for(let P of e)P[l]=null;continue}let F=await B.selectFrom(w).whereIn("id",T).get(),E=new Map;for(let P of F??[])E.set(String(P.id),R(P));for(let P of e)P[l]=E.get(String(P[q]))??null}else{let q=String(t.name??""),T=`${x(q)}_id`,F=[...new Set(e.map((D)=>D.id).filter((D)=>D!=null))];if(!F.length){for(let D of e)D[l]=[];continue}let E=await B.selectFrom(w).whereIn(T,F).get(),P=new Map;for(let D of E??[]){let k=String(D[T]),I=P.get(k)??[];I.push(R(D)),P.set(k,I)}for(let D of e)D[l]=P.get(String(D.id))??[]}}return e}async function dt(e,t){let n=t?.set;if(!n||typeof n!=="object")return e;let r={...e};for(let[s,o]of Object.entries(n)){if(typeof o!=="function"||!(s in r))continue;try{r[s]=await o(r)}catch{}}return r}function pt(e,t){return Se(e,t?.casts,"set")}function ce(e,t){return Se(e,t?.casts,"get")}function m(e,t=200){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}async function De(e){if(Number(e.headers?.get?.("content-length")??0)>me)throw new G(413,`Request body exceeds ${me}-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>me)throw new G(413,`Request body exceeds ${me}-byte limit`);if(!n)return{};let r=JSON.parse(n);return r&&typeof r==="object"&&!Array.isArray(r)?r:{}}catch(n){if(n instanceof G)throw n;throw new G(400,`Invalid JSON body: ${n.message}`)}}function he(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 rn(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 re(e){let t=e._authenticatedUser;if(t)return t;let n=rn(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 ae(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)}async function se(e,t,n){let r=je(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,o=null;try{o=await r.resolve(t,n)}catch{o=null}return{enforced:!0,value:o,field:String(r.field),bypass:s}}async function ft(e,t,n,r){let s=e?.authedFill?.[t];if(!s)return{};if(typeof s==="function")try{let o=await s(n,r);return o&&typeof o==="object"?o:{}}catch{return{}}if(typeof s==="object"){let o={};for(let[i,a]of Object.entries(s))try{o[i]=typeof a==="function"?await a(n,r):a}catch{}return o}return{}}var tn,ve,nn,B,me=1048576,mt,ht,yt;var wt=K(async()=>{_e();Pe();it();tn=qe("config/qb.ts");try{let e=(await import(tn)).default;ct(e??at)}catch{ee.debug("[orm] No config/qb.ts override found - deriving config from DB_CONNECTION");let e=Z.DB_CONNECTION||"sqlite";ct({...at,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||""}})}ve=await xe({defaultsRoot:Yt("framework/defaults/app/Models"),userRoot:qe("app/Models"),onImportError:(e,t)=>ee.warn(`[orm] Could not load model ${e}: ${t.message}`)}),nn=en(),B=nn;mt=await(async()=>{let e=Zt.env.STACKS_API_ROW_SCOPING;try{let t=(await import(qe("config/security.ts"))).default;return Te(t?.api?.rowScoping,e)}catch{return Te(void 0,e)}})(),ht=[];for(let[e,t]of Object.entries(ve)){let n=t.traits?.useApi;if(!n)continue;let r=typeof n==="object"?n:{},s=r.uri||t.table||e.toLowerCase()+"s",o=r.routes||["index","show","store","update","destroy"],i=t.table||s,a=Ge(t),d=gt(t),l=Le(s,r.prefix),c=Xe(t.attributes,d),{read:p,write:w,declared:j}=Ye(n),R=["store","update","destroy"].some((g)=>o.includes(g));if(R&&j&&w.length===0)ee.warn(`[orm] ${e}: registering UNAUTHENTICATED mutating routes at ${l} (explicit \`middleware: []\` opt-out)`);if(["index","show"].some((g)=>o.includes(g))&&j&&p.length===0)ee.debug(`[orm] ${e}: registering public read routes at ${l} (declared \`middleware.read: []\`)`);let T=!!je(t),F=T&&!p.includes("auth")?["auth",...p]:p,E=ze(t),P=R&&!T&&!E;if(P)ht.push(e);if(R&&E)ee.debug(`[orm] ${e}: registering unscoped mutating routes at ${l} (declared \`ownership: false\`)`);let D=P&&mt==="deny",k=(g,u=F)=>{let f=g;for(let h of u)if(f&&typeof f.middleware==="function")f=f.middleware(h);return f};if(o.includes("index")&&!Y("GET",l))k(z.get(l,async(g)=>{try{let u=new URL(g.url),{page:f,perPage:h,offset:S}=et(u.searchParams),O=u.searchParams.get("sort"),y=B.selectFrom(i);y=Ke(y,O,c);let U=new Set(["page","per_page","sort","fields","search","include","limit","offset","with_count","withTrashed","onlyTrashed"]);for(let[C,N]of u.searchParams.entries()){if(U.has(C)||!N)continue;if(!/^[a-z_][a-z0-9_]*$/i.test(C))continue;let X=c.get(C);if(X)y=y.where(X,"=",N)}let _=u.searchParams.get("search");if(_&&a.length>0){let C=a.slice(0,5);y=y.where((N)=>{for(let X of C)N=N.orWhere(x(X),"like",`%${_}%`);return N})}let v=u.searchParams.get("fields");if(v){let C=v.split(",").map((N)=>N.trim()).filter((N)=>/^[a-z_][a-z0-9_]*$/i.test(N)).map((N)=>x(N));if(C.length>0)y=y.select(C)}let M=!!t.traits?.useSoftDeletes,A=u.searchParams.get("withTrashed")==="true",L=u.searchParams.get("onlyTrashed")==="true";if(M&&!A)y=L?y.whereNotNull("deleted_at"):y.whereNull("deleted_at");let b=T?await se(t,await re(g),g):{enforced:!1,value:null,field:"",bypass:!1};if(b.enforced&&!b.bypass){if(b.value==null||Array.isArray(b.value)&&b.value.length===0){let C=Ae(u,f,h,0,!1,void 0);return new Response(JSON.stringify({data:[],...C,meta:ge(u,f,h,0,!1,void 0)}),{status:200,headers:{"Content-Type":"application/json","Cache-Control":"private, no-store",Vary:"Authorization"}})}y=Array.isArray(b.value)?y.where(b.field,"in",b.value):y.where(b.field,"=",b.value)}let Q=await y.limit(h+1).offset(S).get()||[],W=Q.length>h,ie=(W?Q.slice(0,h):Q).map((C)=>ne(ce(C,t),d)),Ne=u.searchParams.get("include");if(Ne)ie=await lt(ie,t,Ne,ve);let Tt=u.searchParams.get("with_count")==="true",te;if(Tt)try{let C=B.selectFrom(i);if(b.enforced&&!b.bypass&&b.value!=null)C=Array.isArray(b.value)?C.where(b.field,"in",b.value):C.where(b.field,"=",b.value);let N=await C.count(),X=typeof N==="number"?N:Number(N?.count??N);if(Number.isFinite(X))te=X}catch{}let le={"Content-Type":"application/json"};if(te!==void 0&&!Number.isNaN(te))le["X-Total-Count"]=String(te);le["Cache-Control"]=b.enforced&&!b.bypass?"private, no-store":"public, max-age=15, must-revalidate",le.Vary="Authorization";let _t=Ae(u,f,h,ie.length,W,te);return new Response(JSON.stringify({data:ie,..._t,meta:ge(u,f,h,ie.length,W,te)}),{status:200,headers:le})}catch(u){if(u instanceof G){let f={error:u.message};if(u.details!==void 0)f.details=u.details;return m(f,u.status||400)}return m({error:`Failed to fetch ${s}`,detail:String(u)},500)}}));if(o.includes("show")&&!Y("GET",`${l}/{id}`))k(z.get(`${l}/{id}`,async(g)=>{try{let u=he(g.params?.id);if(u==null)return m({error:"Invalid ID parameter"},400);let f=await B.selectFrom(i).where({id:u}).executeTakeFirst();if(!f)return m({error:`${e} not found`},404);let h=new URL(g.url);if(t.traits?.useSoftDeletes&&f.deleted_at&&h.searchParams.get("withTrashed")!=="true")return m({error:`${e} not found`},404);let S=T?await se(t,await re(g),g):{enforced:!1,value:null,field:"",bypass:!1};if(S.enforced&&!S.bypass){if(S.value==null||!ae(f[S.field],S.value))return m({error:`${e} not found`},404)}let O=ne(ce(f,t),d),y=h.searchParams.get("include");if(y){let[A]=await lt([O],t,y,ve);O=A}let U=O?.updated_at||O?.created_at,_=U?`W/"${O.id}-${String(U)}"`:void 0,v=g.headers?.get?.("if-none-match");if(_&&v&&v===_)return new Response(null,{status:304,headers:{ETag:_}});let M={"Content-Type":"application/json"};if(_)M.ETag=_;return M["Cache-Control"]=S.enforced&&!S.bypass?"private, no-store":"public, max-age=30, must-revalidate",M.Vary="Authorization",new Response(JSON.stringify({data:O}),{status:200,headers:M})}catch(u){if(u instanceof G){let f={error:u.message};if(u.details!==void 0)f.details=u.details;return m(f,u.status||400)}return m({error:`Failed to fetch ${e}`,detail:String(u)},500)}}));if(!D&&o.includes("store")&&!Y("POST",l))k(z.post(l,async(g)=>{try{let u=await De(g),f=Oe(u,d),h=ke(f,a),S=await re(g);if(S){let A=await ft(t,"creating",S,g);for(let[L,b]of Object.entries(A))if(b!==void 0&&b!==null&&h[L]===void 0)h[L]=b}let O=await se(t,S,g);if(O.enforced&&!O.bypass){if(!S)return m({error:"Auth required"},401);let A=Ve(h,O.field,O.value);if(A.error)return m({error:A.error},403);h=A.data}if(Object.keys(h).length===0)return m({error:"No fillable fields provided"},422);let y=$e(h,t,"creating");if(!y.valid)return m({success:!1,message:"Validation failed",errors:y.errors},422);if(t.traits?.useTimestamps!==!1){let A=new Date().toISOString();h.created_at=A,h.updated_at=A}let U=await dt(h,t),_=Re(pt(U,t)),v=await B.insertInto(i).values(_).execute(),M=_;try{let A=v?.lastInsertRowid??v?.insertId??v;if(A){let L=await B.selectFrom(i).where({id:A}).executeTakeFirst();if(L)M=L}}catch{}return m({data:ne(ce(M,t),d)},201)}catch(u){let{status:f,body:h}=be(u,e,"create");return m(h,f)}}),w);if(!D&&o.includes("update")){let g=async(u)=>{try{let f=he(u.params?.id);if(f==null)return m({error:"Invalid ID parameter"},400);let h=await De(u),S=Oe(h,d),O=ke(S,a),y=await re(u);if(y){let b=await ft(t,"updating",y,u);for(let[Q,W]of Object.entries(b))if(W!==void 0&&W!==null&&O[Q]===void 0)O[Q]=W}if(Object.keys(O).length===0)return m({error:"No fillable fields provided"},422);let U=$e(O,t,"updating");if(!U.valid)return m({success:!1,message:"Validation failed",errors:U.errors},422);let _=await B.selectFrom(i).where({id:f}).executeTakeFirst();if(!_)return m({error:`${e} not found`},404);let v=await se(t,y,u);if(v.enforced&&!v.bypass){if(!y)return m({error:"Auth required"},401);let b=_[v.field];if(!ae(b,v.value))return m({error:`Not your ${e}`},403);let Q=Object.keys(O).find((W)=>x(W)===x(v.field));if(Q!==void 0&&!ae(O[Q],v.value))return m({error:`Cannot reassign ${e} ownership`},403)}if(t.traits?.useTimestamps!==!1)O.updated_at=new Date().toISOString();let M=await dt(O,t),A=Re(pt(M,t));await B.updateTable(i).set(A).where({id:f}).execute();let L={..._,...A};try{let b=await B.selectFrom(i).where({id:f}).executeTakeFirst();if(b)L=b}catch{}return m({data:ne(ce(L,t),d)})}catch(f){let{status:h,body:S}=be(f,e,"update");return m(S,h)}};if(!Y("PUT",`${l}/{id}`))k(z.put(`${l}/{id}`,g),w);if(!Y("PATCH",`${l}/{id}`))k(z.patch(`${l}/{id}`,g),w)}let I=!!t.traits?.useSoftDeletes;if(!D&&o.includes("destroy")&&!Y("DELETE",`${l}/{id}`))k(z.delete(`${l}/{id}`,async(g)=>{try{let u=he(g.params?.id);if(u==null)return m({error:"Invalid ID parameter"},400);let f=await B.selectFrom(i).where({id:u}).executeTakeFirst();if(!f)return m({error:`${e} not found`},404);let h=await re(g),S=await se(t,h,g);if(S.enforced&&!S.bypass){if(!h)return m({error:"Auth required"},401);let O=f[S.field];if(!ae(O,S.value))return m({error:`Not your ${e}`},403)}if(I){let O=new Date().toISOString();await B.updateTable(i).set({deleted_at:O,updated_at:O}).where({id:u}).execute()}else await B.deleteFrom(i).where({id:u}).execute();return new Response(null,{status:204})}catch(u){if(u instanceof G){let f={error:u.message};if(u.details!==void 0)f.details=u.details;return m(f,u.status||400)}return m({error:`Failed to delete ${e}`,detail:String(u)},500)}}),w);if(!D&&o.includes("destroy")&&!Y("POST",`${l}/bulk-delete`))k(z.post(`${l}/bulk-delete`,async(g)=>{try{let f=(await De(g))?.ids;if(!Array.isArray(f)||f.length===0)return m({error:"An array of IDs is required"},422);if(f.length>100)return m({error:"Cannot delete more than 100 records at once"},422);let h=[],S=[];for(let _ of f){let v=he(_);if(v!=null)h.push(v);else S.push(_)}if(S.length>0)return m({error:"Invalid IDs in batch",invalid:S},422);let O=await re(g),y=await se(t,O,g);if(y.enforced&&!y.bypass){if(!O)return m({error:"Auth required"},401);if(y.value==null)return m({error:"Caller has no ownership identity"},403);let _=await B.selectFrom(i).select(["id",y.field]).execute(),v=new Set(_.filter((A)=>ae(A[y.field],y.value)).map((A)=>String(A.id))),M=h.filter((A)=>!v.has(String(A)));if(M.length>0)return m({error:`Cannot delete ${e} you don't own`,ids:M},403)}let U=new Date().toISOString();for(let _ of h)if(I)await B.updateTable(i).set({deleted_at:U,updated_at:U}).where({id:_}).execute();else await B.deleteFrom(i).where({id:_}).execute();return m({message:`Successfully deleted ${h.length} ${s}`})}catch(u){if(u instanceof G){let f={error:u.message};if(u.details!==void 0)f.details=u.details;return m(f,u.status||400)}return m({error:`Failed to bulk delete ${s}`,detail:String(u)},500)}}),w)}{let e=tt(ht,mt);if(e)ee.warn(e)}yt=z});var bt={};de(bt,{default:()=>yt});var Rt=K(async()=>{await wt()});class Ie{data;status;headers;isOk;constructor(e,t,n,r){this.data=e;this.status=t;this.headers=n;this.isOk=r}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 Be{defaultHeaders={Accept:"application/json","Content-Type":"application/json"};queryParams;bodyData;isFormData=!1;customHeaders={};attachments=[];isMultipart=!1;digestAuth;withQueryParams(e){return this.queryParams=e,this}withHeaders(e){return this.customHeaders={...this.customHeaders,...e},this}accept(e){return this.defaultHeaders.Accept=e,this}acceptJson(){return this.accept("application/json")}withToken(e){return this.customHeaders.Authorization=`Bearer ${e}`,this}withBasicAuth(e,t){let n=btoa(`${e}:${t}`);return this.customHeaders.Authorization=`Basic ${n}`,this}withDigestAuth(e,t){return this.digestAuth={username:e,password:t},this}withBody(e){return this.bodyData=e,this}asForm(){return this.isFormData=!0,this.defaultHeaders["Content-Type"]="application/x-www-form-urlencoded",this}attach(e,t,n,r){let s=typeof t==="string"?new Blob([t],{type:r?.["Content-Type"]||"text/plain"}):t;return this.attachments.push({name:e,content:s,filename:n,headers:r}),this.isMultipart=!0,delete this.defaultHeaders["Content-Type"],this}getHeaders(){return{...this.defaultHeaders,...this.customHeaders}}addQueryParams(e){if(!this.queryParams)return e;let t=new URLSearchParams;Object.entries(this.queryParams).forEach(([s,o])=>{if(o!=null)t.append(s,String(o))});let n=t.toString();if(!n)return e;let r=e.includes("?");return e+(r?"&":"?")+n}async formatBody(e){let t=e||this.bodyData;if(this.isMultipart){let n=new FormData;if(t)Object.entries(t).forEach(([r,s])=>{n.append(r,String(s))});for(let r of this.attachments)if(r.headers){let s=r.content instanceof Blob?new Blob([r.content],{type:r.headers["Content-Type"]}):r.content;n.append(r.name,s,r.filename)}else n.append(r.name,r.content,r.filename);return n}if(this.isFormData&&t){let n=new URLSearchParams;return Object.entries(t).forEach(([r,s])=>{if(s!=null)n.append(r,String(s))}),n.toString()}return t?JSON.stringify(t):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(e,t,n,r){if(e.status!==401||!this.digestAuth)return e;let s=e.headers.get("WWW-Authenticate");if(!s?.startsWith("Digest "))return e;let o=s.substring(7).split(",").reduce((j,R)=>{let[q,T]=R.trim().split("=");if(q)j[q]=T?.replace(/["']/g,"")??"";return j},{}),i=await this.generateMD5(`${this.digestAuth.username}:${o.realm}:${this.digestAuth.password}`),a=await this.generateMD5(`${n}:${t}`),d="00000001",l=await this.generateMD5(Date.now().toString()).then((j)=>j.substring(0,8)),c=await this.generateMD5(`${i}:${o.nonce}:${d}:${l}:${o.qop}:${a}`),p={username:`"${this.digestAuth.username}"`,realm:`"${o.realm}"`,nonce:`"${o.nonce}"`,uri:`"${t}"`,algorithm:o.algorithm?`"${o.algorithm}"`:void 0,qop:`"${o.qop}"`,nc:d,cnonce:`"${l}"`,response:`"${c}"`,opaque:o.opaque?`"${o.opaque}"`:void 0},w=Object.entries(p).filter(([j,R])=>R!==void 0).map(([j,R])=>`${j}=${R}`).join(", ");return this.customHeaders.Authorization=`Digest ${w}`,fetch(t,{method:n,headers:this.getHeaders(),body:r?await this.formatBody(r):void 0})}async generateMD5(e){let n=new TextEncoder().encode(e),r=await crypto.subtle.digest("SHA-256",n);return Array.from(new Uint8Array(r)).map((o)=>o.toString(16).padStart(2,"0")).join("")}async request(e,t,n){let r=this.addQueryParams(e),s=await this.formatBody(n),o=await fetch(r,{method:t,headers:this.getHeaders(),body:s});if(this.digestAuth)o=await this.handleDigestAuth(o,r,t,n);let i=await o.json();return this.resetState(),new Ie(i,o.status,o.headers,o.ok)}async get(e){return this.request(e,"GET")}async post(e,t){return this.request(e,"POST",t)}async put(e,t){return this.request(e,"PUT",t)}async patch(e,t){return this.request(e,"PATCH",t)}async delete(e){return this.request(e,"DELETE")}}var pn=new Be;ye();import{path as oe}from"@stacksjs/path";function Ot(e){if(!e||typeof e!=="object")return{type:"string"};let t=e,n=Array.isArray(t.rules)?t.rules:[],r=(c)=>n.find((p)=>p.name===c),s=(c,p)=>{let w=r(c)?.params?.[p];return typeof w==="number"?w:void 0},o=t.name??t._type??"string",i={type:o==="enum"?"string":o},a=s("min","min")??(typeof t._min==="number"?t._min:void 0),d=s("max","max")??(typeof t._max==="number"?t._max:void 0);if(a!==void 0)i[o==="string"?"minLength":"minimum"]=a;if(d!==void 0)i[o==="string"?"maxLength":"maximum"]=d;if(r("email")||t._email)i.format="email";if(r("url")||t._url)i.format="uri";if(r("uuid")||t._uuid)i.format="uuid";let l=Array.isArray(t.allowedValues)?t.allowedValues:Array.isArray(t._enum)?t._enum:null;if(l)i.enum=l;return i}function sn(e){if(!e||typeof e!=="object")return!1;let t=e;return Boolean(t.isRequired??t._required)}function kt(e){return e.replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}function on(e){let t={id:{type:"integer"}},n=["id"];if(e.traits?.useUuid)t.uuid={type:"string",format:"uuid"},n.push("uuid");for(let[r,s]of Object.entries(e.attributes??{})){if(s.hidden===!0)continue;let o=kt(r);if(t[o]=Ot(s.validation?.rule),s.required===!0)n.push(o)}for(let r of e.belongsTo??[]){if(typeof r!=="string"||!r.trim())continue;let s=`${kt(r.trim())}_id`;t[s]??={type:"integer"}}if(e.traits?.useTimestamps!==!1)t.created_at={type:"string",format:"date-time"},t.updated_at={type:"string",format:"date-time"};if(e.traits?.useSoftDeletes)t.deleted_at={type:"string",format:"date-time",nullable:!0};return{type:"object",properties:t,required:[...new Set(n)]}}function an(e){let t=e.traits?.useApi;if(!t||typeof t!=="object"||!t.uri)return null;let n=String(t.prefix||"").replace(/^\/+|\/+$/g,""),r=String(t.uri).replace(/^\/+|\/+$/g,"");return`/api/${n?`${n}/`:""}${r}`}function cn(e,t){let n={...t},r=e?.responses;if(r&&typeof r==="object")for(let[o,i]of Object.entries(r)){let a=i;if(!a||typeof a!=="object"||typeof a.description!=="string")continue;n[String(o)]={description:a.description,...a.schema&&typeof a.schema==="object"?{content:{"application/json":{schema:a.schema}}}:{}}}let s=e?.responseHeaders;if(s&&typeof s==="object"){let o={};for(let[i,a]of Object.entries(s)){let d=a;if(!d||typeof d!=="object"||typeof d.description!=="string")continue;o[i]={description:d.description,...d.schema&&typeof d.schema==="object"?{schema:d.schema}:{}}}if(Object.keys(o).length>0)for(let i of Object.keys(n))n[i]={...n[i],headers:o}}return n}async function un(e){if(typeof e!=="string"||!e||e.includes(".."))return null;try{let{path:t}=await import("@stacksjs/path"),n=[t.appPath(`${e}.ts`),t.storagePath(`framework/defaults/app/${e}.ts`)];for(let r of n)try{if(!await Bun.file(r).exists())continue;let i=(await import(r)).default;return i&&typeof i==="object"?i:null}catch{}}catch{}return null}async function qn(e={}){let t=e.portable??!0,{listRegisteredRoutes:n}=await import("@stacksjs/router");try{let{loadRoutes:c}=await import("@stacksjs/router"),{default:p}=await import(oe.appPath("Routes.ts"));await c(p)}catch(c){let p=c instanceof Error?c.message:String(c);if(t)throw Error(`[generateOpenApi] Refusing to emit a partial spec: failed to load routes/api.ts + framework routes: ${p}`);console.warn(`[generateOpenApi] Failed to load routes/api.ts + framework routes: ${p}`)}try{try{await import("@stacksjs/orm/routes")}catch{await Rt().then(() => bt)}}catch(c){let p=c instanceof Error?c.message:String(c);if(t)throw Error(`[generateOpenApi] Refusing to emit a partial spec: failed to load useApi-generated ORM routes: ${p}`);console.warn(`[generateOpenApi] Failed to load useApi-generated ORM routes: ${p}`)}let r={};try{let p;try{p=await import("@stacksjs/orm/model-registry")}catch{p=await Promise.resolve().then(() => (Pe(),ot))}r=await p.loadModelRegistry({defaultsRoot:oe.storagePath("framework/defaults/app/Models"),userRoot:oe.projectPath("app/Models")})}catch(c){let p=c instanceof Error?c.message:String(c);if(t)throw Error(`[generateOpenApi] Refusing to emit model-free schemas: ${p}`);console.warn(`[generateOpenApi] Failed to load model schemas: ${p}`)}let s=(c)=>c.replace(/(^|\/):(\w+)(?=$|\/)/g,"$1{$2}"),o=[...n()].map((c)=>({route:c,oasPath:s(c.path),method:c.method.toLowerCase()})).sort((c,p)=>{if(c.oasPath!==p.oasPath)return c.oasPath<p.oasPath?-1:1;return c.method<p.method?-1:c.method>p.method?1:0});if(t&&o.length===0)throw Error("[generateOpenApi] Refusing to emit an empty spec: no routes were registered. This usually means route loading failed silently rather than that the app has no API.");let i="Stacks API";if(!t)try{let{config:c}=await import("@stacksjs/config");if(c.app?.name)i=`${c.app.name} API`}catch{}let a={openapi:"3.0.0",info:{title:i,version:"1.0.0"},paths:{},components:{schemas:{}}},d=Object.values(r).map((c)=>({name:String(c.name),path:an(c),schema:on(c)})).filter((c)=>c.path!==null).sort((c,p)=>c.name<p.name?-1:c.name>p.name?1:0);for(let c of d)a.components.schemas[c.name]=c.schema;let l=new Set;for(let{route:c,oasPath:p,method:w}of o){if(!a.paths[p])a.paths[p]={};let j=[];for(let k of c.path.matchAll(/\{(\w+)\}/g))if(k[1])j.push(k[1]);for(let k of c.path.matchAll(/(?:^|\/):(\w+)(?=$|\/)/g))if(k[1])j.push(k[1]);let R=c.name??`${w}_${p.replace(/[^a-z0-9]/gi,"_")}`,q=R;if(l.has(q)){q=`${R}_${w}`;let k=2;while(l.has(q))q=`${R}_${w}_${k++}`}l.add(q);let T={summary:c.name??c.path,operationId:q,parameters:j.map((k)=>({name:k,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"}}},F=d.find((k)=>p===k.path||p===`${k.path}/{id}`);if(F){let k=p===F.path&&w==="get"?{type:"array",items:F.schema}:F.schema;if(T.responses[200].content={"application/json":{schema:{type:"object",properties:{data:k},required:["data"]}}},w==="post"&&p===F.path)T.responses[201]={...T.responses[200],description:"Created"},delete T.responses[200]}let E=c.action??(c.handler?await un(c.handler):null),P=E&&typeof E.validations==="object"&&E.validations!==null?E.validations:null;T.responses=cn(E,T.responses);let D=E?.requestHeaders;if(D&&typeof D==="object")for(let[k,I]of Object.entries(D)){let g=I;if(!g||typeof g!=="object"||typeof g.description!=="string")continue;T.parameters?.push({name:k,in:"header",description:g.description,required:g.required===!0,schema:g.schema&&typeof g.schema==="object"?g.schema:{type:"string"}})}if(P&&Object.keys(P).length>0){let k=Object.entries(P).map(([I,g])=>{let u=g?.rule;return{field:I,schema:Ot(u),required:sn(u)}});if(w==="get"||w==="head"||w==="delete"){let I=new Set(j);for(let{field:g,schema:u,required:f}of k){if(I.has(g))continue;T.parameters?.push({name:g,in:"query",required:f,schema:u})}}else{let I={type:"object",properties:{},required:[]},g=I.properties,u=I.required;for(let f of k)if(g[f.field]=f.schema,f.required)u.push(f.field);if(u.length===0)delete I.required;T.requestBody={required:u.length>0,content:{"application/json":{schema:I}}}}}a.paths[p][w]=T}if(e.write!==!1){await Bun.write(oe.frameworkPath("api/openapi.json"),JSON.stringify(a,null,2));let{renderOpenApiTypes:c}=await Promise.resolve().then(() => (pe(),Me)),{renderApiClient:p}=await Promise.resolve().then(() => (ye(),Ue));await Bun.write(oe.frameworkPath("api/api-types.ts"),c(a)),await Bun.write(oe.frameworkPath("api/client.ts"),p(a,{name:a.info.title}))}return a}pe();class H{static instance=new H;isMissing(){return!0}}class ue{data;constructor(e){this.data=e}}class St{condition;value;defaultValue;constructor(e,t,n=new H){this.condition=e;this.value=t;this.defaultValue=n}resolve(){return(typeof this.condition==="function"?this.condition():this.condition)?this.value:this.defaultValue}}class $t{resource;additional={};request;static wrap="data";static additionalMeta={};constructor(e){this.resource=e}withRequest(e){return this.request=e,this}withAdditional(e){return this.additional={...this.additional,...e},this}resolve(e){let t=this.toArray(e||this.request);return this.filterAndResolve(t)}toResponse(e){let t=this.resolve(e),n=this.constructor.wrap;if(n)return{[n]:t,...this.additional};return{...t,...this.additional}}toJson(e){return JSON.stringify(this.toResponse(e))}toJSON(){return this.toResponse()}static collection(e){return new Ce(e,this)}when(e,t,n){if(typeof e==="function"?e():e)return typeof t==="function"?t():t;return n!==void 0?n:H.instance}whenNotNull(e,t){if(e===null||e===void 0)return H.instance;return t?t(e):e}whenLoaded(e,t,n){let r=this.resource;if(!((e in r)&&r[e]!==void 0))return n!==void 0?n:H.instance;if(t!==void 0)return typeof t==="function"?t():t;return r[e]}whenCounted(e,t){let n=this.resource,r=`${e}_count`;if(r in n)return Number(n[r]);return t!==void 0?t:H.instance}merge(e){return new ue(e)}mergeWhen(e,t){if(!(typeof e==="function"?e():e))return H.instance;let r=typeof t==="function"?t():t;return new ue(r)}static MAX_RESOLVE_DEPTH=20;filterAndResolve(e,t=0){if(t>=$t.MAX_RESOLVE_DEPTH)return e;let n={};for(let[r,s]of Object.entries(e)){if(s instanceof H)continue;if(s instanceof ue){Object.assign(n,this.filterAndResolve(s.data,t+1));continue}if(s instanceof St){let o=s.resolve();if(!(o instanceof H))n[r]=o;continue}if(s!==null&&typeof s==="object"&&!Array.isArray(s)&&!(s instanceof Date)){n[r]=this.filterAndResolve(s,t+1);continue}if(Array.isArray(s)){n[r]=s.filter((o)=>!(o instanceof H)).map((o)=>{if(o instanceof ue)return o.data;if(o!==null&&typeof o==="object"&&!(o instanceof Date))return this.filterAndResolve(o,t+1);return o});continue}n[r]=s}return n}static withoutWrapping(){this.wrap=null}static wrapWith(e){this.wrap=e}}class Ce{resources;ResourceClass;additional={};request;static wrap="data";constructor(e,t){this.resources=e,this.ResourceClass=t}withRequest(e){return this.request=e,this}withAdditional(e){return this.additional={...this.additional,...e},this}resolve(e){let t=e||this.request;return this.resources.map((n)=>{let r=new this.ResourceClass(n);if(t)r.withRequest(t);return r.resolve(t)})}toResponse(e){let t=this.resolve(e),n=this.constructor.wrap;if(n)return{[n]:t,...this.additional};return{data:t,...this.additional}}toJson(e){return JSON.stringify(this.toResponse(e))}count(){return this.resources.length}isEmpty(){return this.resources.length===0}isNotEmpty(){return this.resources.length>0}}class At extends Ce{meta;links;constructor(e,t){super(e.data,t);this.meta=e.meta,this.links=e.links}static fromPagination(e,t,n){let{currentPage:r,perPage:s,total:o,baseUrl:i=""}=n,a=Math.ceil(o/s),d=o>0?(r-1)*s+1:null,l=o>0?Math.min(r*s,o):null;return new At({data:e,meta:{current_page:r,from:d,last_page:a,per_page:s,to:l,total:o},links:{first:`${i}?page=1`,last:`${i}?page=${a}`,prev:r>1?`${i}?page=${r-1}`:null,next:r<a?`${i}?page=${r+1}`:null}},t)}toResponse(e){return{data:this.resolve(e),meta:this.meta,links:this.links,...this.additional}}}function Nn(e,t){let n=t(e);return{toResponse:()=>({data:n}),toJson:()=>JSON.stringify({data:n})}}function In(e,t){let n=e.map(t);return{toResponse:()=>({data:n}),toJson:()=>JSON.stringify({data:n})}}export{St as ConditionalValue,$t as JsonResource,ue as MergeValue,H as MissingValue,At as PaginatedResourceCollection,Ce as ResourceCollection,In as collection,cn as describedResponses,pn as fetcher,qn as generateOpenApi,Fe as methodName,on as modelDefinitionToSchema,Ft as renderApiClient,Nt as renderOpenApiTypes,Nn as resource,sn as ruleIsRequired,Ot as ruleToSchema,J as schemaType};
139
+ `}var oe;var B=P(()=>{v();oe=["get","put","post","delete","options","head","patch"]});var N=()=>{};var U={};ee(U,{loadModelRegistry:()=>he,modelFiles:()=>L});import{readdirSync as pe}from"fs";import{basename as de,extname as I,join as le}from"path";function L(e){let t=[],n=(r)=>{let o;try{o=pe(r,{withFileTypes:!0})}catch{return}for(let s of o){let a=le(r,s.name);if(s.isDirectory()){n(a);continue}if(![".ts",".js"].includes(I(s.name)))continue;if(s.name.startsWith(".")||s.name.startsWith("index"))continue;t.push(a)}};return n(e),t.sort()}async function E(e,t,n){for(let r of L(e))try{let o=I(r),s=await import(`${r}?t=${Date.now()}`),a=s.default??s,c=a.name??de(r,o);t[c]={...a,name:c}}catch(o){n?.(r,o)}}async function he(e){let t={};return await E(e.defaultsRoot,t,e.onImportError),await E(e.userRoot,t,e.onImportError),t}var V=()=>{};class _{data;status;headers;isOk;constructor(e,t,n,r){this.data=e;this.status=t;this.headers=n;this.isOk=r}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 J{defaultHeaders={Accept:"application/json","Content-Type":"application/json"};queryParams;bodyData;isFormData=!1;customHeaders={};attachments=[];isMultipart=!1;digestAuth;withQueryParams(e){return this.queryParams=e,this}withHeaders(e){return this.customHeaders={...this.customHeaders,...e},this}accept(e){return this.defaultHeaders.Accept=e,this}acceptJson(){return this.accept("application/json")}withToken(e){return this.customHeaders.Authorization=`Bearer ${e}`,this}withBasicAuth(e,t){let n=btoa(`${e}:${t}`);return this.customHeaders.Authorization=`Basic ${n}`,this}withDigestAuth(e,t){return this.digestAuth={username:e,password:t},this}withBody(e){return this.bodyData=e,this}asForm(){return this.isFormData=!0,this.defaultHeaders["Content-Type"]="application/x-www-form-urlencoded",this}attach(e,t,n,r){let o=typeof t==="string"?new Blob([t],{type:r?.["Content-Type"]||"text/plain"}):t;return this.attachments.push({name:e,content:o,filename:n,headers:r}),this.isMultipart=!0,delete this.defaultHeaders["Content-Type"],this}getHeaders(){return{...this.defaultHeaders,...this.customHeaders}}addQueryParams(e){if(!this.queryParams)return e;let t=new URLSearchParams;Object.entries(this.queryParams).forEach(([o,s])=>{if(s!=null)t.append(o,String(s))});let n=t.toString();if(!n)return e;let r=e.includes("?");return e+(r?"&":"?")+n}async formatBody(e){let t=e||this.bodyData;if(this.isMultipart){let n=new FormData;if(t)Object.entries(t).forEach(([r,o])=>{n.append(r,String(o))});for(let r of this.attachments)if(r.headers){let o=r.content instanceof Blob?new Blob([r.content],{type:r.headers["Content-Type"]}):r.content;n.append(r.name,o,r.filename)}else n.append(r.name,r.content,r.filename);return n}if(this.isFormData&&t){let n=new URLSearchParams;return Object.entries(t).forEach(([r,o])=>{if(o!=null)n.append(r,String(o))}),n.toString()}return t?JSON.stringify(t):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(e,t,n,r){if(e.status!==401||!this.digestAuth)return e;let o=e.headers.get("WWW-Authenticate");if(!o?.startsWith("Digest "))return e;let s=o.substring(7).split(",").reduce((g,d)=>{let[b,y]=d.trim().split("=");if(b)g[b]=y?.replace(/["']/g,"")??"";return g},{}),a=await this.generateMD5(`${this.digestAuth.username}:${s.realm}:${this.digestAuth.password}`),c=await this.generateMD5(`${n}:${t}`),p="00000001",l=await this.generateMD5(Date.now().toString()).then((g)=>g.substring(0,8)),i=await this.generateMD5(`${a}:${s.nonce}:${p}:${l}:${s.qop}:${c}`),u={username:`"${this.digestAuth.username}"`,realm:`"${s.realm}"`,nonce:`"${s.nonce}"`,uri:`"${t}"`,algorithm:s.algorithm?`"${s.algorithm}"`:void 0,qop:`"${s.qop}"`,nc:p,cnonce:`"${l}"`,response:`"${i}"`,opaque:s.opaque?`"${s.opaque}"`:void 0},f=Object.entries(u).filter(([g,d])=>d!==void 0).map(([g,d])=>`${g}=${d}`).join(", ");return this.customHeaders.Authorization=`Digest ${f}`,fetch(t,{method:n,headers:this.getHeaders(),body:r?await this.formatBody(r):void 0})}async generateMD5(e){let n=new TextEncoder().encode(e),r=await crypto.subtle.digest("SHA-256",n);return Array.from(new Uint8Array(r)).map((s)=>s.toString(16).padStart(2,"0")).join("")}async request(e,t,n){let r=this.addQueryParams(e),o=await this.formatBody(n),s=await fetch(r,{method:t,headers:this.getHeaders(),body:o});if(this.digestAuth)s=await this.handleDigestAuth(s,r,t,n);let a=await s.json();return this.resetState(),new _(a,s.status,s.headers,s.ok)}async get(e){return this.request(e,"GET")}async post(e,t){return this.request(e,"POST",t)}async put(e,t){return this.request(e,"PUT",t)}async patch(e,t){return this.request(e,"PATCH",t)}async delete(e){return this.request(e,"DELETE")}}var we=new J;B();import{path as S}from"@stacksjs/path";function z(e){if(!e||typeof e!=="object")return{type:"string"};let t=e,n=Array.isArray(t.rules)?t.rules:[],r=(i)=>n.find((u)=>u.name===i),o=(i,u)=>{let f=r(i)?.params?.[u];return typeof f==="number"?f:void 0},s=t.name??t._type??"string",a={type:s==="enum"?"string":s},c=o("min","min")??(typeof t._min==="number"?t._min:void 0),p=o("max","max")??(typeof t._max==="number"?t._max:void 0);if(c!==void 0)a[s==="string"?"minLength":"minimum"]=c;if(p!==void 0)a[s==="string"?"maxLength":"maximum"]=p;if(r("email")||t._email)a.format="email";if(r("url")||t._url)a.format="uri";if(r("uuid")||t._uuid)a.format="uuid";let l=Array.isArray(t.allowedValues)?t.allowedValues:Array.isArray(t._enum)?t._enum:null;if(l)a.enum=l;return a}function fe(e){if(!e||typeof e!=="object")return!1;let t=e;return Boolean(t.isRequired??t._required)}function W(e){return e.replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}function me(e){let t={id:{type:"integer"}},n=["id"];if(e.traits?.useUuid)t.uuid={type:"string",format:"uuid"},n.push("uuid");for(let[r,o]of Object.entries(e.attributes??{})){if(o.hidden===!0)continue;let s=W(r);if(t[s]=z(o.validation?.rule),o.required===!0)n.push(s)}for(let r of e.belongsTo??[]){if(typeof r!=="string"||!r.trim())continue;let o=`${W(r.trim())}_id`;t[o]??={type:"integer"}}if(e.traits?.useTimestamps!==!1)t.created_at={type:"string",format:"date-time"},t.updated_at={type:"string",format:"date-time"};if(e.traits?.useSoftDeletes)t.deleted_at={type:"string",format:"date-time",nullable:!0};return{type:"object",properties:t,required:[...new Set(n)]}}function ge(e){let t=e.traits?.useApi;if(!t||typeof t!=="object"||!t.uri)return null;let n=String(t.prefix||"").replace(/^\/+|\/+$/g,""),r=String(t.uri).replace(/^\/+|\/+$/g,"");return`/api/${n?`${n}/`:""}${r}`}function ye(e,t){let n={...t},r=e?.responses;if(r&&typeof r==="object")for(let[s,a]of Object.entries(r)){let c=a;if(!c||typeof c!=="object"||typeof c.description!=="string")continue;n[String(s)]={description:c.description,...c.schema&&typeof c.schema==="object"?{content:{"application/json":{schema:c.schema}}}:{}}}let o=e?.responseHeaders;if(o&&typeof o==="object"){let s={};for(let[a,c]of Object.entries(o)){let p=c;if(!p||typeof p!=="object"||typeof p.description!=="string")continue;s[a]={description:p.description,...p.schema&&typeof p.schema==="object"?{schema:p.schema}:{}}}if(Object.keys(s).length>0)for(let a of Object.keys(n))n[a]={...n[a],headers:s}}return n}async function be(e){if(typeof e!=="string"||!e||e.includes(".."))return null;try{let{path:t}=await import("@stacksjs/path"),n=[t.appPath(`${e}.ts`),t.storagePath(`framework/defaults/app/${e}.ts`)];for(let r of n)try{if(!await Bun.file(r).exists())continue;let a=(await import(r)).default;return a&&typeof a==="object"?a:null}catch{}}catch{}return null}async function ve(e={}){let t=e.portable??!0,{listRegisteredRoutes:n}=await import("@stacksjs/router");try{let{loadRoutes:i}=await import("@stacksjs/router"),{default:u}=await import(S.appPath("Routes.ts"));await i(u)}catch(i){let u=i instanceof Error?i.message:String(i);if(t)throw Error(`[generateOpenApi] Refusing to emit a partial spec: failed to load routes/api.ts + framework routes: ${u}`);console.warn(`[generateOpenApi] Failed to load routes/api.ts + framework routes: ${u}`)}try{try{await import("@stacksjs/orm/routes")}catch{await Promise.resolve().then(() => (N(),{}))}}catch(i){let u=i instanceof Error?i.message:String(i);if(t)throw Error(`[generateOpenApi] Refusing to emit a partial spec: failed to load useApi-generated ORM routes: ${u}`);console.warn(`[generateOpenApi] Failed to load useApi-generated ORM routes: ${u}`)}let r={};try{let u;try{u=await import("@stacksjs/orm/model-registry")}catch{u=await Promise.resolve().then(() => (V(),U))}r=await u.loadModelRegistry({defaultsRoot:S.storagePath("framework/defaults/app/Models"),userRoot:S.projectPath("app/Models")})}catch(i){let u=i instanceof Error?i.message:String(i);if(t)throw Error(`[generateOpenApi] Refusing to emit model-free schemas: ${u}`);console.warn(`[generateOpenApi] Failed to load model schemas: ${u}`)}let o=(i)=>i.replace(/(^|\/):(\w+)(?=$|\/)/g,"$1{$2}"),s=[...n()].map((i)=>({route:i,oasPath:o(i.path),method:i.method.toLowerCase()})).sort((i,u)=>{if(i.oasPath!==u.oasPath)return i.oasPath<u.oasPath?-1:1;return i.method<u.method?-1:i.method>u.method?1:0});if(t&&s.length===0)throw Error("[generateOpenApi] Refusing to emit an empty spec: no routes were registered. This usually means route loading failed silently rather than that the app has no API.");let a="Stacks API";if(!t)try{let{config:i}=await import("@stacksjs/config");if(i.app?.name)a=`${i.app.name} API`}catch{}let c={openapi:"3.0.0",info:{title:a,version:"1.0.0"},paths:{},components:{schemas:{}}},p=Object.values(r).map((i)=>({name:String(i.name),path:ge(i),schema:me(i)})).filter((i)=>i.path!==null).sort((i,u)=>i.name<u.name?-1:i.name>u.name?1:0);for(let i of p)c.components.schemas[i.name]=i.schema;let l=new Set;for(let{route:i,oasPath:u,method:f}of s){if(!c.paths[u])c.paths[u]={};let g=[];for(let h of i.path.matchAll(/\{(\w+)\}/g))if(h[1])g.push(h[1]);for(let h of i.path.matchAll(/(?:^|\/):(\w+)(?=$|\/)/g))if(h[1])g.push(h[1]);let d=i.name??`${f}_${u.replace(/[^a-z0-9]/gi,"_")}`,b=d;if(l.has(b)){b=`${d}_${f}`;let h=2;while(l.has(b))b=`${d}_${f}_${h++}`}l.add(b);let y={summary:i.name??i.path,operationId:b,parameters:g.map((h)=>({name:h,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"}}},k=p.find((h)=>u===h.path||u===`${h.path}/{id}`);if(k){let h=u===k.path&&f==="get"?{type:"array",items:k.schema}:k.schema;if(y.responses[200].content={"application/json":{schema:{type:"object",properties:{data:h},required:["data"]}}},f==="post"&&u===k.path)y.responses[201]={...y.responses[200],description:"Created"},delete y.responses[200]}let j=i.action??(i.handler?await be(i.handler):null),x=j&&typeof j.validations==="object"&&j.validations!==null?j.validations:null;y.responses=ye(j,y.responses);let D=j?.requestHeaders;if(D&&typeof D==="object")for(let[h,w]of Object.entries(D)){let m=w;if(!m||typeof m!=="object"||typeof m.description!=="string")continue;y.parameters?.push({name:h,in:"header",description:m.description,required:m.required===!0,schema:m.schema&&typeof m.schema==="object"?m.schema:{type:"string"}})}if(x&&Object.keys(x).length>0){let h=Object.entries(x).map(([w,m])=>{let A=m?.rule;return{field:w,schema:z(A),required:fe(A)}});if(f==="get"||f==="head"||f==="delete"){let w=new Set(g);for(let{field:m,schema:A,required:q}of h){if(w.has(m))continue;y.parameters?.push({name:m,in:"query",required:q,schema:A})}}else{let w={type:"object",properties:{},required:[]},{properties:m,required:A}=w;for(let q of h)if(m[q.field]=q.schema,q.required)A.push(q.field);if(A.length===0)delete w.required;y.requestBody={required:A.length>0,content:{"application/json":{schema:w}}}}}c.paths[u][f]=y}if(e.write!==!1){await Bun.write(S.frameworkPath("api/openapi.json"),JSON.stringify(c,null,2));await Promise.resolve().then(() => v());await Promise.resolve().then(() => B());await Bun.write(S.frameworkPath("api/api-types.ts"),M(c)),await Bun.write(S.frameworkPath("api/client.ts"),H(c,{name:c.info.title}))}return c}v();class R{static instance=new R;isMissing(){return!0}}class T{data;constructor(e){this.data=e}}class Q{condition;value;defaultValue;constructor(e,t,n=new R){this.condition=e;this.value=t;this.defaultValue=n}resolve(){return(typeof this.condition==="function"?this.condition():this.condition)?this.value:this.defaultValue}}class G{resource;additional={};request;static wrap="data";static additionalMeta={};constructor(e){this.resource=e}withRequest(e){return this.request=e,this}withAdditional(e){return this.additional={...this.additional,...e},this}resolve(e){let t=this.toArray(e||this.request);return this.filterAndResolve(t)}toResponse(e){let t=this.resolve(e),n=this.constructor.wrap;if(n)return{[n]:t,...this.additional};return{...t,...this.additional}}toJson(e){return JSON.stringify(this.toResponse(e))}toJSON(){return this.toResponse()}static collection(e){return new C(e,this)}when(e,t,n){if(typeof e==="function"?e():e)return typeof t==="function"?t():t;return n!==void 0?n:R.instance}whenNotNull(e,t){if(e===null||e===void 0)return R.instance;return t?t(e):e}whenLoaded(e,t,n){let r=this.resource;if(!((e in r)&&r[e]!==void 0))return n!==void 0?n:R.instance;if(t!==void 0)return typeof t==="function"?t():t;return r[e]}whenCounted(e,t){let n=this.resource,r=`${e}_count`;if(r in n)return Number(n[r]);return t!==void 0?t:R.instance}merge(e){return new T(e)}mergeWhen(e,t){if(!(typeof e==="function"?e():e))return R.instance;let r=typeof t==="function"?t():t;return new T(r)}static MAX_RESOLVE_DEPTH=20;filterAndResolve(e,t=0){if(t>=G.MAX_RESOLVE_DEPTH)return e;let n={};for(let[r,o]of Object.entries(e)){if(o instanceof R)continue;if(o instanceof T){Object.assign(n,this.filterAndResolve(o.data,t+1));continue}if(o instanceof Q){let s=o.resolve();if(!(s instanceof R))n[r]=s;continue}if(o!==null&&typeof o==="object"&&!Array.isArray(o)&&!(o instanceof Date)){n[r]=this.filterAndResolve(o,t+1);continue}if(Array.isArray(o)){n[r]=o.filter((s)=>!(s instanceof R)).map((s)=>{if(s instanceof T)return s.data;if(s!==null&&typeof s==="object"&&!(s instanceof Date))return this.filterAndResolve(s,t+1);return s});continue}n[r]=o}return n}static withoutWrapping(){this.wrap=null}static wrapWith(e){this.wrap=e}}class C{resources;ResourceClass;additional={};request;static wrap="data";constructor(e,t){this.resources=e,this.ResourceClass=t}withRequest(e){return this.request=e,this}withAdditional(e){return this.additional={...this.additional,...e},this}resolve(e){let t=e||this.request;return this.resources.map((n)=>{let r=new this.ResourceClass(n);if(t)r.withRequest(t);return r.resolve(t)})}toResponse(e){let t=this.resolve(e),n=this.constructor.wrap;if(n)return{[n]:t,...this.additional};return{data:t,...this.additional}}toJson(e){return JSON.stringify(this.toResponse(e))}count(){return this.resources.length}isEmpty(){return this.resources.length===0}isNotEmpty(){return this.resources.length>0}}class Z extends C{meta;links;constructor(e,t){super(e.data,t);this.meta=e.meta,this.links=e.links}static fromPagination(e,t,n){let{currentPage:r,perPage:o,total:s,baseUrl:a=""}=n,c=Math.ceil(s/o),p=s>0?(r-1)*o+1:null,l=s>0?Math.min(r*o,s):null;return new Z({data:e,meta:{current_page:r,from:p,last_page:c,per_page:o,to:l,total:s},links:{first:`${a}?page=1`,last:`${a}?page=${c}`,prev:r>1?`${a}?page=${r-1}`:null,next:r<c?`${a}?page=${r+1}`:null}},t)}toResponse(e){return{data:this.resolve(e),meta:this.meta,links:this.links,...this.additional}}}function De(e,t){let n=t(e);return{toResponse:()=>({data:n}),toJson:()=>JSON.stringify({data:n})}}function Be(e,t){let n=e.map(t);return{toResponse:()=>({data:n}),toJson:()=>JSON.stringify({data:n})}}export{Q as ConditionalValue,G as JsonResource,T as MergeValue,R as MissingValue,Z as PaginatedResourceCollection,C as ResourceCollection,Be as collection,ye as describedResponses,we as fetcher,ve as generateOpenApi,ie as methodName,me as modelDefinitionToSchema,H as renderApiClient,M as renderOpenApiTypes,De as resource,fe as ruleIsRequired,z as ruleToSchema,O as schemaType};
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/api",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.74.19",
5
+ "version": "0.74.21",
6
6
  "description": "The Stacks API utilities.",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -61,15 +61,15 @@
61
61
  "prepublishOnly": "bun run build"
62
62
  },
63
63
  "dependencies": {
64
- "@stacksjs/config": "0.74.19",
65
- "@stacksjs/path": "0.74.19"
64
+ "@stacksjs/config": "0.74.21",
65
+ "@stacksjs/path": "0.74.21"
66
66
  },
67
67
  "devDependencies": {
68
- "@stacksjs/utils": "0.74.19",
68
+ "@stacksjs/utils": "0.74.21",
69
69
  "better-dx": "^0.2.24"
70
70
  },
71
71
  "peerDependencies": {
72
- "@stacksjs/router": "0.74.19"
72
+ "@stacksjs/router": "0.74.21"
73
73
  },
74
74
  "peerDependenciesMeta": {
75
75
  "@stacksjs/router": {