@stacksjs/api 0.74.34 → 0.74.35

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 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(`
2
+ var _t=Object.defineProperty;var Pt=(e)=>e;function xt(e,t){this[e]=Pt.bind(null,t)}var de=(e,t)=>{for(var n in t)_t(e,n,{get:t[n],enumerable:!0,configurable:!0,set:xt.bind(t,n)})};var K=(e,t)=>()=>(e&&(t=e(e=0)),t);var V=import.meta.require;var Ee={};de(Ee,{renderOpenApiTypes:()=>Ct,schemaType:()=>J});function vt(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(vt).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 Dt(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(`
4
4
  `)}
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}
5
+ }`}function Be(e){if(!e||!Object.keys(e).length)return"never";return`{ ${Object.entries(e).map(([t,n])=>`${JSON.stringify(t)}: ${J(n.schema)}`).join("; ")} }`}function qt(e){let t=e.requestBody?`
6
+ requestBody${e.requestBody.required?"":"?"}: { content: ${Be(e.requestBody.content)} }`:`
7
+ requestBody?: never`,n=Object.entries(e.responses||{}).map(([r,s])=>` ${JSON.stringify(r)}: { content: ${Be(s.content)} }`);return`{
8
+ ${Dt(e.parameters)}${t}
9
9
  responses: {
10
10
  ${n.join(`
11
11
  `)}
12
12
  }
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(`
13
+ }`}function Ct(e){let t=Object.entries(e.paths||{}).map(([r,s])=>{let o=jt.map((i)=>{let a=s[i];return a?` ${i}: ${qt(a)}`:` ${i}?: never`});return` ${JSON.stringify(r)}: {
14
+ ${o.join(`
15
15
  `)}
16
- }`}),n=Object.entries(e.components?.schemas||{}).map(([r,o])=>` ${JSON.stringify(r)}: ${O(o)}`);return`/**
16
+ }`}),n=Object.entries(e.components?.schemas||{}).map(([r,s])=>` ${JSON.stringify(r)}: ${J(s)}`);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 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}/**
32
+ `}var jt;var pe=K(()=>{jt=["get","put","post","delete","options","head","patch","trace"]});var Me={};de(Me,{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 It(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 Bt(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 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 */
36
+ `}function Et(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`${Bt([n.summary&&n.summary!==e?n.summary:`${t.toUpperCase()} ${e}`,n.description??""])} ${r}(${p}options?: RequestOptions): Promise<ApiResult<${It(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 Nt){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(Et(o,a,d,c===0?l:`${l}${c+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
- ${o.join(`
132
+ ${s.join(`
133
133
 
134
134
  `)}
135
135
  }
136
136
  }
137
137
 
138
138
  export type Client = ReturnType<typeof createClient>
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};
139
+ `}var Nt;var he=K(()=>{pe();Nt=["get","put","post","delete","options","head","patch"]});function Mt(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 we(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(Mt(e))return{status:409,body:{error:`${t} already exists`}};return{status:500,body:{error:`Failed to ${n} ${t}`,detail:String(e)}}}function P(e){return e.replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/([A-Z])([A-Z][a-z])/g,"$1_$2").toLowerCase()}function be(e){let t={};for(let[n,r]of Object.entries(e))t[P(n)]=r;return t}function He(e,t){let n=String(t||"").replace(/^\/+|\/+$/g,""),r=String(e).replace(/^\/+/,"");return`/api/${n?`${n}/`:""}${r}`}function Le(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 Qe(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 We(e){return e?.ownership===!1}function ze(e,t,n){let r=Object.keys(e).find((o)=>P(o)===P(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(P(o)===P(t))delete s[o];return s[t]=n,{data:s}}function Ve(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=P(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 Re(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=P(r);if(s!==r&&s in e)n[r]=e[s]}return n}function Ut(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 ke(e,t){if(!t.length)return e;let n={...e};for(let r of t)delete n[r],delete n[P(r)];return n}function te(e,t){if(!e||t.length===0)return e;let n={...e};for(let r of t)delete n[r],delete n[P(r)];return n}function Ge(e,t){let n=new Map;for(let r of[...Object.keys(e??{}),...Jt]){let s=P(r);if(!/^\w+$/.test(s))continue;n.set(r,s),n.set(s,s)}for(let r of t)n.delete(r),n.delete(P(r));return n}function Xe(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 Lt(e){try{return JSON.parse(e)}catch{return e}}function Qt(e){try{return JSON.parse(e)}catch{return[]}}function Oe(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"?Ht[o]:o;if(!i||typeof i[n]!=="function")continue;if(Object.prototype.hasOwnProperty.call(r,s))r[s]=i[n](r[s]);let a=P(s);if(a!==s&&Object.prototype.hasOwnProperty.call(r,a))r[a]=i[n](r[a])}return r}function Se(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=Ut(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 Ke(e,t,n){let r=Ue(n);return e.find((s)=>s.method===t&&Ue(String(s.path??""))===r)}function Ue(e){return e.replace(/\{[^}]*\}/g,"{}").replace(/:[^/]+/g,"{}")}function ye(e){if(Array.isArray(e))return e.filter((t)=>typeof t==="string"&&t.length>0);return typeof e==="string"&&e?[e]:[]}function Ze(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?ye(s.read):["auth"],write:"write"in s?ye(s.write):["auth"],declared:!0}}let r=ye(n);return{read:r,write:r,declared:!0}}function Ye(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(Je),10),s=Math.min(Number.isFinite(r)?Math.max(1,r):Je,Wt);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 zt(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 $e(e,t,n,r,s,o){let{page:i,...a}=zt(e,t,n,r,s,o);return{current_page:i,...a}}function Ae(e,t){return(t??e??"").toString().trim().toLowerCase()==="warn"?"warn":"deny"}function et(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 Jt,Ht,Je=15,Wt=100;var Te=K(()=>{Jt=["id","uuid","created_at","updated_at","deleted_at"];Ht={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"?Lt(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"?Qt(e):[],set:(e)=>e==null?null:Array.isArray(e)?JSON.stringify(e):e}}});var st={};de(st,{loadModelRegistry:()=>_e,modelFiles:()=>rt});import{readdirSync as Vt}from"fs";import{basename as Gt,extname as nt,join as Xt}from"path";function rt(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(nt(o.name)))continue;if(o.name.startsWith(".")||o.name.startsWith("index"))continue;t.push(i)}};return n(e),t.sort()}async function tt(e,t,n){for(let r of rt(e))try{let s=nt(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 _e(e){let t={};return await tt(e.defaultsRoot,t,e.onImportError),await tt(e.userRoot,t,e.onImportError),t}var Pe=()=>{};function xe(e){if(e?.ownership===!1)return null;if(e?.ownership)return e.ownership;let t=Le(e);if(t)return{field:t,resolve:async(r,s)=>{let{resolveAuthenticatedTeamId:o}=await import("@stacksjs/auth");return o(Kt(s))}};let n=Qe(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 ot=K(()=>{Te()});import Zt from"process";import{route as W}from"@stacksjs/router";import{env as Z}from"@stacksjs/env";import{projectPath as De,storagePath as Yt}from"@stacksjs/path";import{createQueryBuilder as en,defaultConfig as it,setConfig as at}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=Ke(W.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 ft(e){if(!e.attributes)return[];return Object.entries(e.attributes).filter(([t,n])=>n.hidden===!0).map(([t])=>t)}function ct(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 ut(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(P(l),{kind:"belongsTo",modelName:l});for(let l of a)d.set(P(l),{kind:"hasOne",modelName:l});for(let l of i)d.set(ct(P(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||ct(P(c.modelName)),j=ft(p),R=(q)=>te(ae(q,p),j);if(c.kind==="belongsTo"||c.kind==="hasOne"){let q=`${P(c.modelName)}_id`,T=[...new Set(e.map((x)=>x[q]).filter((x)=>x!=null))];if(!T.length){for(let x of e)x[l]=null;continue}let M=await B.selectFrom(w).whereIn("id",T).get(),E=new Map;for(let x of M??[])E.set(String(x.id),R(x));for(let x of e)x[l]=E.get(String(x[q]))??null}else{let q=String(t.name??""),T=`${P(q)}_id`,M=[...new Set(e.map((D)=>D.id).filter((D)=>D!=null))];if(!M.length){for(let D of e)D[l]=[];continue}let E=await B.selectFrom(w).whereIn(T,M).get(),x=new Map;for(let D of E??[]){let k=String(D[T]),I=x.get(k)??[];I.push(R(D)),x.set(k,I)}for(let D of e)D[l]=x.get(String(D.id))??[]}}return e}async function lt(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 dt(e,t){return Oe(e,t?.casts,"set")}function ae(e,t){return Oe(e,t?.casts,"get")}function m(e,t=200){return new Response(JSON.stringify(e),{status:t,headers:{"Content-Type":"application/json"}})}async function ve(e){if(Number(e.headers?.get?.("content-length")??0)>ge)throw new G(413,`Request body exceeds ${ge}-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>ge)throw new G(413,`Request body exceeds ${ge}-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 me(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 ne(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 ie(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 re(e,t,n){let r=xe(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 pt(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,je,nn,B,ge=1048576,gt,mt,ht;var yt=K(async()=>{Te();Pe();ot();tn=De("config/qb.ts");try{let e=(await import(tn)).default;at(e??it)}catch{ee.debug("[orm] No config/qb.ts override found - deriving config from DB_CONNECTION");let e=Z.DB_CONNECTION||"sqlite";at({...it,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||""}})}je=await _e({defaultsRoot:Yt("framework/defaults/app/Models"),userRoot:De("app/Models"),onImportError:(e,t)=>ee.warn(`[orm] Could not load model ${e}: ${t.message}`)}),nn=en(),B=nn;gt=await(async()=>{let e=Zt.env.STACKS_API_ROW_SCOPING;try{let t=(await import(De("config/security.ts"))).default;return Ae(t?.api?.rowScoping,e)}catch{return Ae(void 0,e)}})(),mt=[];for(let[e,t]of Object.entries(je)){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=Ve(t),d=ft(t),l=He(s,r.prefix),c=Ge(t.attributes,d),{read:p,write:w,declared:j}=Ze(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=!!xe(t),M=T&&!p.includes("auth")?["auth",...p]:p,E=We(t),x=R&&!T&&!E;if(x)mt.push(e);if(R&&E)ee.debug(`[orm] ${e}: registering unscoped mutating routes at ${l} (declared \`ownership: false\`)`);let D=x&&gt==="deny",k=(g,u=M)=>{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(W.get(l,async(g)=>{try{let u=new URL(g.url),{page:f,perPage:h,offset:S}=Ye(u.searchParams),O=u.searchParams.get("sort"),y=B.selectFrom(i);y=Xe(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(P(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)=>P(N));if(C.length>0)y=y.select(C)}let F=!!t.traits?.useSoftDeletes,A=u.searchParams.get("withTrashed")==="true",L=u.searchParams.get("onlyTrashed")==="true";if(F&&!A)y=L?y.whereNotNull("deleted_at"):y.whereNull("deleted_at");let b=T?await re(t,await ne(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=$e(u,f,h,0,!1,void 0);return new Response(JSON.stringify({data:[],...C}),{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()||[],z=Q.length>h,ue=(z?Q.slice(0,h):Q).map((C)=>te(ae(C,t),d)),Ce=u.searchParams.get("include");if(Ce)ue=await ut(ue,t,Ce,je);let At=u.searchParams.get("with_count")==="true",oe;if(At)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))oe=X}catch{}let le={"Content-Type":"application/json"};if(oe!==void 0&&!Number.isNaN(oe))le["X-Total-Count"]=String(oe);le["Cache-Control"]=b.enforced&&!b.bypass?"private, no-store":"public, max-age=15, must-revalidate",le.Vary="Authorization";let Tt=$e(u,f,h,ue.length,z,oe);return new Response(JSON.stringify({data:ue,...Tt}),{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(W.get(`${l}/{id}`,async(g)=>{try{let u=me(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 re(t,await ne(g),g):{enforced:!1,value:null,field:"",bypass:!1};if(S.enforced&&!S.bypass){if(S.value==null||!ie(f[S.field],S.value))return m({error:`${e} not found`},404)}let O=te(ae(f,t),d),y=h.searchParams.get("include");if(y){let[A]=await ut([O],t,y,je);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 F={"Content-Type":"application/json"};if(_)F.ETag=_;return F["Cache-Control"]=S.enforced&&!S.bypass?"private, no-store":"public, max-age=30, must-revalidate",F.Vary="Authorization",new Response(JSON.stringify({data:O}),{status:200,headers:F})}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(W.post(l,async(g)=>{try{let u=await ve(g),f=ke(u,d),h=Re(f,a),S=await ne(g);if(S){let A=await pt(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 re(t,S,g);if(O.enforced&&!O.bypass){if(!S)return m({error:"Auth required"},401);let A=ze(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=Se(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 lt(h,t),_=be(dt(U,t)),v=await B.insertInto(i).values(_).execute(),F=_;try{let A=v?.lastInsertRowid??v?.insertId??v;if(A){let L=await B.selectFrom(i).where({id:A}).executeTakeFirst();if(L)F=L}}catch{}return m({data:te(ae(F,t),d)},201)}catch(u){let{status:f,body:h}=we(u,e,"create");return m(h,f)}}),w);if(!D&&o.includes("update")){let g=async(u)=>{try{let f=me(u.params?.id);if(f==null)return m({error:"Invalid ID parameter"},400);let h=await ve(u),S=ke(h,d),O=Re(S,a),y=await ne(u);if(y){let b=await pt(t,"updating",y,u);for(let[Q,z]of Object.entries(b))if(z!==void 0&&z!==null&&O[Q]===void 0)O[Q]=z}if(Object.keys(O).length===0)return m({error:"No fillable fields provided"},422);let U=Se(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 re(t,y,u);if(v.enforced&&!v.bypass){if(!y)return m({error:"Auth required"},401);let b=_[v.field];if(!ie(b,v.value))return m({error:`Not your ${e}`},403);let Q=Object.keys(O).find((z)=>P(z)===P(v.field));if(Q!==void 0&&!ie(O[Q],v.value))return m({error:`Cannot reassign ${e} ownership`},403)}if(t.traits?.useTimestamps!==!1)O.updated_at=new Date().toISOString();let F=await lt(O,t),A=be(dt(F,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:te(ae(L,t),d)})}catch(f){let{status:h,body:S}=we(f,e,"update");return m(S,h)}};if(!Y("PUT",`${l}/{id}`))k(W.put(`${l}/{id}`,g),w);if(!Y("PATCH",`${l}/{id}`))k(W.patch(`${l}/{id}`,g),w)}let I=!!t.traits?.useSoftDeletes;if(!D&&o.includes("destroy")&&!Y("DELETE",`${l}/{id}`))k(W.delete(`${l}/{id}`,async(g)=>{try{let u=me(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 ne(g),S=await re(t,h,g);if(S.enforced&&!S.bypass){if(!h)return m({error:"Auth required"},401);let O=f[S.field];if(!ie(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(W.post(`${l}/bulk-delete`,async(g)=>{try{let f=(await ve(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=me(_);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 ne(g),y=await re(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)=>ie(A[y.field],y.value)).map((A)=>String(A.id))),F=h.filter((A)=>!v.has(String(A)));if(F.length>0)return m({error:`Cannot delete ${e} you don't own`,ids:F},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=et(mt,gt);if(e)ee.warn(e)}ht=W});var wt={};de(wt,{default:()=>ht});var bt=K(async()=>{await yt()});class Ne{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 Ie{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 Ne(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 Ie;he();import{path as se}from"@stacksjs/path";function kt(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 Rt(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=Rt(r);if(t[o]=kt(s.validation?.rule),s.required===!0)n.push(o)}for(let r of e.belongsTo??[]){if(typeof r!=="string"||!r.trim())continue;let s=`${Rt(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(se.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 bt().then(() => wt)}}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(),st))}r=await p.loadModelRegistry({defaultsRoot:se.storagePath("framework/defaults/app/Models"),userRoot:se.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"}}},M=d.find((k)=>p===k.path||p===`${k.path}/{id}`);if(M){let k=p===M.path&&w==="get"?{type:"array",items:M.schema}:M.schema;if(T.responses[200].content={"application/json":{schema:{type:"object",properties:{data:k},required:["data"]}}},w==="post"&&p===M.path)T.responses[201]={...T.responses[200],description:"Created"},delete T.responses[200]}let E=c.action??(c.handler?await un(c.handler):null),x=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(x&&Object.keys(x).length>0){let k=Object.entries(x).map(([I,g])=>{let u=g?.rule;return{field:I,schema:kt(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(se.frameworkPath("api/openapi.json"),JSON.stringify(a,null,2));let{renderOpenApiTypes:c}=await Promise.resolve().then(() => (pe(),Ee)),{renderApiClient:p}=await Promise.resolve().then(() => (he(),Me));await Bun.write(se.frameworkPath("api/api-types.ts"),c(a)),await Bun.write(se.frameworkPath("api/client.ts"),p(a,{name:a.info.title}))}return a}pe();class H{static instance=new H;isMissing(){return!0}}class ce{data;constructor(e){this.data=e}}class Ot{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 St{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 qe(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 ce(e)}mergeWhen(e,t){if(!(typeof e==="function"?e():e))return H.instance;let r=typeof t==="function"?t():t;return new ce(r)}static MAX_RESOLVE_DEPTH=20;filterAndResolve(e,t=0){if(t>=St.MAX_RESOLVE_DEPTH)return e;let n={};for(let[r,s]of Object.entries(e)){if(s instanceof H)continue;if(s instanceof ce){Object.assign(n,this.filterAndResolve(s.data,t+1));continue}if(s instanceof Ot){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 ce)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 qe{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 $t extends qe{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 $t({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{Ot as ConditionalValue,St as JsonResource,ce as MergeValue,H as MissingValue,$t as PaginatedResourceCollection,qe as ResourceCollection,In as collection,cn as describedResponses,pn as fetcher,qn as generateOpenApi,Fe as methodName,on as modelDefinitionToSchema,Ft as renderApiClient,Ct as renderOpenApiTypes,Nn as resource,sn as ruleIsRequired,kt as ruleToSchema,J 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.34",
5
+ "version": "0.74.35",
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.34",
65
- "@stacksjs/path": "0.74.34"
64
+ "@stacksjs/config": "0.74.35",
65
+ "@stacksjs/path": "0.74.35"
66
66
  },
67
67
  "devDependencies": {
68
- "@stacksjs/utils": "0.74.34",
68
+ "@stacksjs/utils": "0.74.35",
69
69
  "better-dx": "^0.2.24"
70
70
  },
71
71
  "peerDependencies": {
72
- "@stacksjs/router": "0.74.34"
72
+ "@stacksjs/router": "0.74.35"
73
73
  },
74
74
  "peerDependenciesMeta": {
75
75
  "@stacksjs/router": {