express-zod-api 29.3.1 → 29.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  ## Version 29
4
4
 
5
+ ### v29.3.3
6
+
7
+ - Added a warning about using the built-in logger in production:
8
+ - The `BuiltinLogger` is intended for development purposes only because it prints messages synchronously;
9
+ - That may degrade the performance of your API in production mode (`NODE_ENV=production`).
10
+
11
+ ### v29.3.2
12
+
13
+ - The tags and scopes given to `EndpointsFactory::build()` are now deduplicated and immutable:
14
+ - The generated `Documentation` and `Integration` would no longer contain duplicate entries of that kind.
15
+
5
16
  ### v29.3.1
6
17
 
7
18
  - Fixed the `Endpoint` methods duplication issue:
package/README.md CHANGED
@@ -729,7 +729,7 @@ To receive a compressed response, the client should include the following header
729
729
 
730
730
  ## Customizing logger
731
731
 
732
- A simple built-in console logger is used by default with the following options that you can configure:
732
+ The built-in logger is used by default with the following options that you can configure:
733
733
 
734
734
  ```ts
735
735
  import { createConfig } from "express-zod-api";
@@ -742,8 +742,10 @@ const config = createConfig({
742
742
  });
743
743
  ```
744
744
 
745
- You can also replace it with a one having at least the following methods: `info()`, `debug()`, `error()` and `warn()`.
746
- Winston and Pino support is well-known. Here is an example configuring `pino` logger with `pino-pretty` extension:
745
+ However, it's for development purposes only: it prints messages to the console synchronously, which may degrade the
746
+ performance of your API in [production mode](#production-mode). Consider installing a professional logging solution
747
+ instead, such as [Pino](https://github.com/pinojs/pino) or [Winston](https://github.com/winstonjs/winston). You can use
748
+ any logger having at least these methods: `info()`, `debug()`, `error()` and `warn()`. Here is how to use `pino`:
747
749
 
748
750
  ```ts
749
751
  import pino, { Logger } from "pino";
@@ -1459,9 +1461,9 @@ const rawAcceptingEndpoint = defaultEndpointsFactory.build({
1459
1461
 
1460
1462
  ## Profiling
1461
1463
 
1462
- For debugging and performance testing purposes the framework offers a simple `.profile()` method on the built-in logger.
1463
- It starts a timer when you call it and measures the duration in adaptive units (from picoseconds to minutes) until you
1464
- invoke the returned callback. The default severity of those measurements is `debug`.
1464
+ During development, for debugging and performance testing purposes, the framework offers a simple `.profile()` method
1465
+ on the built-in logger. It starts a timer when you call it and measures the duration in adaptive units (from
1466
+ picoseconds to minutes) until you invoke the returned callback. The default severity of those measurements is `debug`.
1465
1467
 
1466
1468
  ```ts
1467
1469
  import { createConfig, BuiltinLogger } from "express-zod-api";
@@ -1 +1 @@
1
- import{$ as e,F as t,G as n,I as r,J as i,K as a,N as o,Q as s,R as c,W as l,X as u,j as d,nt as f,q as p,r as m,w as h,x as g,y as _}from"./routing-walker-CcgJ8aiU.js";import{z as v}from"zod";import*as y from"ramda";import{isReferenceObject as b,isSchemaObject as x}from"openapi3-ts/oas32";const S=e=>e.type===`object`,C=y.mergeDeepWith((e,t)=>{if(Array.isArray(e)&&Array.isArray(t))return y.concat(e,t);if(e===t)return t;throw Error(`Can not flatten properties`,{cause:{a:e,b:t}})}),w=new Set([`type`,`properties`,`required`,`examples`,`description`,`additionalProperties`]),T=e=>{for(let t of Object.keys(e))if(!w.has(t))return!1;return!0},E=y.pair(!0),ee=(e,t,n)=>!(`allOf`in e)||!e.allOf?[]:e.allOf.map(e=>{if(t===`throw`&&!(e.type===`object`&&T(e)))throw Error(`Can not merge`);return y.pair(n,e)}),te=e=>{let t=[];return e.anyOf&&t.push(...y.map(E,e.anyOf)),e.oneOf&&t.push(...y.map(E,e.oneOf)),t},ne=(e,t,n,r)=>{if(!a(e.propertyNames))return;let i=[];typeof e.propertyNames.const==`string`&&i.push(e.propertyNames.const),e.propertyNames.enum&&i.push(...e.propertyNames.enum.filter(e=>typeof e==`string`));let o={...Object(e.additionalProperties)};for(let e of i)t.properties[e]??=o;r||n.push(...i)},re=(e,t,n)=>{t.examples?.length&&(e.examples=n?y.concat(e.examples||[],t.examples):c(e.examples?.filter(a)||[],t.examples.filter(a),([e,t])=>y.mergeDeepRight(e,t)))},D=(e,t=`coerce`)=>{let n=[y.pair(!1,e)],r={type:`object`,properties:{}},i=[];for(let[e,a]of n)a.description&&(r.description??=a.description),n.push(...ee(a,t,e)),n.push(...te(a)),re(r,a,e),S(a)&&(n.push([e,{examples:O(a)}]),a.properties&&(r.properties=(t===`throw`?C:y.mergeDeepRight)(r.properties,a.properties),!e&&a.required&&i.push(...a.required)),ne(a,r,i,e));return i.length&&(r.required=[...new Set(i)]),r},O=e=>Object.entries(e.properties||{}).reduce((e,[t,n])=>{let{examples:r=[]}=a(n)?n:{};return c(e,r.map(y.objOf(t)),([e,t])=>({...e,...t}))},[]),k=`x-coerce`,A=(e,t)=>{if(e[`x-coerce`]===!0)return!0;if(e.anyOf)return e.anyOf.some(e=>A(e,t));if(e.oneOf)return e.oneOf.some(e=>A(e,t));if(e.allOf)return e.allOf.every(e=>A(e,t));if(e.type===void 0||e.type===`string`)return!0;if(t===`query`&&[`array`,`object`].includes(e.type)){let n=[e.items,e.prefixItems,e.additionalItems,Object.values(e.properties??{}),e.additionalProperties,e.propertyNames];for(let e of n){if(!a(e))continue;let n=Array.isArray(e)?e:[e];for(let e of n)if(a(e)&&!A(e,t))return!1}return!0}return!1};let j;const M=()=>j??=new Set(`a-im.accept.accept-additions.accept-charset.accept-datetime.accept-encoding.accept-features.accept-language.accept-signature.access-control.access-control-request-headers.access-control-request-method.alpn.alt-used.amp-cache-transform.apply-to-redirect-ref.authorization.available-dictionary.c-ext.c-man.c-opt.c-pep.c-pep-info.cache-control.cal-managed-id.caldav-timezones.capsule-protocol.cdn-loop.cert-not-after.cert-not-before.client-cert.client-cert-chain.close.cmcd-object.cmcd-request.cmcd-session.cmcd-status.cmsd-dynamic.cmsd-static.concealed-auth-export.configuration-context.connection.content-digest.content-disposition.content-encoding.content-id.content-language.content-length.content-location.content-md5.content-range.content-script-type.content-type.cookie.cookie2.cta-common-access-token.dasl.date.dav.default-style.delta-base.deprecation.depth.derived-from.destination.detached-jws.dictionary-id.differential-id.digest.dpop.early-data.ediint-features.expect.expect-ct.ext.forwarded.from.getprofile.hobareg.host.http2-settings.if.if-match.if-modified-since.if-none-match.if-range.if-schedule-tag-match.if-unmodified-since.im.include-referred-token-binding-id.incremental.isolation.keep-alive.label.last-event-id.link.link-template.lock-token.man.max-forwards.memento-datetime.meter.method-check.method-check-expires.mime-version.negotiate.odata-entityid.odata-isolation.odata-maxversion.odata-version.opt.ordering-type.origin.origin-agent-cluster.oscore.oslc-core-version.overwrite.pep.pep-info.permissions-policy.pics-label.ping-from.ping-to.position.pragma.prefer.preference-applied.priority.profileobject.protocol.protocol-info.protocol-query.protocol-request.proxy-authorization.proxy-features.proxy-instruction.range.redirect-ref.referer.referer-root.referrer-policy.repeatability-client-id.repeatability-first-sent.repeatability-request-id.repeatability-result.replay-nonce.reporting-endpoints.repr-digest.safe.schedule-reply.schedule-tag.sec-fetch-storage-access.sec-gpc.sec-purpose.sec-token-binding.sec-websocket-extensions.sec-websocket-key.sec-websocket-protocol.sec-websocket-version.security-scheme.signature.signature-input.slug.soapaction.status-uri.sunset.surrogate-capability.tcn.te.timeout.topic.traceparent.tracestate.trailer.transfer-encoding.ttl.upgrade.urgency.uri.user-agent.variant-vary.via.want-content-digest.want-digest.want-repr-digest.want-unencoded-digest.warning.x-content-type-options.x-frame-options`.split(`.`)),N={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},P=e=>e.replace(u,e=>`{${e.slice(1)}}`),F=({},e)=>{if(e.isResponse)throw new h(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},I=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),L=({zodSchema:e,jsonSchema:t})=>{if(!p(e,`union`)||!(`discriminator`in e._zod.def))return t;let n=e._zod.def.discriminator;return{...t,discriminator:t.discriminator??{propertyName:n}}},R=y.tryCatch(({jsonSchema:e})=>{if(!e.allOf)throw`no allOf`;return D(e,`throw`)},(e,{jsonSchema:t})=>t),z=({jsonSchema:e})=>{if(!e.anyOf||!e.anyOf.length)return e;let t=e.anyOf[0];return Object.assign(t,{type:K(t.type)})},B=e=>e,V=({jsonSchema:e},t)=>{if(t.isResponse)throw new h(`Please use ez.dateOut() for output.`,t);return e},H=({jsonSchema:e},t)=>{if(!t.isResponse)throw new h(`Please use ez.dateIn() for input.`,t);return e},U=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),W=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,G=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return N?.[t]},K=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],ie=({zodSchema:e,jsonSchema:t},r)=>{let i=e._zod.def[r.isResponse?`out`:`in`],a=e._zod.def[r.isResponse?`in`:`out`];if(!p(i,`transform`))return t;let o=B(Z(a,{ctx:r}));if(x(o))if(r.isResponse){let e=n(i,G(o));if(e&&[`number`,`string`,`boolean`].includes(e))return{...t,type:e}}else{let{type:e,...t}=o;return{...t,format:`${t.format||e} (preprocessed)`}}return t},q=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!a(t.properties.raw)?e:t.properties.raw},J=e=>e.length?y.fromPairs(y.zip(y.times(e=>`example${e+1}`,e.length),y.map(y.objOf(`dataValue`),e))):void 0,Y=(e,t)=>t?.has(e)||e.startsWith(`x-`)||M().has(e),ae=({method:e,path:t,security:n,inputSources:r,isHeader:i})=>{let a=new Set(l(t)),o=r.includes(`query`),s=r.includes(`params`),c=r.includes(`headers`),u=r.includes(`cookies`)||r.includes(`signedCookies`),d;c&&n&&(d=m(n,`header`));let f;return u&&n&&(f=m(n,`cookie`)),{pathParams:a,getLocation:n=>{if(s&&a.has(n)&&a.delete(n))return`path`;if(u&&f?.has(n))return`cookie`;if(c&&(i?.(n,e,t)??Y(n,d)))return`header`;if(o&&e!==`query`)return`query`},isQueryEnabled:o}},oe=({path:e,method:t,flatRequest:n,makeRef:r,composition:o,getLocation:s,description:c=`${t.toUpperCase()} ${e} Parameter`})=>{let l=[];for(let[e,t]of Object.entries(n.properties)){if(!a(t))continue;let u=s(e);if(!u)continue;let d=B(t),f=o===`components`?r(t.id||JSON.stringify(t),d,t.id||i(c,e)):d;l.push({name:e,in:u,deprecated:t.deprecated,required:n.required?.includes(e)||u===`path`,description:d.description||c,schema:f,examples:J(x(d)&&d.examples?.length?d.examples:y.pluck(e,n.examples?.filter(y.both(a,y.has(e)))||[]))})}return l},X={nullable:z,union:L,bigint:U,intersection:R,tuple:W,pipe:ie,[o]:V,[d]:H,[g]:F,[_]:q,[t]:I},se=(e,t,n)=>{let r=[e,t],i=e=>/schema\d+$/.test(e)?void 0:e;for(let e=0;e<r.length;e++){let a=r[e];if(y.is(Object,a)){if(b(a)&&!a.$ref.startsWith(`#/components`)){let e=a.$ref.split(`/`).pop(),r=t[e];if(r){let t=r.id||i(e);a.$ref=n.makeRef(t||r,B(r),t).$ref}continue}r.push(...y.values(a))}y.is(Array,a)&&r.push(...y.values(a))}return e},Z=(e,{ctx:t,rules:n=X})=>{let{$defs:i={},properties:o={}}=v.toJSONSchema(v.object({subject:e}),{unrepresentable:`any`,io:t.isResponse?`output`:`input`,override:e=>{let i=v.globalRegistry.get(e.zodSchema)?.id;if(i){let n=t.seenIds.get(i);if(n&&n!==e.zodSchema)throw new h(`The meta id "${i}" is used by two different schemas. Please make the ids unique or reuse the same schema instance.`,t);t.seenIds.set(i,e.zodSchema)}let a=r(e.zodSchema),o=n[a&&a in n?a:e.zodSchema._zod.def.type];if(o){let n={...o(e,t)};for(let t in e.jsonSchema)delete e.jsonSchema[t];Object.assign(e.jsonSchema,n)}}});return se(a(o.subject)?o.subject:{},i,t)},Q=(e,t)=>{if(b(e))return[e,!1];let n=!1,r=y.map(e=>{let[r,i]=Q(e,t);return n||=i,r}),i=y.omit(t),a={properties:i,examples:y.map(i),required:y.without(t),allOf:r,oneOf:r,anyOf:r},o=y.evolve(a,e);return[o,n||!!o.required?.length]},ce=({method:t,path:n,schema:r,mimeTypes:a,variant:o,makeRef:c,composition:l,hasMultipleStatusCodes:u,statusCode:d,brandHandling:p,seenIds:m,description:h=`${t.toUpperCase()} ${n} ${e(o)} response ${u?d:``}`.trim()})=>{if(!s(t,a))return{description:h};let g=B(Z(r,{rules:{...p,...X},ctx:{isResponse:!0,makeRef:c,path:n,method:t,seenIds:m}})),_=[];x(g)&&g.examples&&(_.push(...g.examples),delete g.examples);let v=l===`components`?c(r,g,i(h)):g;return{description:h,content:y.fromPairs(a.map(e=>[e,{[e===f.sse?`itemSchema`:`schema`]:v,examples:J(_)}]))}},le=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},ue=({name:e},t)=>{let n={type:`apiKey`,in:`query`,name:e};return t?.includes(`body`)&&(t?.includes(`query`)?(n[`x-in-alternative`]=`body`,n.description=`${e} CAN also be supplied within the request body`):(n[`x-in-actual`]=`body`,n.description=`${e} MUST be supplied within the request body instead of query`)),n},de=({name:e})=>({type:`apiKey`,in:`header`,name:e}),fe=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),pe=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),$=({flows:e={},oauth2MetadataUrl:t})=>({type:`oauth2`,flows:y.map(e=>({...e,scopes:e.scopes||{}}),y.reject(y.isNil,e)),oauth2MetadataUrl:t}),me=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?le(e):e.type===`input`?ue(e,t):e.type===`header`?de(e):e.type===`cookie`?fe(e):e.type===`openid`?pe(e):$(e);return e.map(e=>e.map(({deprecated:e,...t})=>({...n(t),deprecated:e})))},he=(e,t,n)=>e.map(e=>e.reduce((e,r)=>{let i=n(r),a=[`oauth2`,`openIdConnect`].includes(r.type);return Object.assign(e,{[i]:a?t:[]})},{})),ge=({schema:e,brandHandling:t,makeRef:n,path:r,method:i,seenIds:a})=>Z(e,{rules:{...t,...X},ctx:{isResponse:!1,makeRef:n,path:r,method:i,seenIds:a}}),_e=({method:e,path:t,bodyJsonSchema:n,hasRequiredBodyProps:r,flatRequest:o,mimeType:s,makeRef:c,composition:l,paramNames:u,description:d=`${e.toUpperCase()} ${t} Request body`})=>{let p=B(n),m=[];x(p)&&p.examples&&(m.push(...p.examples),delete p.examples);let h={schema:l===`components`?c(JSON.stringify(p),p,i(d)):p,examples:J(m.length?m:o.examples?.filter(e=>a(e)&&!Array.isArray(e)).map(y.omit(u))||[])},g={description:d,content:{[s]:h}};return(r||s===f.raw)&&(g.required=!0),g},ve=e=>Object.entries(e).reduce((e,[t,n])=>{if(!n)return e;if(typeof n==`string`)return e.concat({name:t,description:n});let{url:r,...i}=n,a={...i,name:t};return r&&(a.externalDocs={...a.externalDocs,url:r}),e.concat(a)},[]),ye=(e,t=50)=>!e||e.length<=t?e:e.slice(0,Math.max(1,t||0)-1)+`…`,be=e=>e.length?e.slice():void 0;export{me as a,Q as c,P as d,ye as f,A as h,ce as i,ae as l,D as m,ge as n,he as o,k as p,oe as r,ve as s,_e as t,be as u};
1
+ import{$ as e,F as t,G as n,I as r,J as i,K as a,N as o,Q as s,R as c,W as l,X as u,j as d,nt as f,q as p,r as m,w as h,x as g,y as _}from"./routing-walker-DwbmnLCt.js";import{z as v}from"zod";import*as y from"ramda";import{isReferenceObject as b,isSchemaObject as x}from"openapi3-ts/oas32";const S=e=>e.type===`object`,C=y.mergeDeepWith((e,t)=>{if(Array.isArray(e)&&Array.isArray(t))return y.concat(e,t);if(e===t)return t;throw Error(`Can not flatten properties`,{cause:{a:e,b:t}})}),w=new Set([`type`,`properties`,`required`,`examples`,`description`,`additionalProperties`]),T=e=>{for(let t of Object.keys(e))if(!w.has(t))return!1;return!0},E=y.pair(!0),ee=(e,t,n)=>!(`allOf`in e)||!e.allOf?[]:e.allOf.map(e=>{if(t===`throw`&&!(e.type===`object`&&T(e)))throw Error(`Can not merge`);return y.pair(n,e)}),te=e=>{let t=[];return e.anyOf&&t.push(...y.map(E,e.anyOf)),e.oneOf&&t.push(...y.map(E,e.oneOf)),t},ne=(e,t,n,r)=>{if(!a(e.propertyNames))return;let i=[];typeof e.propertyNames.const==`string`&&i.push(e.propertyNames.const),e.propertyNames.enum&&i.push(...e.propertyNames.enum.filter(e=>typeof e==`string`));let o={...Object(e.additionalProperties)};for(let e of i)t.properties[e]??=o;r||n.push(...i)},re=(e,t,n)=>{t.examples?.length&&(e.examples=n?y.concat(e.examples||[],t.examples):c(e.examples?.filter(a)||[],t.examples.filter(a),([e,t])=>y.mergeDeepRight(e,t)))},D=(e,t=`coerce`)=>{let n=[y.pair(!1,e)],r={type:`object`,properties:{}},i=[];for(let[e,a]of n)a.description&&(r.description??=a.description),n.push(...ee(a,t,e)),n.push(...te(a)),re(r,a,e),S(a)&&(n.push([e,{examples:O(a)}]),a.properties&&(r.properties=(t===`throw`?C:y.mergeDeepRight)(r.properties,a.properties),!e&&a.required&&i.push(...a.required)),ne(a,r,i,e));return i.length&&(r.required=[...new Set(i)]),r},O=e=>Object.entries(e.properties||{}).reduce((e,[t,n])=>{let{examples:r=[]}=a(n)?n:{};return c(e,r.map(y.objOf(t)),([e,t])=>({...e,...t}))},[]),k=`x-coerce`,A=(e,t)=>{if(e[`x-coerce`]===!0)return!0;if(e.anyOf)return e.anyOf.some(e=>A(e,t));if(e.oneOf)return e.oneOf.some(e=>A(e,t));if(e.allOf)return e.allOf.every(e=>A(e,t));if(e.type===void 0||e.type===`string`)return!0;if(t===`query`&&[`array`,`object`].includes(e.type)){let n=[e.items,e.prefixItems,e.additionalItems,Object.values(e.properties??{}),e.additionalProperties,e.propertyNames];for(let e of n){if(!a(e))continue;let n=Array.isArray(e)?e:[e];for(let e of n)if(a(e)&&!A(e,t))return!1}return!0}return!1};let j;const M=()=>j??=new Set(`a-im.accept.accept-additions.accept-charset.accept-datetime.accept-encoding.accept-features.accept-language.accept-signature.access-control.access-control-request-headers.access-control-request-method.alpn.alt-used.amp-cache-transform.apply-to-redirect-ref.authorization.available-dictionary.c-ext.c-man.c-opt.c-pep.c-pep-info.cache-control.cal-managed-id.caldav-timezones.capsule-protocol.cdn-loop.cert-not-after.cert-not-before.client-cert.client-cert-chain.close.cmcd-object.cmcd-request.cmcd-session.cmcd-status.cmsd-dynamic.cmsd-static.concealed-auth-export.configuration-context.connection.content-digest.content-disposition.content-encoding.content-id.content-language.content-length.content-location.content-md5.content-range.content-script-type.content-type.cookie.cookie2.cta-common-access-token.dasl.date.dav.default-style.delta-base.deprecation.depth.derived-from.destination.detached-jws.dictionary-id.differential-id.digest.dpop.early-data.ediint-features.expect.expect-ct.ext.forwarded.from.getprofile.hobareg.host.http2-settings.if.if-match.if-modified-since.if-none-match.if-range.if-schedule-tag-match.if-unmodified-since.im.include-referred-token-binding-id.incremental.isolation.keep-alive.label.last-event-id.link.link-template.lock-token.man.max-forwards.memento-datetime.meter.method-check.method-check-expires.mime-version.negotiate.odata-entityid.odata-isolation.odata-maxversion.odata-version.opt.ordering-type.origin.origin-agent-cluster.oscore.oslc-core-version.overwrite.pep.pep-info.permissions-policy.pics-label.ping-from.ping-to.position.pragma.prefer.preference-applied.priority.profileobject.protocol.protocol-info.protocol-query.protocol-request.proxy-authorization.proxy-features.proxy-instruction.range.redirect-ref.referer.referer-root.referrer-policy.repeatability-client-id.repeatability-first-sent.repeatability-request-id.repeatability-result.replay-nonce.reporting-endpoints.repr-digest.safe.schedule-reply.schedule-tag.sec-fetch-storage-access.sec-gpc.sec-purpose.sec-token-binding.sec-websocket-extensions.sec-websocket-key.sec-websocket-protocol.sec-websocket-version.security-scheme.signature.signature-input.slug.soapaction.status-uri.sunset.surrogate-capability.tcn.te.timeout.topic.traceparent.tracestate.trailer.transfer-encoding.ttl.upgrade.urgency.uri.user-agent.variant-vary.via.want-content-digest.want-digest.want-repr-digest.want-unencoded-digest.warning.x-content-type-options.x-frame-options`.split(`.`)),N={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},P=e=>e.replace(u,e=>`{${e.slice(1)}}`),F=({},e)=>{if(e.isResponse)throw new h(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},I=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),L=({zodSchema:e,jsonSchema:t})=>{if(!p(e,`union`)||!(`discriminator`in e._zod.def))return t;let n=e._zod.def.discriminator;return{...t,discriminator:t.discriminator??{propertyName:n}}},R=y.tryCatch(({jsonSchema:e})=>{if(!e.allOf)throw`no allOf`;return D(e,`throw`)},(e,{jsonSchema:t})=>t),z=({jsonSchema:e})=>{if(!e.anyOf||!e.anyOf.length)return e;let t=e.anyOf[0];return Object.assign(t,{type:K(t.type)})},B=e=>e,V=({jsonSchema:e},t)=>{if(t.isResponse)throw new h(`Please use ez.dateOut() for output.`,t);return e},H=({jsonSchema:e},t)=>{if(!t.isResponse)throw new h(`Please use ez.dateIn() for input.`,t);return e},U=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),W=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,G=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return N?.[t]},K=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],ie=({zodSchema:e,jsonSchema:t},r)=>{let i=e._zod.def[r.isResponse?`out`:`in`],a=e._zod.def[r.isResponse?`in`:`out`];if(!p(i,`transform`))return t;let o=B(Z(a,{ctx:r}));if(x(o))if(r.isResponse){let e=n(i,G(o));if(e&&[`number`,`string`,`boolean`].includes(e))return{...t,type:e}}else{let{type:e,...t}=o;return{...t,format:`${t.format||e} (preprocessed)`}}return t},q=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!a(t.properties.raw)?e:t.properties.raw},J=e=>e.length?y.fromPairs(y.zip(y.times(e=>`example${e+1}`,e.length),y.map(y.objOf(`dataValue`),e))):void 0,Y=(e,t)=>t?.has(e)||e.startsWith(`x-`)||M().has(e),ae=({method:e,path:t,security:n,inputSources:r,isHeader:i})=>{let a=new Set(l(t)),o=r.includes(`query`),s=r.includes(`params`),c=r.includes(`headers`),u=r.includes(`cookies`)||r.includes(`signedCookies`),d;c&&n&&(d=m(n,`header`));let f;return u&&n&&(f=m(n,`cookie`)),{pathParams:a,getLocation:n=>{if(s&&a.has(n)&&a.delete(n))return`path`;if(u&&f?.has(n))return`cookie`;if(c&&(i?.(n,e,t)??Y(n,d)))return`header`;if(o&&e!==`query`)return`query`},isQueryEnabled:o}},oe=({path:e,method:t,flatRequest:n,makeRef:r,composition:o,getLocation:s,description:c=`${t.toUpperCase()} ${e} Parameter`})=>{let l=[];for(let[e,t]of Object.entries(n.properties)){if(!a(t))continue;let u=s(e);if(!u)continue;let d=B(t),f=o===`components`?r(t.id||JSON.stringify(t),d,t.id||i(c,e)):d;l.push({name:e,in:u,deprecated:t.deprecated,required:n.required?.includes(e)||u===`path`,description:d.description||c,schema:f,examples:J(x(d)&&d.examples?.length?d.examples:y.pluck(e,n.examples?.filter(y.both(a,y.has(e)))||[]))})}return l},X={nullable:z,union:L,bigint:U,intersection:R,tuple:W,pipe:ie,[o]:V,[d]:H,[g]:F,[_]:q,[t]:I},se=(e,t,n)=>{let r=[e,t],i=e=>/schema\d+$/.test(e)?void 0:e;for(let e=0;e<r.length;e++){let a=r[e];if(y.is(Object,a)){if(b(a)&&!a.$ref.startsWith(`#/components`)){let e=a.$ref.split(`/`).pop(),r=t[e];if(r){let t=r.id||i(e);a.$ref=n.makeRef(t||r,B(r),t).$ref}continue}r.push(...y.values(a))}y.is(Array,a)&&r.push(...y.values(a))}return e},Z=(e,{ctx:t,rules:n=X})=>{let{$defs:i={},properties:o={}}=v.toJSONSchema(v.object({subject:e}),{unrepresentable:`any`,io:t.isResponse?`output`:`input`,override:e=>{let i=v.globalRegistry.get(e.zodSchema)?.id;if(i){let n=t.seenIds.get(i);if(n&&n!==e.zodSchema)throw new h(`The meta id "${i}" is used by two different schemas. Please make the ids unique or reuse the same schema instance.`,t);t.seenIds.set(i,e.zodSchema)}let a=r(e.zodSchema),o=n[a&&a in n?a:e.zodSchema._zod.def.type];if(o){let n={...o(e,t)};for(let t in e.jsonSchema)delete e.jsonSchema[t];Object.assign(e.jsonSchema,n)}}});return se(a(o.subject)?o.subject:{},i,t)},Q=(e,t)=>{if(b(e))return[e,!1];let n=!1,r=y.map(e=>{let[r,i]=Q(e,t);return n||=i,r}),i=y.omit(t),a={properties:i,examples:y.map(i),required:y.without(t),allOf:r,oneOf:r,anyOf:r},o=y.evolve(a,e);return[o,n||!!o.required?.length]},ce=({method:t,path:n,schema:r,mimeTypes:a,variant:o,makeRef:c,composition:l,hasMultipleStatusCodes:u,statusCode:d,brandHandling:p,seenIds:m,description:h=`${t.toUpperCase()} ${n} ${e(o)} response ${u?d:``}`.trim()})=>{if(!s(t,a))return{description:h};let g=B(Z(r,{rules:{...p,...X},ctx:{isResponse:!0,makeRef:c,path:n,method:t,seenIds:m}})),_=[];x(g)&&g.examples&&(_.push(...g.examples),delete g.examples);let v=l===`components`?c(r,g,i(h)):g;return{description:h,content:y.fromPairs(a.map(e=>[e,{[e===f.sse?`itemSchema`:`schema`]:v,examples:J(_)}]))}},le=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},ue=({name:e},t)=>{let n={type:`apiKey`,in:`query`,name:e};return t?.includes(`body`)&&(t?.includes(`query`)?(n[`x-in-alternative`]=`body`,n.description=`${e} CAN also be supplied within the request body`):(n[`x-in-actual`]=`body`,n.description=`${e} MUST be supplied within the request body instead of query`)),n},de=({name:e})=>({type:`apiKey`,in:`header`,name:e}),fe=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),pe=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),$=({flows:e={},oauth2MetadataUrl:t})=>({type:`oauth2`,flows:y.map(e=>({...e,scopes:e.scopes||{}}),y.reject(y.isNil,e)),oauth2MetadataUrl:t}),me=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?le(e):e.type===`input`?ue(e,t):e.type===`header`?de(e):e.type===`cookie`?fe(e):e.type===`openid`?pe(e):$(e);return e.map(e=>e.map(({deprecated:e,...t})=>({...n(t),deprecated:e})))},he=Set.prototype.has.bind(new Set([`oauth2`,`openIdConnect`])),ge=(e,t,n)=>{let r=Array.from(t);return e.map(e=>{let t={};for(let i of e){let e=n(i);t[e]=he(i.type)?r:[]}return t})},_e=({schema:e,brandHandling:t,makeRef:n,path:r,method:i,seenIds:a})=>Z(e,{rules:{...t,...X},ctx:{isResponse:!1,makeRef:n,path:r,method:i,seenIds:a}}),ve=({method:e,path:t,bodyJsonSchema:n,hasRequiredBodyProps:r,flatRequest:o,mimeType:s,makeRef:c,composition:l,paramNames:u,description:d=`${e.toUpperCase()} ${t} Request body`})=>{let p=B(n),m=[];x(p)&&p.examples&&(m.push(...p.examples),delete p.examples);let h={schema:l===`components`?c(JSON.stringify(p),p,i(d)):p,examples:J(m.length?m:o.examples?.filter(e=>a(e)&&!Array.isArray(e)).map(y.omit(u))||[])},g={description:d,content:{[s]:h}};return(r||s===f.raw)&&(g.required=!0),g},ye=e=>Object.entries(e).reduce((e,[t,n])=>{if(!n)return e;if(typeof n==`string`)return e.concat({name:t,description:n});let{url:r,...i}=n,a={...i,name:t};return r&&(a.externalDocs={...a.externalDocs,url:r}),e.concat(a)},[]),be=(e,t=50)=>!e||e.length<=t?e:e.slice(0,Math.max(1,t||0)-1)+`…`,xe=e=>{let t=Array.from(e);return t.length?t:void 0};export{me as a,Q as c,P as d,be as f,A as h,ce as i,ae as l,D as m,_e as n,ge as o,k as p,oe as r,ye as s,ve as t,xe as u};
@@ -1,4 +1,4 @@
1
- import { M as ResponseVariant, g as CommonConfig, t as Routing } from "./routing-uoFmENK3.js";
1
+ import { M as ResponseVariant, g as CommonConfig, t as Routing } from "./routing-BAxxZ1xA.js";
2
2
  import {
3
3
  c as IsHeader,
4
4
  l as depictTags,
@@ -6,7 +6,7 @@ import {
6
6
  s as Depicter,
7
7
  t as DocumentationError,
8
8
  u as trimSummary,
9
- } from "./errors-BoYRbAGq.js";
9
+ } from "./errors-D9O6qgel.js";
10
10
  import { InfoObject, OpenApiBuilder, ServerObject } from "openapi3-ts/oas32";
11
11
  type Component = `${ResponseVariant}Response` | "requestParameter" | "requestBody";
12
12
  /** @desc user defined function that creates a component description from its properties */
@@ -1 +1 @@
1
- import{H as e,J as t,Y as n,i as r,n as i,nt as a,p as o,t as s,w as c}from"./routing-walker-CcgJ8aiU.js";import{a as l,c as u,d,f,i as p,l as m,m as h,n as g,o as _,r as v,s as y,t as b,u as x}from"./documentation-helpers-DBaBYdUT.js";import"zod";import*as S from"ramda";import{OpenApiBuilder as C}from"openapi3-ts/oas32";const w=({description:e,summary:t=e,trim:n})=>n(t);var T=class extends C{#e=new Map;#t=new Map;#n=new Map;#r=new Map;#i(e,t,n){let r=this.#n.get(e);if(!r){let t=+!n;do r=`${n??`Schema`}${t?this.#n.size+t:``}`,t++;while(this.rootDoc.components?.schemas?.[r]);this.#n.set(e,r)}return this.addSchema(r,t),{$ref:`#/components/schemas/${r}`}}#a(e,n,r){let i=r||t(n,e),a=this.#t.get(i);if(a===void 0)return this.#t.set(i,1),i;if(r)throw new c(`Duplicated operationId: "${r}"`,{method:n,isResponse:!1,path:e});return a++,this.#t.set(i,a),`${i}${a}`}#o(e){let t=JSON.stringify(e);for(let e in this.rootDoc.components?.securitySchemes||{})if(t===JSON.stringify(this.rootDoc.components?.securitySchemes?.[e]))return e;let n=(this.#e.get(e.type)||0)+1;return this.#e.set(e.type,n),`${e.type.toUpperCase()}_${n}`}#s({tags:e,server:t,info:n={title:`Generated by Express Zod API`,version:`0.0.0`}}){if(this.addInfo(n),e&&(this.rootDoc.tags=y(e)),t)for(let e of Array.isArray(t)?t:[t])this.addServer(typeof e==`string`?{url:e}:e)}#c(e,t){if(e===`head`||!t.includes(`:`))return;let r=n(t),i=this.#r.get(r);if(i!==void 0&&i!==t)throw new c(`Path has a duplicate: the normalized path "${r}" is already registered with different parameter names at "${i}"`,{method:e,path:t,isResponse:!1});i===void 0&&this.#r.set(r,t)}#l({config:t,descriptions:n,brandHandling:i,isHeader:s,summarizer:y=w,composition:C=`inline`}){let T={composition:C,brandHandling:i,makeRef:this.#i.bind(this),seenIds:new Map};return(i,C,w)=>{this.#c(i,C);let E={...T,path:C,method:i,endpoint:w},{description:D,summary:O,scopes:k,inputSchema:A,security:j}=w,M=e(i,t.inputSources),{pathParams:N,getLocation:P}=m({method:i,path:C,security:j,inputSources:M,isHeader:s}),F=this.#a(C,i,w.getOperationId(i)),I=g({...E,schema:A}),L=h(I),R=v({...E,getLocation:P,flatRequest:L,description:n?.requestParameter?.({method:i,path:C,operationId:F})});if(N.size)throw new c(`The input schema is missing the path parameter "${[...N][0]}"`,{method:i,path:C,isResponse:!1});let z={};for(let e of o){let t=w.getResponses(e);for(let{mimeTypes:r,schema:a,statusCodes:o}of t)for(let s of o)z[s]=p({...E,variant:e,schema:a,mimeTypes:r,statusCode:s,hasMultipleStatusCodes:t.length>1||o.length>1,description:n?.[`${e}Response`]?.({method:i,path:C,operationId:F,statusCode:s})})}let B;if(M.includes(`body`)){let e=S.pluck(`name`,R),[t,r]=u(I,e);B=b({...E,bodyJsonSchema:t,hasRequiredBodyProps:r,flatRequest:L,paramNames:e,mimeType:a[w.getProbableRequestType(i)],description:n?.requestBody?.({method:i,path:C,operationId:F})})}let V=_(l(r(j),M),k,e=>{let t=this.#o(e);return this.addSecurityScheme(t,e),t}),H={operationId:F,summary:y({summary:O,description:D,trim:f}),description:D,deprecated:w.isDeprecated||void 0,tags:x(w.tags),parameters:x(R),requestBody:B,security:x(V),responses:z};this.addPath(d(C),{[i]:H})}}constructor({hasHeadMethod:e=!0,...t}){super(),this.#s(t);let n=this.#l(t),r=e?i(n):n;s({...t,onEndpoint:r})}};export{T as Documentation,c as DocumentationError};
1
+ import{H as e,J as t,Y as n,i as r,n as i,nt as a,p as o,t as s,w as c}from"./routing-walker-DwbmnLCt.js";import{a as l,c as u,d,f,i as p,l as m,m as h,n as g,o as _,r as v,s as y,t as b,u as x}from"./documentation-helpers-at11Rk61.js";import"zod";import*as S from"ramda";import{OpenApiBuilder as C}from"openapi3-ts/oas32";const w=({description:e,summary:t=e,trim:n})=>n(t);var T=class extends C{#e=new Map;#t=new Map;#n=new Map;#r=new Map;#i(e,t,n){let r=this.#n.get(e);if(!r){let t=+!n;do r=`${n??`Schema`}${t?this.#n.size+t:``}`,t++;while(this.rootDoc.components?.schemas?.[r]);this.#n.set(e,r)}return this.addSchema(r,t),{$ref:`#/components/schemas/${r}`}}#a(e,n,r){let i=r||t(n,e),a=this.#t.get(i);if(a===void 0)return this.#t.set(i,1),i;if(r)throw new c(`Duplicated operationId: "${r}"`,{method:n,isResponse:!1,path:e});return a++,this.#t.set(i,a),`${i}${a}`}#o(e){let t=JSON.stringify(e);for(let e in this.rootDoc.components?.securitySchemes||{})if(t===JSON.stringify(this.rootDoc.components?.securitySchemes?.[e]))return e;let n=(this.#e.get(e.type)||0)+1;return this.#e.set(e.type,n),`${e.type.toUpperCase()}_${n}`}#s({tags:e,server:t,info:n={title:`Generated by Express Zod API`,version:`0.0.0`}}){if(this.addInfo(n),e&&(this.rootDoc.tags=y(e)),t)for(let e of Array.isArray(t)?t:[t])this.addServer(typeof e==`string`?{url:e}:e)}#c(e,t){if(e===`head`||!t.includes(`:`))return;let r=n(t),i=this.#r.get(r);if(i!==void 0&&i!==t)throw new c(`Path has a duplicate: the normalized path "${r}" is already registered with different parameter names at "${i}"`,{method:e,path:t,isResponse:!1});i===void 0&&this.#r.set(r,t)}#l({config:t,descriptions:n,brandHandling:i,isHeader:s,summarizer:y=w,composition:C=`inline`}){let T={composition:C,brandHandling:i,makeRef:this.#i.bind(this),seenIds:new Map};return(i,C,w)=>{this.#c(i,C);let E={...T,path:C,method:i,endpoint:w},{description:D,summary:O,scopes:k,inputSchema:A,security:j}=w,M=e(i,t.inputSources),{pathParams:N,getLocation:P}=m({method:i,path:C,security:j,inputSources:M,isHeader:s}),F=this.#a(C,i,w.getOperationId(i)),I=g({...E,schema:A}),L=h(I),R=v({...E,getLocation:P,flatRequest:L,description:n?.requestParameter?.({method:i,path:C,operationId:F})});if(N.size)throw new c(`The input schema is missing the path parameter "${[...N][0]}"`,{method:i,path:C,isResponse:!1});let z={};for(let e of o){let t=w.getResponses(e);for(let{mimeTypes:r,schema:a,statusCodes:o}of t)for(let s of o)z[s]=p({...E,variant:e,schema:a,mimeTypes:r,statusCode:s,hasMultipleStatusCodes:t.length>1||o.length>1,description:n?.[`${e}Response`]?.({method:i,path:C,operationId:F,statusCode:s})})}let B;if(M.includes(`body`)){let e=S.pluck(`name`,R),[t,r]=u(I,e);B=b({...E,bodyJsonSchema:t,hasRequiredBodyProps:r,flatRequest:L,paramNames:e,mimeType:a[w.getProbableRequestType(i)],description:n?.requestBody?.({method:i,path:C,operationId:F})})}let V=_(l(r(j),M),k,e=>{let t=this.#o(e);return this.addSecurityScheme(t,e),t}),H={operationId:F,summary:y({summary:O,description:D,trim:f}),description:D,deprecated:w.isDeprecated||void 0,tags:x(w.tags),parameters:x(R),requestBody:B,security:x(V),responses:z};this.addPath(d(C),{[i]:H})}}constructor({hasHeadMethod:e=!0,...t}){super(),this.#s(t);let n=this.#l(t),r=e?i(n):n;s({...t,onEndpoint:r})}};export{T as Documentation,c as DocumentationError};
@@ -1,4 +1,4 @@
1
- import { D as ClientMethod, O as Method, f as Tag } from "./routing-uoFmENK3.js";
1
+ import { D as ClientMethod, O as Method, f as Tag } from "./routing-BAxxZ1xA.js";
2
2
  import { z } from "zod";
3
3
  import { ReferenceObject, SchemaObjectValue, TagObject } from "openapi3-ts/oas32";
4
4
  interface ReqResCommons {
package/dist/index.d.ts CHANGED
@@ -31,14 +31,14 @@ import {
31
31
  w as Extension,
32
32
  x as arrayResultHandler,
33
33
  y as AbstractResultHandler,
34
- } from "./routing-uoFmENK3.js";
34
+ } from "./routing-BAxxZ1xA.js";
35
35
  import {
36
36
  a as RoutingError,
37
37
  i as OutputValidationError,
38
38
  n as InputValidationError,
39
39
  r as MissingPeerError,
40
40
  t as DocumentationError,
41
- } from "./errors-BoYRbAGq.js";
41
+ } from "./errors-D9O6qgel.js";
42
42
  import { z } from "zod";
43
43
  import express, { CookieOptions, Request, Response } from "express";
44
44
  import http from "node:http";
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import{A as e,B as t,C as n,D as r,E as i,H as a,K as o,L as s,M as c,O as l,P as u,S as d,T as f,U as p,V as ee,Z as m,_ as h,a as te,b as ne,c as g,d as re,f as ie,g as ae,h as _,k as oe,l as v,m as y,nt as b,o as se,p as ce,s as x,t as le,tt as S,u as C,w as ue,z as de}from"./routing-walker-CcgJ8aiU.js";import{t as w}from"./peer-helpers-BQlC55XO.js";import{h as fe,l as pe,m as me,p as he}from"./documentation-helpers-DBaBYdUT.js";import{globalRegistry as T,z as E}from"zod";import*as ge from"ramda";import D,{isHttpError as _e}from"http-errors";import ve,{blue as ye,cyanBright as be,green as xe,hex as O,italic as Se,red as Ce,whiteBright as k}from"ansis";import{inspect as we}from"node:util";import{performance as Te}from"node:perf_hooks";import A from"express";import Ee from"node:http";import De from"node:https";import{setInterval as Oe}from"node:timers/promises";import{createRequest as ke,createResponse as Ae}from"node-mocks-http";function je(e){return e}const Me=(e,t)=>e&&t?e.and(t):e||t,Ne=(e,t)=>e?e.and(t):t;var Pe=class e{#e;constructor(e){this.#e=e}async execute(...n){try{return await this.#e(...n)}catch(r){let{response:i,logger:a,error:o}=n[0],s=new l(t(r),o||void 0);e.lastResort({response:i,logger:a,error:s})}}static lastResort({error:e,logger:t,response:n}){t.error(`Result handler failure`,e);let r=g(D(500,`An error occurred while serving the result: ${e.message}.`+(e.handled?`\nOriginal error: ${e.handled.message}.`:``),{expose:_e(e.cause)?e.cause.expose:!1}));n.status(500).type(`text/plain`).end(r)}},j=class extends Pe{#e;#t;constructor(e){super(e.handler),this.#e=e.positive,this.#t=e.negative}getPositiveResponse(e){return C(this.#e,{variant:`positive`,args:[e]})}getNegativeResponse(){return C(this.#t,{variant:`negative`,args:[]})}};const M=E.object({status:E.literal(`error`),error:E.object({message:E.string()})});T.add(M,{examples:[{status:`error`,error:{message:`Sample error message`}}]});const N=new j({positive:e=>{let t=E.object({status:E.literal(`success`),data:e}),n=s(e);return n.length&&T.add(t,{examples:n.map(e=>({status:`success`,data:e}))}),t},negative:M,handler:({error:e,input:t,output:n,request:r,response:i,logger:a})=>{if(e){let n=x(e);v(n,a,r,t),i.status(n.statusCode).set(n.headers).json({status:`error`,error:{message:g(n)}});return}i.status(ie.positive).json({status:`success`,data:n})}}),P=E.string();T.add(P,{examples:[`Sample error message`]});const F=new j({positive:e=>{let t=e instanceof E.ZodObject&&`items`in e.shape&&e.shape.items instanceof E.ZodArray?e.shape.items:E.array(E.any());if(s(t).length)return t;let n=s(e).filter(e=>o(e)&&`items`in e&&Array.isArray(e.items)).map(e=>e.items);if(n?.length){let e=t.meta();T.remove(t).add(t,{...e,examples:n})}return t},negative:{schema:P,mimeType:`text/plain`},handler:({response:e,output:t,error:n,logger:r,request:i,input:a})=>{if(n){let t=x(n);v(t,r,i,a),e.status(t.statusCode).type(`text/plain`).send(g(t));return}if(`items`in t&&Array.isArray(t.items)){e.status(ie.positive).json(t.items);return}throw Error(`Property 'items' is missing in the endpoint output`)}}),I=e=>{let t=[];return e.scope&&t.push(e.scope),e.noStore&&t.push(`no-store`),e.noCache&&t.push(`no-cache`),e.maxAge!==void 0&&t.push(`max-age=${e.maxAge}`),e.sMaxAge!==void 0&&t.push(`s-maxage=${e.sMaxAge}`),e.mustRevalidate&&t.push(`must-revalidate`),e.proxyRevalidate&&t.push(`proxy-revalidate`),e.mustUnderstand&&t.push(`must-understand`),e.immutable&&t.push(`immutable`),e.noTransform&&t.push(`no-transform`),e.staleWhileRevalidate!==void 0&&t.push(`stale-while-revalidate=${e.staleWhileRevalidate}`),e.staleIfError!==void 0&&t.push(`stale-if-error=${e.staleIfError}`),t.join(`, `)},Fe={"max-age":`maxAge`,"max-stale":`maxStale`,"min-fresh":`minFresh`,"stale-if-error":`staleIfError`},Ie={"no-cache":`noCache`,"no-store":`noStore`,"no-transform":`noTransform`,"only-if-cached":`onlyIfCached`},Le=e=>{if(!e)return;let t={};for(let n of e.toLowerCase().split(`,`)){let[e,r]=n.split(`=`),i=Fe[e.trim()];if(i){let e=parseInt(r?.trim()??``,10);isNaN(e)||(t[i]=e);continue}let a=Ie[e.trim()];a&&(t[a]=!0)}return t},L=e=>new _({handler:async({request:t,response:n})=>(e&&n.setHeader(`Cache-Control`,I(e)),{get ifNoneMatch(){let e=t.headers[`if-none-match`];if(!e)return;let n=e.trim();return n===`*`?n:n.split(`,`).map(e=>e.trim().replace(/^(?:W\/)?"/,``).replace(/"$/,``))},get ifModifiedSince(){let e=t.headers[`if-modified-since`];if(!e)return;let n=new Date(e);return isNaN(n.getTime())?void 0:n},get cacheControl(){return Le(t.headers[`cache-control`])},addCachePolicy:t=>{n.setHeader(`Cache-Control`,I({...e,...t}))},setETag:e=>{n.setHeader(`ETag`,e.startsWith(`"`)?e:`"${e}"`)},setLastModified:e=>{n.setHeader(`Last-Modified`,e.toUTCString())},setVary:(...e)=>{n.setHeader(`Vary`,e.join(`, `))},setExpires:e=>{n.setHeader(`Expires`,e.toUTCString())},clearSiteData:()=>{n.setHeader(`Clear-Site-Data`,`"cache"`)},notModified:()=>{n.status(304).end()}})}),R=e=>new _({handler:async({request:t,response:n})=>({getCookie:e=>t.signedCookies?.[e]??t.cookies?.[e],setCookie:(t,r,i)=>{n.cookie(t,r,{...e,...i})},clearCookie:(t,r)=>{n.clearCookie(t,{...e,...r})}})}),z=e=>{let t=w(`express-rate-limit`)({statusCode:429,...e,handler:(e,t,n,r)=>{n(D(r.statusCode,r.message))}}),{getKey:n,resetKey:r}=t,i={getKey:n,resetKey:r};return new y(t,{statusCode:e?.statusCode,provider:t=>({rateLimit:{...i,...t[e?.requestPropertyName??`rateLimit`]}})})};var B=class e{resultHandler;schema=void 0;statusCodes=new Set;middlewares=[];constructor(e){this.resultHandler=e}#e(t){let n=new e(this.resultHandler);return n.middlewares=this.middlewares.concat(t),n.schema=Me(this.schema,t.schema),n.statusCodes=this.statusCodes.union(t.statusCodes),n}addMiddleware(e){return this.#e(e instanceof _?e:new _(e))}useCookies(...e){return this.#e(R(...e))}useCache(...e){return this.#e(L(...e))}useRateLimit(...e){return this.#e(z(...e))}use=this.addExpressMiddleware;addExpressMiddleware(...e){return this.#e(new y(...e))}addContext(e){return this.#e(new _({handler:({ctx:t})=>e(t)}))}build({input:e=de,output:t,operationId:n,scope:r,tag:i,method:a,statusCode:o,...s}){let{middlewares:c,resultHandler:l}=this,u=new ae(typeof a==`string`?[a]:a),d=typeof n==`function`?n:e=>n&&`${n}${e===`head`?`__HEAD`:``}`,f=typeof r==`string`?[r]:r||[],p=typeof i==`string`?[i]:i||[];return new se({...s,middlewares:c,outputSchema:t,resultHandler:l,scopes:f,tags:p,methods:u,getOperationId:d,inputSchema:Ne(this.schema,e),statusCodes:this.statusCodes.union(new Set(typeof o==`number`?[o]:o||[]))})}buildVoid({handler:e,...t}){return this.build({...t,output:de,handler:async t=>(await e(t),{})})}};const Re=new B(N),ze=new B(F),V={debug:ye,info:xe,warn:O(`#FFA500`),error:Ce,ctx:be},H={debug:10,info:20,warn:30,error:40},Be=e=>o(e)&&Object.keys(H).some(t=>t in e),Ve=e=>e in H,He=(e,t)=>H[e]<H[t],U=ge.memoizeWith((e,t)=>`${e}${t}`,(e,t=0)=>Intl.NumberFormat(void 0,{useGrouping:!1,minimumFractionDigits:0,maximumFractionDigits:t,style:`unit`,unitDisplay:`long`,unit:e})),Ue=e=>e<1e-6?U(`nanosecond`,3).format(e/1e-6):e<.001?U(`nanosecond`).format(e/1e-6):e<1?U(`microsecond`).format(e/.001):e<1e3?U(`millisecond`).format(e):e<6e4?U(`second`,2).format(e/1e3):U(`minute`,2).format(e/6e4);var W=class e{config;constructor({color:e=ve.isSupported(),level:t=m.isProduction?`warn`:`debug`,depth:n=2,ctx:r={}}={}){this.config={color:e,level:t,depth:n,ctx:r}}format(e){let{depth:t,color:n,level:r}=this.config;return we(e,{depth:t,colors:n,breakLength:r===`debug`?80:1/0,compact:r!==`debug`||3})}print(e,t,n){let{level:r,ctx:{requestId:i,...a},color:o}=this.config;if(r===`silent`||He(e,r))return;let s=[new Date().toISOString()];i&&s.push(o?V.ctx(i):i),s.push(o?`${V[e](e)}:`:`${e}:`,t),n!==void 0&&s.push(this.format(n)),Object.keys(a).length>0&&s.push(this.format(a)),console.log(s.join(` `))}debug(e,t){this.print(`debug`,e,t)}info(e,t){this.print(`info`,e,t)}warn(e,t){this.print(`warn`,e,t)}error(e,t){this.print(`error`,e,t)}child(t){return new e({...this.config,ctx:t})}get ctx(){return this.config.ctx}profile(e){let t=Te.now();return()=>{let n=Te.now()-t,{message:r,severity:i=`debug`,formatter:a=Ue}=typeof e==`object`?e:{message:e};this.print(typeof i==`function`?i(n):i,r,a(n))}}},We=class{logger;config;#e=new WeakMap;constructor(e,t){this.logger=e,this.config=t}#t(e,t,n){if(!e.isSchemaChecked){for(let e of[`input`,`output`]){let r=[E.toJSONSchema(t[`${e}Schema`],{unrepresentable:`any`})];for(let t of r){t.type&&t.type!==`object`&&this.logger.warn(`Endpoint ${e} schema is not object-based`,n);for(let e of[`allOf`,`oneOf`,`anyOf`])t[e]&&r.push(...t[e])}}if(t.getProbableRequestType()===`json`){let e=h(t.inputSchema,`input`);e&&this.logger.warn(`The final input schema of the endpoint contains an unsupported JSON payload type.`,{...n,reason:e})}for(let e of ce)for(let{mimeTypes:r,schema:i}of t.getResponses(e)){if(!r?.includes(b.json))continue;let t=h(i,`output`);t&&this.logger.warn(`The final ${e} response schema of the endpoint contains an unsupported JSON payload type.`,{...n,reason:t})}e.isSchemaChecked=!0}}#n(e,t,n,r,i){if(e.paths.has(r))return;let{pathParams:s,getLocation:c,isQueryEnabled:l}=pe({method:n,path:r,security:t.security,inputSources:a(n,this.config.inputSources)});if(!(s.size===0&&!l)){e.flat??=me(E.toJSONSchema(t.inputSchema,{unrepresentable:`any`,io:`input`,override:({zodSchema:e,jsonSchema:t})=>{(e._zod.traits.has(`$ZodPreprocess`)||`coerce`in e._zod.def&&e._zod.def.coerce)&&(t[he]=!0)}}));for(let[t,n]of Object.entries(e.flat.properties)){if(!o(n))continue;let r=c(t);(r===`path`||r===`query`)&&(r===`path`&&!e.flat.required?.includes(t)&&this.logger.warn(`The path parameter "${t}" is declared optional in the input schema, but path parameters are always required since Express matches the route only when the segment is present.`,{...i,name:t}),!fe(n,r)&&this.logger.warn(`The ${r} parameter "${t}" has a schema that most likely would not accept the parsed data, ${r===`path`?`since path parameters always arrive as strings`:`depending on the "queryParser" config option`}. Convert the parsed value from "z.string()" using ".transform()" method, or use "z.coerce" at least.`,{...i,name:t,jsonSchema:n}))}for(let e of s)this.logger.warn(`The input schema of the endpoint is most likely missing the parameter of the path it's assigned to.`,{...i,param:e});e.paths.add(r)}}check=(e,t,n)=>{let r=this.#e.get(n);r||(r={isSchemaChecked:!1,paths:new Set},this.#e.set(n,r)),this.#t(r,n,{method:e,path:t}),this.#n(r,n,e,t,{method:e,path:t})}};const G=e=>e.sort((e,t)=>S(t)-+S(e)||e.localeCompare(t)).join(`, `).toUpperCase(),Ge=e=>({method:t},n,r)=>{let i=G(e);n.set({Allow:i}),r(D(405,`${t} is not allowed`,{headers:{Allow:i}}))},Ke=({app:e,getLogger:t,config:n,routing:r})=>{let i=m.isProduction?void 0:new We(t(),n),a=new Map;return le({routing:r,config:n,onEndpoint:(e,t,r)=>{i?.check(e,t,r),a.has(t)||a.set(t,new Map(n.cors?[[`options`,r]]:[])),a.get(t)?.set(e,r)},onStatic:e.use.bind(e)}),a},K=({app:e,config:t,getLogger:n,...r})=>{let i=Ke({app:e,getLogger:n,config:t,...r}),a=new Map;for(let[r,o]of i){let i=Array.from(o.keys());i.includes(`get`)&&i.push(`head`);for(let[a,s]of o){let o=[];t.cors&&o.push((e,t,n)=>{t.set(`Access-Control-Allow-Methods`,G(i)),n()}),o.push(async(e,r)=>{let i=n(e);return s.execute({request:e,response:r,logger:i,config:t})}),e[a]?.(r,...o)}t.hintAllowedMethods!==!1&&a.set(r,Ge(i))}for(let[t,n]of a)e.all(t,n)},qe=e=>`_httpMessage`in e&&typeof e._httpMessage==`object`&&e._httpMessage!==null&&`headersSent`in e._httpMessage&&typeof e._httpMessage.headersSent==`boolean`&&`setHeader`in e._httpMessage&&typeof e._httpMessage.setHeader==`function`,Je=e=>`server`in e&&typeof e.server==`object`&&e.server!==null&&`close`in e.server&&typeof e.server.close==`function`,Ye=e=>`encrypted`in e&&typeof e.encrypted==`boolean`&&e.encrypted,Xe=({},e)=>void(!e.headersSent&&e.setHeader(`connection`,`close`)),Ze=e=>{let{promise:t,resolve:n,reject:r}=Promise.withResolvers();return e.close(e=>e?r(e):n()),t},Qe=({timeout:e=1e3,logger:t}={})=>{let n,r=new Set,i=new Set,a=e=>void i.delete(e),o=e=>a(e.destroy()),s=e=>void(qe(e)?!e._httpMessage.headersSent&&e._httpMessage.setHeader(`connection`,`close`):o(e)),c=e=>void(n?e.destroy():i.add(e.once(`close`,()=>a(e)).once(`error`,()=>o(e)))),l=async()=>{for(let e of r)e.on(`request`,Xe);t?.info(`Graceful shutdown`,{sockets:i.size,timeout:e});for(let e of i)(Ye(e)||Je(e))&&s(e);for await(let t of Oe(10,Date.now()))if(i.size===0||Date.now()-t>=e)break;for(let e of i)o(e);return Promise.allSettled(r.values().map(Ze))},u={sockets:i,add:(...e)=>{for(let t of e)if(!r.has(t)){r.add(t);for(let e of[`connection`,`secureConnection`])t.on(e,c)}return u},shutdown:()=>n??=l(),get isShuttingDown(){return!!n}};return u},q=Symbol.for(`express-zod-api`),$e=({errorHandler:e,getLogger:n})=>async(r,i,a,o)=>r?e.execute({error:t(r),request:i,response:a,input:null,output:null,ctx:{},logger:n(i)}):o(),et=({errorHandler:e,getLogger:t})=>async(n,r)=>{let i=D(404,`Can not ${n.method} ${n.path}`),a=t(n);await e.execute({request:n,response:r,logger:a,error:i,input:null,output:null,ctx:{}})},tt=e=>(t,{},n)=>{if(Object.values(t?.files||[]).flat().find(({truncated:e})=>e))return n(e);n()},nt=({config:e})=>{let t=w(`cookie-parser`),{secret:n,...r}={...typeof e.cookies==`object`&&e.cookies};return t(n,Object.keys(r).length?r:void 0)},J=e=>typeof e==`function`?e:({},e,t)=>{e.set({"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Headers":`content-type`}),t()},rt=e=>({log:t=>{/not eligible/i.test(t)||e.debug(t)}}),it=({getLogger:e,config:t})=>{let n=w(`express-fileupload`),{limitError:r,beforeUpload:i,...a}={...typeof t.upload==`object`&&t.upload},o=[];return o.push(async(t,r,o)=>{let s=e(t);return await i?.({request:t,logger:s}),n({debug:!0,...a,abortOnLimit:!1,parseNested:!0,logger:rt(s)})(t,r,o)}),r&&o.push(tt(r)),o},at=(e,{},t)=>{Buffer.isBuffer(e.body)&&(e.body={raw:e.body}),t()},ot=({logger:e,config:{childLoggerProvider:t,accessLogger:n=({method:e,path:t},n)=>n.debug(`${e}: ${t}`)}})=>async(r,i,a)=>{let o=await t?.({request:r,parent:e})||e;n?.(r,o),r.res&&(r.res.locals[q]={logger:o}),a()},st=e=>t=>t?.res?.locals[q]?.logger||e;let Y=!1;const ct=e=>{Y||(Y=!0,process.on(`deprecation`,({message:t,namespace:n,name:r,stack:i})=>e.warn(`${r} (${n}): ${t}`,i.split(`
2
- `).slice(1))))};let X,Z,Q;const lt=({servers:e,logger:t,options:{timeout:n,beforeExit:r,events:i=[`SIGINT`,`SIGTERM`]}})=>{X??=Qe({logger:t,timeout:n}),X.add(...e),r&&(Q??=new Set).add(r),Z??=async()=>{X?.isShuttingDown||(await X?.shutdown(),Q&&await Promise.allSettled(Q.values().map(async e=>e())),process.exit())};for(let e of i)process.listeners(e).includes(Z)||process.on(e,Z)},ut=e=>{if(e.columns<62)return;let t=Se(`for Angie`.padStart(52)),n=O(`#F5A9B8`),r=O(`#5BCEFA`),i=[r`8888888888${t}`,r`888`,r`888`,r`8888888 888 888 88888b. 888d888 .d88b. .d8888b .d8888b`,n`888 `Y8bd8P' 888 "88b 888P" d8P Y8b 88K 88K`,n`888 X88K 888 888 888 88888888 "Y8888b. "Y8888b.`,n`888 .d8""8b. 888 d88P 888 Y8b. X88 X88`,k`8888888888 888 888 88888P" 888 "Y8888 88888P' 88888P'`,k` 888`,k`8888888888P 888 888 d8888 8888888b. 8888888`,k` d88P 888 d88888 888 Y88b 888`,n` d88P 888 d88P888 888 888 888`,n` d88P .d88b. .d88888 d88P 888 888 d88P 888`,n` d88P d88""88b d88" 888 d88P 888 8888888P" 888`,r` d88P 888 888 888 888 d88P 888 888 888`,r` d88P Y88..88P Y88b 888 d8888888888 888 888`,r`d8888888888 "Y88P" "Y88888 d88P 888 888 8888888`];e.write(`
1
+ import{A as e,B as t,C as n,D as r,E as i,H as a,K as o,L as s,M as c,O as l,P as u,S as ee,T as d,U as f,V as te,Z as p,_ as m,a as ne,b as re,c as h,d as ie,f as g,g as _,h as v,k as ae,l as y,m as oe,nt as b,o as se,p as ce,s as x,t as le,tt as ue,u as S,w as de,z as C}from"./routing-walker-DwbmnLCt.js";import{t as w}from"./peer-helpers-CoetX8Sc.js";import{h as fe,l as pe,m as me,p as he}from"./documentation-helpers-at11Rk61.js";import{globalRegistry as T,z as E}from"zod";import*as ge from"ramda";import D,{isHttpError as _e}from"http-errors";import ve,{blue as ye,cyanBright as be,green as xe,hex as O,italic as Se,red as Ce,whiteBright as k}from"ansis";import{inspect as we}from"node:util";import{performance as A}from"node:perf_hooks";import j from"express";import Te from"node:http";import Ee from"node:https";import{setInterval as De}from"node:timers/promises";import{createRequest as Oe,createResponse as ke}from"node-mocks-http";function Ae(e){return e}const je=(e,t)=>e&&t?e.and(t):e||t,Me=(e,t)=>e?e.and(t):t;var Ne=class e{#e;constructor(e){this.#e=e}async execute(...n){try{return await this.#e(...n)}catch(r){let{response:i,logger:a,error:o}=n[0],s=new l(t(r),o||void 0);e.lastResort({response:i,logger:a,error:s})}}static lastResort({error:e,logger:t,response:n}){t.error(`Result handler failure`,e);let r=h(D(500,`An error occurred while serving the result: ${e.message}.`+(e.handled?`\nOriginal error: ${e.handled.message}.`:``),{expose:_e(e.cause)?e.cause.expose:!1}));n.status(500).type(`text/plain`).end(r)}},M=class extends Ne{#e;#t;constructor(e){super(e.handler),this.#e=e.positive,this.#t=e.negative}getPositiveResponse(e){return S(this.#e,{variant:`positive`,args:[e]})}getNegativeResponse(){return S(this.#t,{variant:`negative`,args:[]})}};const N=E.object({status:E.literal(`error`),error:E.object({message:E.string()})});T.add(N,{examples:[{status:`error`,error:{message:`Sample error message`}}]});const P=new M({positive:e=>{let t=E.object({status:E.literal(`success`),data:e}),n=s(e);return n.length&&T.add(t,{examples:n.map(e=>({status:`success`,data:e}))}),t},negative:N,handler:({error:e,input:t,output:n,request:r,response:i,logger:a})=>{if(e){let n=x(e);y(n,a,r,t),i.status(n.statusCode).set(n.headers).json({status:`error`,error:{message:h(n)}});return}i.status(g.positive).json({status:`success`,data:n})}}),F=E.string();T.add(F,{examples:[`Sample error message`]});const I=new M({positive:e=>{let t=e instanceof E.ZodObject&&`items`in e.shape&&e.shape.items instanceof E.ZodArray?e.shape.items:E.array(E.any());if(s(t).length)return t;let n=s(e).filter(e=>o(e)&&`items`in e&&Array.isArray(e.items)).map(e=>e.items);if(n?.length){let e=t.meta();T.remove(t).add(t,{...e,examples:n})}return t},negative:{schema:F,mimeType:`text/plain`},handler:({response:e,output:t,error:n,logger:r,request:i,input:a})=>{if(n){let t=x(n);y(t,r,i,a),e.status(t.statusCode).type(`text/plain`).send(h(t));return}if(`items`in t&&Array.isArray(t.items)){e.status(g.positive).json(t.items);return}throw Error(`Property 'items' is missing in the endpoint output`)}}),L=e=>{let t=[];return e.scope&&t.push(e.scope),e.noStore&&t.push(`no-store`),e.noCache&&t.push(`no-cache`),e.maxAge!==void 0&&t.push(`max-age=${e.maxAge}`),e.sMaxAge!==void 0&&t.push(`s-maxage=${e.sMaxAge}`),e.mustRevalidate&&t.push(`must-revalidate`),e.proxyRevalidate&&t.push(`proxy-revalidate`),e.mustUnderstand&&t.push(`must-understand`),e.immutable&&t.push(`immutable`),e.noTransform&&t.push(`no-transform`),e.staleWhileRevalidate!==void 0&&t.push(`stale-while-revalidate=${e.staleWhileRevalidate}`),e.staleIfError!==void 0&&t.push(`stale-if-error=${e.staleIfError}`),t.join(`, `)},Pe={"max-age":`maxAge`,"max-stale":`maxStale`,"min-fresh":`minFresh`,"stale-if-error":`staleIfError`},Fe={"no-cache":`noCache`,"no-store":`noStore`,"no-transform":`noTransform`,"only-if-cached":`onlyIfCached`},Ie=e=>{if(!e)return;let t={};for(let n of e.toLowerCase().split(`,`)){let[e,r]=n.split(`=`),i=Pe[e.trim()];if(i){let e=parseInt(r?.trim()??``,10);isNaN(e)||(t[i]=e);continue}let a=Fe[e.trim()];a&&(t[a]=!0)}return t},R=e=>new v({handler:async({request:t,response:n})=>(e&&n.setHeader(`Cache-Control`,L(e)),{get ifNoneMatch(){let e=t.headers[`if-none-match`];if(!e)return;let n=e.trim();return n===`*`?n:n.split(`,`).map(e=>e.trim().replace(/^(?:W\/)?"/,``).replace(/"$/,``))},get ifModifiedSince(){let e=t.headers[`if-modified-since`];if(!e)return;let n=new Date(e);return isNaN(n.getTime())?void 0:n},get cacheControl(){return Ie(t.headers[`cache-control`])},addCachePolicy:t=>{n.setHeader(`Cache-Control`,L({...e,...t}))},setETag:e=>{n.setHeader(`ETag`,e.startsWith(`"`)?e:`"${e}"`)},setLastModified:e=>{n.setHeader(`Last-Modified`,e.toUTCString())},setVary:(...e)=>{n.setHeader(`Vary`,e.join(`, `))},setExpires:e=>{n.setHeader(`Expires`,e.toUTCString())},clearSiteData:()=>{n.setHeader(`Clear-Site-Data`,`"cache"`)},notModified:()=>{n.status(304).end()}})}),z=e=>new v({handler:async({request:t,response:n})=>({getCookie:e=>t.signedCookies?.[e]??t.cookies?.[e],setCookie:(t,r,i)=>{n.cookie(t,r,{...e,...i})},clearCookie:(t,r)=>{n.clearCookie(t,{...e,...r})}})}),B=e=>{let t=w(`express-rate-limit`)({statusCode:429,...e,handler:(e,t,n,r)=>{n(D(r.statusCode,r.message))}}),{getKey:n,resetKey:r}=t,i={getKey:n,resetKey:r};return new oe(t,{statusCode:e?.statusCode,provider:t=>({rateLimit:{...i,...t[e?.requestPropertyName??`rateLimit`]}})})};var V=class e{resultHandler;schema=void 0;statusCodes=new Set;middlewares=[];constructor(e){this.resultHandler=e}#e(t){let n=new e(this.resultHandler);return n.middlewares=this.middlewares.concat(t),n.schema=je(this.schema,t.schema),n.statusCodes=this.statusCodes.union(t.statusCodes),n}addMiddleware(e){return this.#e(e instanceof v?e:new v(e))}useCookies(...e){return this.#e(z(...e))}useCache(...e){return this.#e(R(...e))}useRateLimit(...e){return this.#e(B(...e))}use=this.addExpressMiddleware;addExpressMiddleware(...e){return this.#e(new oe(...e))}addContext(e){return this.#e(new v({handler:({ctx:t})=>e(t)}))}build({input:e=C,output:t,operationId:n,scope:r,tag:i,method:a,statusCode:o,...s}){let{middlewares:c,resultHandler:l}=this,u=new _(typeof a==`string`?[a]:a),ee=typeof n==`function`?n:e=>n&&`${n}${e===`head`?`__HEAD`:``}`,d=new _(typeof r==`string`?[r]:r),f=new _(typeof i==`string`?[i]:i);return new se({...s,middlewares:c,outputSchema:t,resultHandler:l,scopes:d,tags:f,methods:u,getOperationId:ee,inputSchema:Me(this.schema,e),statusCodes:this.statusCodes.union(new Set(typeof o==`number`?[o]:o||[]))})}buildVoid({handler:e,...t}){return this.build({...t,output:C,handler:async t=>(await e(t),{})})}};const Le=new V(P),Re=new V(I),H={debug:ye,info:xe,warn:O(`#FFA500`),error:Ce,ctx:be},U={debug:10,info:20,warn:30,error:40},ze=e=>o(e)&&Object.keys(U).some(t=>t in e),Be=e=>e in U,Ve=(e,t)=>U[e]<U[t],W=ge.memoizeWith((e,t)=>`${e}${t}`,(e,t=0)=>Intl.NumberFormat(void 0,{useGrouping:!1,minimumFractionDigits:0,maximumFractionDigits:t,style:`unit`,unitDisplay:`long`,unit:e})),He=e=>e<1e-6?W(`nanosecond`,3).format(e/1e-6):e<.001?W(`nanosecond`).format(e/1e-6):e<1?W(`microsecond`).format(e/.001):e<1e3?W(`millisecond`).format(e):e<6e4?W(`second`,2).format(e/1e3):W(`minute`,2).format(e/6e4);var G=class e{config;constructor({color:e=ve.isSupported(),level:t=p.isProduction?`warn`:`debug`,depth:n=2,ctx:r={}}={}){this.config={color:e,level:t,depth:n,ctx:r}}format(e){let{depth:t,color:n,level:r}=this.config;return we(e,{depth:t,colors:n,breakLength:r===`debug`?80:1/0,compact:r!==`debug`||3})}print(e,t,n){let{level:r,ctx:{requestId:i,...a},color:o}=this.config;if(r===`silent`||Ve(e,r))return;let s=[new Date().toISOString()];i&&s.push(o?H.ctx(i):i),s.push(o?`${H[e](e)}:`:`${e}:`,t),n!==void 0&&s.push(this.format(n)),Object.keys(a).length>0&&s.push(this.format(a)),console.log(s.join(` `))}debug(e,t){this.print(`debug`,e,t)}info(e,t){this.print(`info`,e,t)}warn(e,t){this.print(`warn`,e,t)}error(e,t){this.print(`error`,e,t)}child(t){return new e({...this.config,ctx:t})}get ctx(){return this.config.ctx}profile(e){let t=A.now();return()=>{let n=A.now()-t,{message:r,severity:i=`debug`,formatter:a=He}=typeof e==`object`?e:{message:e};this.print(typeof i==`function`?i(n):i,r,a(n))}}},Ue=class{logger;config;#e=new WeakMap;constructor(e,t){this.logger=e,this.config=t}#t(e,t,n){if(!e.isSchemaChecked){for(let e of[`input`,`output`]){let r=[E.toJSONSchema(t[`${e}Schema`],{unrepresentable:`any`})];for(let t of r){t.type&&t.type!==`object`&&this.logger.warn(`Endpoint ${e} schema is not object-based`,n);for(let e of[`allOf`,`oneOf`,`anyOf`])t[e]&&r.push(...t[e])}}if(t.getProbableRequestType()===`json`){let e=m(t.inputSchema,`input`);e&&this.logger.warn(`The final input schema of the endpoint contains an unsupported JSON payload type.`,{...n,reason:e})}for(let e of ce)for(let{mimeTypes:r,schema:i}of t.getResponses(e)){if(!r?.includes(b.json))continue;let t=m(i,`output`);t&&this.logger.warn(`The final ${e} response schema of the endpoint contains an unsupported JSON payload type.`,{...n,reason:t})}e.isSchemaChecked=!0}}#n(e,t,n,r,i){if(e.paths.has(r))return;let{pathParams:s,getLocation:c,isQueryEnabled:l}=pe({method:n,path:r,security:t.security,inputSources:a(n,this.config.inputSources)});if(!(s.size===0&&!l)){e.flat??=me(E.toJSONSchema(t.inputSchema,{unrepresentable:`any`,io:`input`,override:({zodSchema:e,jsonSchema:t})=>{(e._zod.traits.has(`$ZodPreprocess`)||`coerce`in e._zod.def&&e._zod.def.coerce)&&(t[he]=!0)}}));for(let[t,n]of Object.entries(e.flat.properties)){if(!o(n))continue;let r=c(t);(r===`path`||r===`query`)&&(r===`path`&&!e.flat.required?.includes(t)&&this.logger.warn(`The path parameter "${t}" is declared optional in the input schema, but path parameters are always required since Express matches the route only when the segment is present.`,{...i,name:t}),!fe(n,r)&&this.logger.warn(`The ${r} parameter "${t}" has a schema that most likely would not accept the parsed data, ${r===`path`?`since path parameters always arrive as strings`:`depending on the "queryParser" config option`}. Convert the parsed value from "z.string()" using ".transform()" method, or use "z.coerce" at least.`,{...i,name:t,jsonSchema:n}))}for(let e of s)this.logger.warn(`The input schema of the endpoint is most likely missing the parameter of the path it's assigned to.`,{...i,param:e});e.paths.add(r)}}check=(e,t,n)=>{let r=this.#e.get(n);r||(r={isSchemaChecked:!1,paths:new Set},this.#e.set(n,r)),this.#t(r,n,{method:e,path:t}),this.#n(r,n,e,t,{method:e,path:t})}};const K=e=>e.sort((e,t)=>ue(t)-+ue(e)||e.localeCompare(t)).join(`, `).toUpperCase(),We=e=>({method:t},n,r)=>{let i=K(e);n.set({Allow:i}),r(D(405,`${t} is not allowed`,{headers:{Allow:i}}))},Ge=({app:e,getLogger:t,config:n,routing:r})=>{let i=p.isProduction?void 0:new Ue(t(),n),a=new Map;return le({routing:r,config:n,onEndpoint:(e,t,r)=>{i?.check(e,t,r),a.has(t)||a.set(t,new Map(n.cors?[[`options`,r]]:[])),a.get(t)?.set(e,r)},onStatic:e.use.bind(e)}),a},q=({app:e,config:t,getLogger:n,...r})=>{let i=Ge({app:e,getLogger:n,config:t,...r}),a=new Map;for(let[r,o]of i){let i=Array.from(o.keys());i.includes(`get`)&&i.push(`head`);for(let[a,s]of o){let o=[];t.cors&&o.push((e,t,n)=>{t.set(`Access-Control-Allow-Methods`,K(i)),n()}),o.push(async(e,r)=>{let i=n(e);return s.execute({request:e,response:r,logger:i,config:t})}),e[a]?.(r,...o)}t.hintAllowedMethods!==!1&&a.set(r,We(i))}for(let[t,n]of a)e.all(t,n)},Ke=e=>`_httpMessage`in e&&typeof e._httpMessage==`object`&&e._httpMessage!==null&&`headersSent`in e._httpMessage&&typeof e._httpMessage.headersSent==`boolean`&&`setHeader`in e._httpMessage&&typeof e._httpMessage.setHeader==`function`,qe=e=>`server`in e&&typeof e.server==`object`&&e.server!==null&&`close`in e.server&&typeof e.server.close==`function`,Je=e=>`encrypted`in e&&typeof e.encrypted==`boolean`&&e.encrypted,Ye=({},e)=>void(!e.headersSent&&e.setHeader(`connection`,`close`)),Xe=e=>{let{promise:t,resolve:n,reject:r}=Promise.withResolvers();return e.close(e=>e?r(e):n()),t},Ze=({timeout:e=1e3,logger:t}={})=>{let n,r=new Set,i=new Set,a=e=>void i.delete(e),o=e=>a(e.destroy()),s=e=>void(Ke(e)?!e._httpMessage.headersSent&&e._httpMessage.setHeader(`connection`,`close`):o(e)),c=e=>void(n?e.destroy():i.add(e.once(`close`,()=>a(e)).once(`error`,()=>o(e)))),l=async()=>{for(let e of r)e.on(`request`,Ye);t?.info(`Graceful shutdown`,{sockets:i.size,timeout:e});for(let e of i)(Je(e)||qe(e))&&s(e);for await(let t of De(10,Date.now()))if(i.size===0||Date.now()-t>=e)break;for(let e of i)o(e);return Promise.allSettled(r.values().map(Xe))},u={sockets:i,add:(...e)=>{for(let t of e)if(!r.has(t)){r.add(t);for(let e of[`connection`,`secureConnection`])t.on(e,c)}return u},shutdown:()=>n??=l(),get isShuttingDown(){return!!n}};return u},J=Symbol.for(`express-zod-api`),Qe=({errorHandler:e,getLogger:n})=>async(r,i,a,o)=>r?e.execute({error:t(r),request:i,response:a,input:null,output:null,ctx:{},logger:n(i)}):o(),$e=({errorHandler:e,getLogger:t})=>async(n,r)=>{let i=D(404,`Can not ${n.method} ${n.path}`),a=t(n);await e.execute({request:n,response:r,logger:a,error:i,input:null,output:null,ctx:{}})},et=e=>(t,{},n)=>{if(Object.values(t?.files||[]).flat().find(({truncated:e})=>e))return n(e);n()},tt=({config:e})=>{let t=w(`cookie-parser`),{secret:n,...r}={...typeof e.cookies==`object`&&e.cookies};return t(n,Object.keys(r).length?r:void 0)},Y=e=>typeof e==`function`?e:({},e,t)=>{e.set({"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Headers":`content-type`}),t()},nt=e=>({log:t=>{/not eligible/i.test(t)||e.debug(t)}}),rt=({getLogger:e,config:t})=>{let n=w(`express-fileupload`),{limitError:r,beforeUpload:i,...a}={...typeof t.upload==`object`&&t.upload},o=[];return o.push(async(t,r,o)=>{let s=e(t);return await i?.({request:t,logger:s}),n({debug:!0,...a,abortOnLimit:!1,parseNested:!0,logger:nt(s)})(t,r,o)}),r&&o.push(et(r)),o},it=(e,{},t)=>{Buffer.isBuffer(e.body)&&(e.body={raw:e.body}),t()},at=({logger:e,config:{childLoggerProvider:t,accessLogger:n=({method:e,path:t},n)=>n.debug(`${e}: ${t}`)}})=>async(r,i,a)=>{let o=await t?.({request:r,parent:e})||e;n?.(r,o),r.res&&(r.res.locals[J]={logger:o}),a()},ot=e=>t=>t?.res?.locals[J]?.logger||e;let X=!1;const st=e=>{X||(X=!0,process.on(`deprecation`,({message:t,namespace:n,name:r,stack:i})=>e.warn(`${r} (${n}): ${t}`,i.split(`
2
+ `).slice(1))))};let Z,Q,$;const ct=({servers:e,logger:t,options:{timeout:n,beforeExit:r,events:i=[`SIGINT`,`SIGTERM`]}})=>{Z??=Ze({logger:t,timeout:n}),Z.add(...e),r&&($??=new Set).add(r),Q??=async()=>{Z?.isShuttingDown||(await Z?.shutdown(),$&&await Promise.allSettled($.values().map(async e=>e())),process.exit())};for(let e of i)process.listeners(e).includes(Q)||process.on(e,Q)},lt=e=>{if(e.columns<62)return;let t=Se(`for Angie`.padStart(52)),n=O(`#F5A9B8`),r=O(`#5BCEFA`),i=[r`8888888888${t}`,r`888`,r`888`,r`8888888 888 888 88888b. 888d888 .d88b. .d8888b .d8888b`,n`888 `Y8bd8P' 888 "88b 888P" d8P Y8b 88K 88K`,n`888 X88K 888 888 888 88888888 "Y8888b. "Y8888b.`,n`888 .d8""8b. 888 d88P 888 Y8b. X88 X88`,k`8888888888 888 888 88888P" 888 "Y8888 88888P' 88888P'`,k` 888`,k`8888888888P 888 888 d8888 8888888b. 8888888`,k` d88P 888 d88888 888 Y88b 888`,n` d88P 888 d88P888 888 888 888`,n` d88P .d88b. .d88888 d88P 888 888 d88P 888`,n` d88P d88""88b d88" 888 d88P 888 8888888P" 888`,r` d88P 888 888 888 888 d88P 888 888 888`,r` d88P Y88..88P Y88b 888 d8888888888 888 888`,r`d8888888888 "Y88P" "Y88888 d88P 888 888 8888888`];e.write(`
3
3
  `+i.join(`
4
4
  `)+`
5
5
 
6
- `)},$=e=>{e.startupLogo!==!1&&ut(process.stdout);let t=e.errorHandler||N,n=Be(e.logger)?e.logger:new W(e.logger);n.debug(`Running`,{build:`v29.3.1`,env:m.env}),ct(n);let r=ot({logger:n,config:e}),i={getLogger:st(n),errorHandler:t},a=et(i),o=$e(i);return{...i,logger:n,notFoundHandler:a,catcher:o,loggingMiddleware:r}},dt=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,loggingMiddleware:a}=$(e),o=e.app.use(a);return e.cors&&o.use(J(e.cors)),K({app:o,routing:t,getLogger:r,config:e}),{notFoundHandler:i,logger:n}},ft=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,catcher:a,loggingMiddleware:o}=$(e),s=A().disable(`x-powered-by`).set(`query parser`,e.queryParser??`simple`).use(o);if(e.beforeParsers?.({app:s,getLogger:r}),e.compression){let t=w(`compression`);s.use(t(typeof e.compression==`object`?e.compression:void 0))}return e.cookies&&s.use(nt({config:e})),e.cors&&s.use(J(e.cors)),s.use(e.jsonParser||A.json()).use(e.formParser||A.urlencoded()).use(e.rawParser||A.raw(),at),e.upload&&s.use(...it({config:e,getLogger:r})),e.beforeRouting?.({app:s,getLogger:r}),K({app:s,routing:t,getLogger:r,config:e}),e.afterRouting?.({app:s,getLogger:r}),s.use(a,i),{app:s,logger:n}},pt=(e,t)=>{let{app:n,logger:r}=ft(e,t),i=[],a=(e,t)=>()=>e.listen(t,()=>r.info(`Listening`,t)),o=[];if(e.http){let t=Ee.createServer(n);i.push(t),o.push(a(t,e.http.listen))}if(e.https){let t=De.createServer(e.https.options,n);i.push(t),o.push(a(t,e.https.listen))}return i.length||r.warn(`No servers configured.`),e.gracefulShutdown&&lt({logger:r,servers:i,options:e.gracefulShutdown===!0?{}:e.gracefulShutdown}),{app:n,logger:r,servers:o.map(e=>e())}},mt=e=>ke({...e,headers:{"content-type":b.json,...e?.headers}}),ht=e=>Ae(e),gt=e=>{let t={warn:[],error:[],info:[],debug:[]};return new Proxy(e||{},{get(e,n,r){return n===`_getLogs`?()=>t:Ve(n)?(...e)=>t[n].push(e):Reflect.get(e,n,r)}})},_t=({requestProps:e,responseOptions:t,configProps:n,loggerProps:r})=>{let i=mt(e),a=ht({req:i,...t});a.req=t?.req||i,i.res=a;let o=gt(r);return{requestMock:i,responseMock:a,loggerMock:o,configMock:{cors:!1,logger:o,...n}}},vt=async({endpoint:e,...t})=>{let{requestMock:n,responseMock:r,loggerMock:i,configMock:a}=_t(t);return await e.execute({request:n,response:r,config:a,logger:i}),{requestMock:n,responseMock:r,loggerMock:i}},yt=async({middleware:e,ctx:n={},...r})=>{let{configMock:{inputSources:i,errorHandler:a=N},...o}=_t(r),s=ee(o.requestMock,i),c={request:o.requestMock,response:o.responseMock,logger:o.loggerMock,input:s,ctx:n};try{let t=await e.execute(c);return{...o,output:t}}catch(e){return await a.execute({...c,error:t(e),output:null}),{...o,output:{}}}},bt=(e,t)=>E.object({data:t,event:E.literal(e),id:E.string().optional(),retry:E.int().positive().optional()}),xt=(e,t,n)=>bt(String(t),e[t]).transform(e=>[`event: ${e.event}`,`data: ${JSON.stringify(e.data)}`,``,``].join(`
7
- `)).parse({event:t,data:n}),St=e=>e.headersSent||e.writeHead(200,{connection:`keep-alive`,"content-type":b.sse,"cache-control":`no-cache`}),Ct=e=>new _({handler:async({request:t,response:n})=>{let r=new AbortController,i=setTimeout(()=>St(n),1e4);return t.once(`close`,()=>{clearTimeout(i),r.abort()}),{isClosed:()=>n.writableEnded||n.closed,signal:r.signal,emit:(t,r)=>{St(n),n.write(xt(e,t,r),`utf-8`),n.flush?.()}}}}),wt=e=>new j({positive:()=>{let[t,...n]=Object.entries(e).map(([e,t])=>bt(e,t));if(!t)throw new l(Error(`At least one SSE event is required.`));return{mimeType:b.sse,schema:n.length?E.discriminatedUnion(`event`,[t,...n]):t}},negative:{mimeType:`text/plain`,schema:E.string()},handler:async({response:e,error:t,logger:n,request:r,input:i})=>{if(t){let a=x(t);v(a,n,r,i),e.headersSent||e.status(a.statusCode).type(`text/plain`).write(g(a),`utf-8`)}e.end()}});var Tt=class extends B{constructor(e){super(wt(e)),this.middlewares=[Ct(e)]}};const Et=[`total`,`limit`,`offset`],Dt=[`nextCursor`,`limit`];function Ot({style:e,itemSchema:t,itemsName:n=`items`,maxLimit:r=100,defaultLimit:i=20}){if(!Number.isInteger(r)||r<1)throw Error(`ez.paginated: maxLimit must be a positive integer`);if(!Number.isInteger(i)||i<1)throw Error(`ez.paginated: defaultLimit must be a positive integer`);if(i>r)throw Error(`ez.paginated: defaultLimit must not be greater than maxLimit`);if(e===`offset`&&Et.includes(n))throw Error(`ez.paginated: itemsName must not match reserved keys for offset output (${Et.join(`, `)})`);if(e===`cursor`&&Dt.includes(n))throw Error(`ez.paginated: itemsName must not match reserved keys for cursor output (${Dt.join(`, `)})`);let a=E.coerce.number().int().min(1).max(r).default(i).describe(`Page size (number of ${n} per page)`);if(e===`offset`){let e=E.coerce.number().int().min(0).default(0).describe(`Number of ${n} to skip`);return{input:E.object({limit:a,offset:e}),output:E.object({[n]:E.array(t).describe(`Page of ${n}`),total:E.number().int().min(0).describe(`Total number of ${n}`),limit:E.number().int().min(1).describe(`Page size used`),offset:E.number().int().min(0).describe(`Offset used`)})}}let o=E.string().optional().describe(`Cursor for the next page; omit for first page`);return{input:E.object({cursor:o,limit:a}),output:E.object({[n]:E.array(t).describe(`Page of ${n}`),nextCursor:E.string().nullable().describe(`Cursor for the next page, or null if no more pages`),limit:E.number().int().min(1).describe(`Page size used`)})}}const kt={dateIn:c,dateOut:e,form:n,upload:d,raw:ne,buffer:u,paginated:Ot};export{W as BuiltinLogger,ue as DocumentationError,B as EndpointsFactory,Tt as EventStreamFactory,f as InputValidationError,_ as Middleware,i as MissingPeerError,r as OutputValidationError,j as ResultHandler,oe as RoutingError,te as ServeStatic,ze as arrayEndpointsFactory,F as arrayResultHandler,dt as attachRouting,re as createApiResponse,L as createCacheMiddleware,je as createConfig,R as createCookieMiddleware,z as createRateLimitMiddleware,pt as createServer,Re as defaultEndpointsFactory,N as defaultResultHandler,x as ensureHttpError,kt as ez,p as getMessageFromError,vt as testEndpoint,yt as testMiddleware};
6
+ `)},ut=e=>{e.startupLogo!==!1&&lt(process.stdout);let t=e.errorHandler||P,n=ze(e.logger)?e.logger:new G(e.logger);n.debug(`Running`,{build:`v29.3.3`,env:p.env}),p.isProduction&&n instanceof G&&n.warn(`Using the built-in logger in production may degrade performance due to synchronous printing. Consider installing a professional logging solution, such as Pino or Winston.`),st(n);let r=at({logger:n,config:e}),i={getLogger:ot(n),errorHandler:t},a=$e(i),o=Qe(i);return{...i,logger:n,notFoundHandler:a,catcher:o,loggingMiddleware:r}},dt=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,loggingMiddleware:a}=ut(e),o=e.app.use(a);return e.cors&&o.use(Y(e.cors)),q({app:o,routing:t,getLogger:r,config:e}),{notFoundHandler:i,logger:n}},ft=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,catcher:a,loggingMiddleware:o}=ut(e),s=j().disable(`x-powered-by`).set(`query parser`,e.queryParser??`simple`).use(o);if(e.beforeParsers?.({app:s,getLogger:r}),e.compression){let t=w(`compression`);s.use(t(typeof e.compression==`object`?e.compression:void 0))}return e.cookies&&s.use(tt({config:e})),e.cors&&s.use(Y(e.cors)),s.use(e.jsonParser||j.json()).use(e.formParser||j.urlencoded()).use(e.rawParser||j.raw(),it),e.upload&&s.use(...rt({config:e,getLogger:r})),e.beforeRouting?.({app:s,getLogger:r}),q({app:s,routing:t,getLogger:r,config:e}),e.afterRouting?.({app:s,getLogger:r}),s.use(a,i),{app:s,logger:n}},pt=(e,t)=>{let{app:n,logger:r}=ft(e,t),i=[],a=(e,t)=>()=>e.listen(t,()=>r.info(`Listening`,t)),o=[];if(e.http){let t=Te.createServer(n);i.push(t),o.push(a(t,e.http.listen))}if(e.https){let t=Ee.createServer(e.https.options,n);i.push(t),o.push(a(t,e.https.listen))}return i.length||r.warn(`No servers configured.`),e.gracefulShutdown&&ct({logger:r,servers:i,options:e.gracefulShutdown===!0?{}:e.gracefulShutdown}),{app:n,logger:r,servers:o.map(e=>e())}},mt=e=>Oe({...e,headers:{"content-type":b.json,...e?.headers}}),ht=e=>ke(e),gt=e=>{let t={warn:[],error:[],info:[],debug:[]};return new Proxy(e||{},{get(e,n,r){return n===`_getLogs`?()=>t:Be(n)?(...e)=>t[n].push(e):Reflect.get(e,n,r)}})},_t=({requestProps:e,responseOptions:t,configProps:n,loggerProps:r})=>{let i=mt(e),a=ht({req:i,...t});a.req=t?.req||i,i.res=a;let o=gt(r);return{requestMock:i,responseMock:a,loggerMock:o,configMock:{cors:!1,logger:o,...n}}},vt=async({endpoint:e,...t})=>{let{requestMock:n,responseMock:r,loggerMock:i,configMock:a}=_t(t);return await e.execute({request:n,response:r,config:a,logger:i}),{requestMock:n,responseMock:r,loggerMock:i}},yt=async({middleware:e,ctx:n={},...r})=>{let{configMock:{inputSources:i,errorHandler:a=P},...o}=_t(r),s=te(o.requestMock,i),c={request:o.requestMock,response:o.responseMock,logger:o.loggerMock,input:s,ctx:n};try{let t=await e.execute(c);return{...o,output:t}}catch(e){return await a.execute({...c,error:t(e),output:null}),{...o,output:{}}}},bt=(e,t)=>E.object({data:t,event:E.literal(e),id:E.string().optional(),retry:E.int().positive().optional()}),xt=(e,t,n)=>bt(String(t),e[t]).transform(e=>[`event: ${e.event}`,`data: ${JSON.stringify(e.data)}`,``,``].join(`
7
+ `)).parse({event:t,data:n}),St=e=>e.headersSent||e.writeHead(200,{connection:`keep-alive`,"content-type":b.sse,"cache-control":`no-cache`}),Ct=e=>new v({handler:async({request:t,response:n})=>{let r=new AbortController,i=setTimeout(()=>St(n),1e4);return t.once(`close`,()=>{clearTimeout(i),r.abort()}),{isClosed:()=>n.writableEnded||n.closed,signal:r.signal,emit:(t,r)=>{St(n),n.write(xt(e,t,r),`utf-8`),n.flush?.()}}}}),wt=e=>new M({positive:()=>{let[t,...n]=Object.entries(e).map(([e,t])=>bt(e,t));if(!t)throw new l(Error(`At least one SSE event is required.`));return{mimeType:b.sse,schema:n.length?E.discriminatedUnion(`event`,[t,...n]):t}},negative:{mimeType:`text/plain`,schema:E.string()},handler:async({response:e,error:t,logger:n,request:r,input:i})=>{if(t){let a=x(t);y(a,n,r,i),e.headersSent||e.status(a.statusCode).type(`text/plain`).write(h(a),`utf-8`)}e.end()}});var Tt=class extends V{constructor(e){super(wt(e)),this.middlewares=[Ct(e)]}};const Et=[`total`,`limit`,`offset`],Dt=[`nextCursor`,`limit`];function Ot({style:e,itemSchema:t,itemsName:n=`items`,maxLimit:r=100,defaultLimit:i=20}){if(!Number.isInteger(r)||r<1)throw Error(`ez.paginated: maxLimit must be a positive integer`);if(!Number.isInteger(i)||i<1)throw Error(`ez.paginated: defaultLimit must be a positive integer`);if(i>r)throw Error(`ez.paginated: defaultLimit must not be greater than maxLimit`);if(e===`offset`&&Et.includes(n))throw Error(`ez.paginated: itemsName must not match reserved keys for offset output (${Et.join(`, `)})`);if(e===`cursor`&&Dt.includes(n))throw Error(`ez.paginated: itemsName must not match reserved keys for cursor output (${Dt.join(`, `)})`);let a=E.coerce.number().int().min(1).max(r).default(i).describe(`Page size (number of ${n} per page)`);if(e===`offset`){let e=E.coerce.number().int().min(0).default(0).describe(`Number of ${n} to skip`);return{input:E.object({limit:a,offset:e}),output:E.object({[n]:E.array(t).describe(`Page of ${n}`),total:E.number().int().min(0).describe(`Total number of ${n}`),limit:E.number().int().min(1).describe(`Page size used`),offset:E.number().int().min(0).describe(`Offset used`)})}}let o=E.string().optional().describe(`Cursor for the next page; omit for first page`);return{input:E.object({cursor:o,limit:a}),output:E.object({[n]:E.array(t).describe(`Page of ${n}`),nextCursor:E.string().nullable().describe(`Cursor for the next page, or null if no more pages`),limit:E.number().int().min(1).describe(`Page size used`)})}}const kt={dateIn:c,dateOut:e,form:n,upload:ee,raw:re,buffer:u,paginated:Ot};export{G as BuiltinLogger,de as DocumentationError,V as EndpointsFactory,Tt as EventStreamFactory,d as InputValidationError,v as Middleware,i as MissingPeerError,r as OutputValidationError,M as ResultHandler,ae as RoutingError,ne as ServeStatic,Re as arrayEndpointsFactory,I as arrayResultHandler,dt as attachRouting,ie as createApiResponse,R as createCacheMiddleware,Ae as createConfig,z as createCookieMiddleware,B as createRateLimitMiddleware,pt as createServer,Le as defaultEndpointsFactory,P as defaultResultHandler,x as ensureHttpError,kt as ez,f as getMessageFromError,vt as testEndpoint,yt as testMiddleware};
@@ -1,4 +1,4 @@
1
- import { d as FlatObject, g as CommonConfig, l as EmptyObject, t as Routing } from "./routing-uoFmENK3.js";
1
+ import { d as FlatObject, g as CommonConfig, l as EmptyObject, t as Routing } from "./routing-BAxxZ1xA.js";
2
2
  import { z } from "zod";
3
3
  import ts, { default as ts$1 } from "typescript";
4
4
  interface NextHandlerInc<U> {
@@ -1,4 +1,4 @@
1
- import{F as e,G as t,I as n,J as r,N as i,Q as a,et as o,j as s,n as c,nt as l,p as u,q as d,r as f,t as p,v as m,y as h}from"./routing-walker-CcgJ8aiU.js";import{t as g}from"./peer-helpers-BQlC55XO.js";import{globalRegistry as _,z as v}from"zod";import*as y from"ramda";import b from"typescript";const x={Path:`Path`,Implementation:`Implementation`,DefaultContext:`DefaultContext`,key:`key`,path:`path`,params:`params`,ctx:`ctx`,method:`method`,request:`request`,event:`event`,data:`data`,handler:`handler`,msg:`msg`,parseRequest:`parseRequest`,substitute:`substitute`,provide:`provide`,on:`on`,implementation:`implementation`,hasBody:`hasBody`,undefined:`undefined`,response:`response`,rest:`rest`,searchParams:`searchParams`,defaultImplementation:`defaultImplementation`,hasFiles:`hasFiles`,value:`value`,File:`File`,FormData:`FormData`,headers:`headers`,body:`body`,client:`client`,contentType:`contentType`,isBlob:`isBlob`,source:`source`,Method:`Method`,SomeOf:`SomeOf`,Request:`Request`,Pagination:`Pagination`,override:`override`},S={input:`Input`,positive:`PositiveResponse`,negative:`NegativeResponse`,encoded:`EncodedResponse`,response:`Response`},C=e=>Array.from(e,e=>`"${e}"`),w=e=>e;var ee=class{serverUrl;paths=new Set;tags=new Map;registry=new Map;constructor(e){this.serverUrl=e}makeMethodType=()=>{let e=C(o).join(` | `);return`export type ${x.Method} = ${e};`};makeOmit=(e,t,n=``)=>`Omit<${e}, ${n&&`\n/** ${n} */\n`}${C(t).join(` | `)}>`;makeSomeOfType=()=>`type ${x.SomeOf}<T> = T[keyof T];`;makeRequestType=()=>`export type ${x.Request} = keyof ${S.input};`;someOf=e=>`${x.SomeOf}<${e}>`;makePathType=()=>{let e=C(this.paths).join(` | `);return`export type ${x.Path} = ${e};`};makePublicInterfaces=()=>Object.keys(S).map(e=>{let t=Array.from(this.registry).map(([t,{store:n,isDeprecated:r}])=>` ${r?`/** @deprecated */
1
+ import{F as e,G as t,I as n,J as r,N as i,Q as a,et as o,j as s,n as c,nt as l,p as u,q as d,r as f,t as p,v as m,y as h}from"./routing-walker-DwbmnLCt.js";import{t as g}from"./peer-helpers-CoetX8Sc.js";import{globalRegistry as _,z as v}from"zod";import*as y from"ramda";import b from"typescript";const x={Path:`Path`,Implementation:`Implementation`,DefaultContext:`DefaultContext`,key:`key`,path:`path`,params:`params`,ctx:`ctx`,method:`method`,request:`request`,event:`event`,data:`data`,handler:`handler`,msg:`msg`,parseRequest:`parseRequest`,substitute:`substitute`,provide:`provide`,on:`on`,implementation:`implementation`,hasBody:`hasBody`,undefined:`undefined`,response:`response`,rest:`rest`,searchParams:`searchParams`,defaultImplementation:`defaultImplementation`,hasFiles:`hasFiles`,value:`value`,File:`File`,FormData:`FormData`,headers:`headers`,body:`body`,client:`client`,contentType:`contentType`,isBlob:`isBlob`,source:`source`,Method:`Method`,SomeOf:`SomeOf`,Request:`Request`,Pagination:`Pagination`,override:`override`},S={input:`Input`,positive:`PositiveResponse`,negative:`NegativeResponse`,encoded:`EncodedResponse`,response:`Response`},C=e=>Array.from(e).map(e=>`"${e}"`),w=e=>e;var ee=class{serverUrl;paths=new Set;tags=new Map;registry=new Map;constructor(e){this.serverUrl=e}makeMethodType=()=>{let e=C(o).join(` | `);return`export type ${x.Method} = ${e};`};makeOmit=(e,t,n=``)=>`Omit<${e}, ${n&&`\n/** ${n} */\n`}${C(t).join(` | `)}>`;makeSomeOfType=()=>`type ${x.SomeOf}<T> = T[keyof T];`;makeRequestType=()=>`export type ${x.Request} = keyof ${S.input};`;someOf=e=>`${x.SomeOf}<${e}>`;makePathType=()=>{let e=C(this.paths).join(` | `);return`export type ${x.Path} = ${e};`};makePublicInterfaces=()=>Object.keys(S).map(e=>{let t=Array.from(this.registry).map(([t,{store:n,isDeprecated:r}])=>` ${r?`/** @deprecated */
2
2
  `:``}"${t}": ${n[e]};`).join(`
3
3
  `);return`export interface ${S[e]} {\n${t}\n}`});makeEndpointTags=()=>`export const endpointTags = {\n${Array.from(this.tags).map(([e,t])=>` "${e}": [${C(t).join(`, `)}]`).join(`,
4
4
  `)}\n}`;makeImplementationType=()=>{let e=[`${x.method}: ${x.Method}`,`${x.path}: string`,`${x.params}: Record<string, any>`,`${x.ctx}?: T`].join(`,`);return`export type ${x.Implementation}<T extends Record<string, unknown>> = (${e}) => Promise<any>;`};makeDefaultContextType=()=>`export type ${x.DefaultContext} = { ${x.override}?: (init: RequestInit) => RequestInit };`;makeParseRequestFn=()=>{let e=`${x.request}: string`,t=`[${x.Method}, ${x.Path}]`,n=`${x.request}.${w(`split`)}(/ (.+)/, 2) as ${t}`;return`const ${x.parseRequest} = (${e}) => ${n};`};makeSubstituteFn=()=>{let e=`${x.path}: string, ${x.params}: Record<string, any>`,t=`\`:\${${x.key}}\``,n=`: [typeof ${x.path}, typeof ${x.params}]`;return[`const ${x.substitute} = (${e})${n} => {`,` if (${x.params} instanceof Blob) return [${x.path}, ${x.params}] as const;`,` const ${x.rest} = { ...${x.params} };`,` for (const ${x.key} in ${x.params}) {`,` ${x.path} = ${x.path}.${w(`replace`)}(${t}, () => {`,` delete ${x.rest}[${x.key}];`,` return ${x.params}[${x.key}];`,` });`,` }`,` return [${x.path}, ${x.rest}] as const;`,`}`].join(`
@@ -6,7 +6,7 @@ import{F as e,G as t,I as n,J as r,N as i,Q as a,et as o,j as s,n as c,nt as l,p
6
6
  `)};makeDefaultImplementation=e=>{let t=`${x.method}, ${x.path}, ${x.params}, ${x.ctx}`,n=C([`get`,`head`,`delete`]).join(`, `),r=`!${x.hasBody} || ${x.hasFiles} ? ${x.undefined} : { "Content-Type": ${x.isBlob} ? "${l.raw}" : "${l.json}" };`,i=`${x.response}.${w(`headers`)}.${w(`get`)}("content-type")`,a=`\`?\${new ${URLSearchParams.name}(${x.params})}\``;return[`const ${x.defaultImplementation}: ${x.Implementation}<${x.DefaultContext}> = async (${t}) => {`,` const ${x.isBlob} = ${x.params} instanceof Blob;`,` const ${x.hasFiles} = !${x.isBlob} && Object.${w(`values`)}(${x.params}).${w(`some`)}((one) => one instanceof Blob || one instanceof ${x.File});`,` const ${x.hasBody} = ![${n}].includes(${x.method});`,` const ${x.searchParams} = ${x.isBlob} || ${x.hasBody} ? "" : ${a};`,` const ${x.headers} = ${r}`,` let ${x.body}: RequestInit["${x.body}"] = ${x.undefined};`,` if (${x.hasBody}) {`,` if (${x.isBlob}) {`,` ${x.body} = ${x.params};`,` } else if (${x.hasFiles}) {`,` ${x.body} = new ${FormData.name}();`,` for (const [${x.key}, ${x.value}] of Object.${w(`entries`)}(${x.params}))`,` if (${x.value} !== undefined) ${x.body}.${w(`append`)}(${x.key}, ${x.value});`,` } else {`,` ${x.body} = JSON.${w(`stringify`)}(${x.params});`,` }`,` }`,` let init: RequestInit = {`,` ${w(`method`)}: ${x.method}.${w(`toUpperCase`)}(),`,` ${w(`credentials`)}: ${e?`"include"`:x.undefined},`,` ${x.headers},`,` ${x.body},`,` };`,` if (${x.ctx}?.${x.override}) init = ${x.ctx}.${x.override}(init);`,` const ${x.response} = await ${fetch.name}(`,` new ${URL.name}(\`\${${x.path}}\${${x.searchParams}}\`, "${this.serverUrl}"),`,` init,`,` );`,` const ${x.contentType} = ${i};`,` if (!${x.contentType}) return;`,` if (${x.contentType}.${w(`startsWith`)}("${l.json}")) return ${x.response}.${w(`json`)}();`,` if (${x.contentType}.${w(`startsWith`)}("text/")) return ${x.response}.${w(`text`)}();`,` return ${x.response}.${w(`blob`)}();`,`};`].join(`
7
7
  `)};makeSubscriptionClass=(e,t)=>{let n=`${x.substitute}(${x.parseRequest}(${x.request})[1], ${x.params})`,r=`Extract<R, { ${w(`event`)}: E }>["${w(`data`)}"]`,i=`(${x.msg} as ${MessageEvent.name}).${w(`data`)}`;return[`export class ${e}<`,` K extends Extract<${x.Request}, \`get \${string}\`>,`,` R extends Extract<${S.positive}[K], { ${w(`event`)}: string }>,`,`> {`,` public ${x.source}: EventSource;`,` public constructor(${x.request}: K, ${x.params}: ${S.input}[K]) {`,` const [${x.path}, ${x.rest}] = ${n};`,` const ${x.searchParams} = \`?\${new ${URLSearchParams.name}(${x.rest})}\`;`,` this.${x.source} = new EventSource(`,` new URL(\`\${${x.path}}\${${x.searchParams}}\`, "${this.serverUrl}"),`,` { ${w(`withCredentials`)}: ${t?`true`:x.undefined} }`,` );`,` }`,` public ${x.on}<E extends R["${w(`event`)}"]>(`,` ${w(`event`)}: E,`,` ${x.handler}: (${x.data}: ${r}) => void | Promise<void>,`,` ) {`,` this.${x.source}.${w(`addEventListener`)}(${x.event}, (${x.msg}) =>`,` ${x.handler}(JSON.${w(`parse`)}(${i})),`,` );`,` return this;`,` }`,`}`].join(`
8
8
  `)};makeUsageStatements=(e,t)=>[`const ${x.client} = new ${e}();`,`${x.client}.${x.provide}("get /v1/user/retrieve", { id: "10" });`,`new ${t}("get /v1/events/stream", {}).${x.on}("time", (time) => {});`].join(`
9
- `)};const T=b.factory,E=/^[A-Za-z_$][A-Za-z0-9_$]*$/,D=[b.SyntaxKind.AnyKeyword,b.SyntaxKind.BigIntKeyword,b.SyntaxKind.BooleanKeyword,b.SyntaxKind.NeverKeyword,b.SyntaxKind.NumberKeyword,b.SyntaxKind.ObjectKeyword,b.SyntaxKind.StringKeyword,b.SyntaxKind.SymbolKeyword,b.SyntaxKind.UndefinedKeyword,b.SyntaxKind.UnknownKeyword,b.SyntaxKind.VoidKeyword],O=e=>typeof e==`number`?T.createNumericLiteral(e):typeof e==`bigint`?T.createBigIntLiteral(e.toString()):typeof e==`boolean`?e?T.createTrue():T.createFalse():e===null?T.createNull():T.createStringLiteral(e),k=e=>T.createIdentifier(e),A=e=>typeof e==`string`&&E.test(e)?k(e):O(e),j=(e,t)=>typeof e==`number`?T.createKeywordTypeNode(e):typeof e==`string`||b.isIdentifier(e)?T.createTypeReferenceNode(e,t&&y.map(j,t)):e,M=e=>{let t=new Map;for(let n of e)t.set(N(n)?n.kind:n,n);return T.createUnionTypeNode(Array.from(t.values()))},N=e=>D.includes(e.kind),P=(e,t)=>b.addSyntheticLeadingComment(e,b.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0),F=(e,t)=>{let n=b.createSourceFile(`print.ts`,``,b.ScriptTarget.Latest,!1,b.ScriptKind.TS);return b.createPrinter(t).printNode(b.EmitHint.Unspecified,e,n)},te=(e,t,{isOptional:n,hasUndefined:r=n,isDeprecated:i,comment:a}={})=>{let o=j(t),s=T.createPropertySignature(void 0,A(e),n?T.createToken(b.SyntaxKind.QuestionToken):void 0,r?M([o,j(b.SyntaxKind.UndefinedKeyword)]):o),c=y.reject(y.isNil,[i?`@deprecated`:void 0,a]);return c.length?P(s,c.join(` `)):s},I=e=>T.createLiteralTypeNode(O(e)),L=(e,{rules:t,onMissing:r,ctx:i={}})=>{let a=n(e),o=a&&a in t?t[a]:t[e._zod.def.type],s=e=>L(e,{ctx:i,rules:t,onMissing:r});return o?o(e,{...i,next:s}):r(e,i)},R={name:y.path([`name`,`text`]),type:y.path([`type`]),optional:y.path([`questionToken`])},z=({_zod:{def:e}})=>{let t=e.values.map(e=>e===void 0?j(b.SyntaxKind.UndefinedKeyword):I(e));return t.length===1?t[0]:M(t)},B=({_zod:{def:e}},{next:t})=>{let{parts:n}=e,r=0,i=()=>{let e=``;for(;r<n.length;){let t=n[r];if(d(t))break;r++,e+=t??``}return e},a=T.createTemplateHead(i()),o=[];for(;r<n.length;){let e=t(n[r++]),a=i(),s=r<n.length?T.createTemplateMiddle:T.createTemplateTail;o.push(T.createTemplateLiteralTypeSpan(e,s(a)))}return o.length?T.createTemplateLiteralType(a,o):I(a.text)},V=(e,{isResponse:t,next:n,makeAlias:r})=>{let i=()=>{let r=Object.entries(e._zod.def.shape).map(([e,r])=>{let{description:i,deprecated:a}=_.get(r)||{},o=(t?r._zod.optout:r._zod.optin)===`optional`,s=o&&!(r instanceof v.core.$ZodExactOptional);return te(e,n(r),{comment:i,isDeprecated:a,isOptional:o,hasUndefined:s})});return T.createTypeLiteralNode(r)};return m(e,{io:t?`output`:`input`})?r(e,i):i()},H=({_zod:{def:e}},{next:t})=>T.createArrayTypeNode(t(e.element)),U=({_zod:{def:e}})=>M(y.map(I,Object.values(e.entries))),W=({_zod:{def:e}},{next:t})=>M(e.options.map(t)),G=({_zod:{def:e}},{next:t})=>M([t(e.innerType),I(null)]),K=({_zod:{def:e}},{next:t})=>T.createTupleTypeNode(e.items.map(t).concat(e.rest===null?[]:T.createRestTypeNode(t(e.rest)))),q=({_zod:{def:e}},{next:t})=>{let[n,r]=[e.keyType,e.valueType].map(t),i=j(`Record`,[n,r]);return e.mode===`loose`?T.createIntersectionTypeNode([i,j(`Record`,[`PropertyKey`,r])]):i},J=y.tryCatch(e=>{if(!e.every(b.isTypeLiteralNode))throw Error(`Not objects`);let t=y.chain(y.prop(`members`),e),n=y.uniqWith((...e)=>{if(!y.eqBy(R.name,...e))return!1;if(y.both(y.eqBy(R.type),y.eqBy(R.optional))(...e))return!0;throw Error(`Has conflicting prop`)},t);return T.createTypeLiteralNode(n)},(e,t)=>T.createIntersectionTypeNode(t)),Y=({_zod:{def:e}},{next:t})=>J([e.left,e.right].map(t)),X=e=>()=>j(e),Z=({_zod:{def:e}},{next:t})=>t(e.innerType),Q=e=>j(e?b.SyntaxKind.UnknownKeyword:b.SyntaxKind.AnyKeyword),ne=({_zod:{def:e}},{next:n,isResponse:r})=>{let i=e[r?`out`:`in`],a=e[r?`in`:`out`];if(!d(i,`transform`))return n(i);let o=n(a),s={[b.SyntaxKind.AnyKeyword]:``,[b.SyntaxKind.BigIntKeyword]:BigInt(0),[b.SyntaxKind.BooleanKeyword]:!1,[b.SyntaxKind.NumberKeyword]:0,[b.SyntaxKind.ObjectKeyword]:{},[b.SyntaxKind.StringKeyword]:``,[b.SyntaxKind.UndefinedKeyword]:void 0}[o.kind],c=t(i,s),l={number:b.SyntaxKind.NumberKeyword,bigint:b.SyntaxKind.BigIntKeyword,boolean:b.SyntaxKind.BooleanKeyword,string:b.SyntaxKind.StringKeyword,undefined:b.SyntaxKind.UndefinedKeyword,object:b.SyntaxKind.ObjectKeyword};return j(c&&l[c]||Q(r))},re=()=>I(null),ie=({_zod:{def:e}},{makeAlias:t,next:n})=>t(e.getter,()=>n(e.getter())),ae=()=>j(`Blob`),oe=(e,{next:t})=>t(e._zod.def.shape.raw),se={string:X(b.SyntaxKind.StringKeyword),number:X(b.SyntaxKind.NumberKeyword),bigint:X(b.SyntaxKind.BigIntKeyword),boolean:X(b.SyntaxKind.BooleanKeyword),any:X(b.SyntaxKind.AnyKeyword),undefined:X(b.SyntaxKind.UndefinedKeyword),[i]:X(b.SyntaxKind.StringKeyword),[s]:X(b.SyntaxKind.StringKeyword),never:X(b.SyntaxKind.NeverKeyword),void:X(b.SyntaxKind.UndefinedKeyword),unknown:X(b.SyntaxKind.UnknownKeyword),null:re,array:H,tuple:K,record:q,object:V,literal:z,template_literal:B,intersection:Y,union:W,default:Z,enum:U,optional:Z,nonoptional:Z,nullable:G,catch:Z,pipe:ne,lazy:ie,readonly:Z,[e]:ae,[h]:oe},$=(e,{brandHandling:t,ctx:n})=>L(e,{rules:{...t,...se},onMissing:({},{isResponse:e})=>Q(e),ctx:n});var ce=class extends ee{#e=[];#t=new Map;#n;#r(e,t){let n=this.#t.get(e);if(!n){n=`Type${this.#t.size+1}`,this.#t.set(e,n);let r=t();this.#e.push(e=>`type ${n} = ${F(r,e)};`)}return j(n)}constructor({routing:e,config:t,brandHandling:n,variant:i=`client`,clientClassName:o=`Client`,subscriptionClassName:s=`Subscription`,serverUrl:l=`https://example.com`,noBodySchema:d=v.undefined(),hasHeadMethod:m=!0,hasCredentials:h=!1}){super(l);let g={makeAlias:this.#r.bind(this)},_={brandHandling:n,ctx:{...g,isResponse:!1}},y={brandHandling:n,ctx:{...g,isResponse:!0}},b=!1,x=(e,t,n)=>{let i=r.bind(null,e,t),{isDeprecated:o,inputSchema:s,tags:c}=n,l=`${e} ${t}`,p=i(`input`),m=f(n.security,`cookie`);m.size&&(b=!0);let h=$(s,_);this.#e.push(e=>{let t=F(h,e);return[`/** ${l} */`,`type ${p} = ${m.size?this.makeOmit(t,m,`security cookies`):t};`].join(`
9
+ `)};const T=b.factory,E=/^[A-Za-z_$][A-Za-z0-9_$]*$/,D=new Set([b.SyntaxKind.AnyKeyword,b.SyntaxKind.BigIntKeyword,b.SyntaxKind.BooleanKeyword,b.SyntaxKind.NeverKeyword,b.SyntaxKind.NumberKeyword,b.SyntaxKind.ObjectKeyword,b.SyntaxKind.StringKeyword,b.SyntaxKind.SymbolKeyword,b.SyntaxKind.UndefinedKeyword,b.SyntaxKind.UnknownKeyword,b.SyntaxKind.VoidKeyword]),O=e=>typeof e==`number`?T.createNumericLiteral(e):typeof e==`bigint`?T.createBigIntLiteral(e.toString()):typeof e==`boolean`?e?T.createTrue():T.createFalse():e===null?T.createNull():T.createStringLiteral(e),k=e=>T.createIdentifier(e),A=e=>typeof e==`string`&&E.test(e)?k(e):O(e),j=(e,t)=>typeof e==`number`?T.createKeywordTypeNode(e):typeof e==`string`||b.isIdentifier(e)?T.createTypeReferenceNode(e,t&&y.map(j,t)):e,M=e=>{let t=new Map;for(let n of e)t.set(N(n)?n.kind:n,n);return T.createUnionTypeNode(Array.from(t.values()))},N=e=>D.has(e.kind),P=(e,t)=>b.addSyntheticLeadingComment(e,b.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0),F=(e,t)=>{let n=b.createSourceFile(`print.ts`,``,b.ScriptTarget.Latest,!1,b.ScriptKind.TS);return b.createPrinter(t).printNode(b.EmitHint.Unspecified,e,n)},te=(e,t,{isOptional:n,hasUndefined:r=n,isDeprecated:i,comment:a}={})=>{let o=j(t),s=T.createPropertySignature(void 0,A(e),n?T.createToken(b.SyntaxKind.QuestionToken):void 0,r?M([o,j(b.SyntaxKind.UndefinedKeyword)]):o),c=y.reject(y.isNil,[i?`@deprecated`:void 0,a]);return c.length?P(s,c.join(` `)):s},I=e=>T.createLiteralTypeNode(O(e)),L=(e,{rules:t,onMissing:r,ctx:i={}})=>{let a=n(e),o=a&&a in t?t[a]:t[e._zod.def.type],s=e=>L(e,{ctx:i,rules:t,onMissing:r});return o?o(e,{...i,next:s}):r(e,i)},R={name:y.path([`name`,`text`]),type:y.path([`type`]),optional:y.path([`questionToken`])},z=({_zod:{def:e}})=>{let t=e.values.map(e=>e===void 0?j(b.SyntaxKind.UndefinedKeyword):I(e));return t.length===1?t[0]:M(t)},B=({_zod:{def:e}},{next:t})=>{let{parts:n}=e,r=0,i=()=>{let e=``;for(;r<n.length;){let t=n[r];if(d(t))break;r++,e+=t??``}return e},a=T.createTemplateHead(i()),o=[];for(;r<n.length;){let e=t(n[r++]),a=i(),s=r<n.length?T.createTemplateMiddle:T.createTemplateTail;o.push(T.createTemplateLiteralTypeSpan(e,s(a)))}return o.length?T.createTemplateLiteralType(a,o):I(a.text)},V=(e,{isResponse:t,next:n,makeAlias:r})=>{let i=()=>{let r=Object.entries(e._zod.def.shape).map(([e,r])=>{let{description:i,deprecated:a}=_.get(r)||{},o=(t?r._zod.optout:r._zod.optin)===`optional`,s=o&&!(r instanceof v.core.$ZodExactOptional);return te(e,n(r),{comment:i,isDeprecated:a,isOptional:o,hasUndefined:s})});return T.createTypeLiteralNode(r)};return m(e,{io:t?`output`:`input`})?r(e,i):i()},H=({_zod:{def:e}},{next:t})=>T.createArrayTypeNode(t(e.element)),U=({_zod:{def:e}})=>M(y.map(I,Object.values(e.entries))),W=({_zod:{def:e}},{next:t})=>M(e.options.map(t)),G=({_zod:{def:e}},{next:t})=>M([t(e.innerType),I(null)]),K=({_zod:{def:e}},{next:t})=>T.createTupleTypeNode(e.items.map(t).concat(e.rest===null?[]:T.createRestTypeNode(t(e.rest)))),q=({_zod:{def:e}},{next:t})=>{let[n,r]=[e.keyType,e.valueType].map(t),i=j(`Record`,[n,r]);return e.mode===`loose`?T.createIntersectionTypeNode([i,j(`Record`,[`PropertyKey`,r])]):i},J=y.tryCatch(e=>{if(!e.every(b.isTypeLiteralNode))throw Error(`Not objects`);let t=y.chain(y.prop(`members`),e),n=y.uniqWith((...e)=>{if(!y.eqBy(R.name,...e))return!1;if(y.both(y.eqBy(R.type),y.eqBy(R.optional))(...e))return!0;throw Error(`Has conflicting prop`)},t);return T.createTypeLiteralNode(n)},(e,t)=>T.createIntersectionTypeNode(t)),Y=({_zod:{def:e}},{next:t})=>J([e.left,e.right].map(t)),X=e=>()=>j(e),Z=({_zod:{def:e}},{next:t})=>t(e.innerType),Q=e=>j(e?b.SyntaxKind.UnknownKeyword:b.SyntaxKind.AnyKeyword),ne=({_zod:{def:e}},{next:n,isResponse:r})=>{let i=e[r?`out`:`in`],a=e[r?`in`:`out`];if(!d(i,`transform`))return n(i);let o=n(a),s={[b.SyntaxKind.AnyKeyword]:``,[b.SyntaxKind.BigIntKeyword]:BigInt(0),[b.SyntaxKind.BooleanKeyword]:!1,[b.SyntaxKind.NumberKeyword]:0,[b.SyntaxKind.ObjectKeyword]:{},[b.SyntaxKind.StringKeyword]:``,[b.SyntaxKind.UndefinedKeyword]:void 0}[o.kind],c=t(i,s),l={number:b.SyntaxKind.NumberKeyword,bigint:b.SyntaxKind.BigIntKeyword,boolean:b.SyntaxKind.BooleanKeyword,string:b.SyntaxKind.StringKeyword,undefined:b.SyntaxKind.UndefinedKeyword,object:b.SyntaxKind.ObjectKeyword};return j(c&&l[c]||Q(r))},re=()=>I(null),ie=({_zod:{def:e}},{makeAlias:t,next:n})=>t(e.getter,()=>n(e.getter())),ae=()=>j(`Blob`),oe=(e,{next:t})=>t(e._zod.def.shape.raw),se={string:X(b.SyntaxKind.StringKeyword),number:X(b.SyntaxKind.NumberKeyword),bigint:X(b.SyntaxKind.BigIntKeyword),boolean:X(b.SyntaxKind.BooleanKeyword),any:X(b.SyntaxKind.AnyKeyword),undefined:X(b.SyntaxKind.UndefinedKeyword),[i]:X(b.SyntaxKind.StringKeyword),[s]:X(b.SyntaxKind.StringKeyword),never:X(b.SyntaxKind.NeverKeyword),void:X(b.SyntaxKind.UndefinedKeyword),unknown:X(b.SyntaxKind.UnknownKeyword),null:re,array:H,tuple:K,record:q,object:V,literal:z,template_literal:B,intersection:Y,union:W,default:Z,enum:U,optional:Z,nonoptional:Z,nullable:G,catch:Z,pipe:ne,lazy:ie,readonly:Z,[e]:ae,[h]:oe},$=(e,{brandHandling:t,ctx:n})=>L(e,{rules:{...t,...se},onMissing:({},{isResponse:e})=>Q(e),ctx:n});var ce=class extends ee{#e=[];#t=new Map;#n;#r(e,t){let n=this.#t.get(e);if(!n){n=`Type${this.#t.size+1}`,this.#t.set(e,n);let r=t();this.#e.push(e=>`type ${n} = ${F(r,e)};`)}return j(n)}constructor({routing:e,config:t,brandHandling:n,variant:i=`client`,clientClassName:o=`Client`,subscriptionClassName:s=`Subscription`,serverUrl:l=`https://example.com`,noBodySchema:d=v.undefined(),hasHeadMethod:m=!0,hasCredentials:h=!1}){super(l);let g={makeAlias:this.#r.bind(this)},_={brandHandling:n,ctx:{...g,isResponse:!1}},y={brandHandling:n,ctx:{...g,isResponse:!0}},b=!1,x=(e,t,n)=>{let i=r.bind(null,e,t),{isDeprecated:o,inputSchema:s,tags:c}=n,l=`${e} ${t}`,p=i(`input`),m=f(n.security,`cookie`);m.size&&(b=!0);let h=$(s,_);this.#e.push(e=>{let t=F(h,e);return[`/** ${l} */`,`type ${p} = ${m.size?this.makeOmit(t,m,`security cookies`):t};`].join(`
10
10
  `)});let g=u.reduce((t,r)=>{let o=n.getResponses(r),s=[];for(let[t,{schema:n,mimeTypes:c,statusCodes:u}]of o.entries()){let o=a(e,c),f=i(r,`variant`,`${t+1}`),p=$(o?n:d,y);this.#e.push(e=>`/** ${l} */\ntype ${f} = ${F(p,e)};`);for(let e of u)s.push(` ${e}: ${f};`)}let c=i(r,`response`,`variants`);return this.#e.push(`/** ${l} */\ninterface ${c} {\n${s.join(`
11
11
  `)}\n}`),Object.assign(t,{[r]:c})},{});this.paths.add(t);let v={input:p,positive:this.someOf(g.positive),negative:this.someOf(g.negative),response:`${S.positive}["${l}"] | ${S.negative}["${l}"]`,encoded:`${g.positive} & ${g.negative}`};this.registry.set(l,{isDeprecated:o,store:v}),this.tags.set(l,c)};p({routing:e,config:t,onEndpoint:m?c(x):x}),this.#e.push(this.makeSomeOfType(),this.makePathType(),this.makeMethodType(),...this.makePublicInterfaces(),this.makeRequestType()),i!==`types`&&(this.#e.push(this.makeEndpointTags(),this.makeParseRequestFn(),this.makeSubstituteFn(),this.makeImplementationType(),this.makePaginationType(),this.makeDefaultContextType(),this.makeDefaultImplementation(h&&b),this.makeClientClass(o),this.makeSubscriptionClass(s,h&&b)),this.#n=this.makeUsageStatements(o,s))}print(e){let t=this.#e.map(t=>typeof t==`function`?t(e):t);return this.#n&&t.push(`// Usage example:\n/*\n${this.#n}*/`),t.join(`
12
12
 
@@ -1 +1 @@
1
- import{E as e}from"./routing-walker-CcgJ8aiU.js";import{createRequire as t}from"node:module";let n;const r=(r,i=`default`)=>{try{let e=(n??=t(import.meta.url))(r);return i==="default"?e.default===void 0?e:e.default:e[i]}catch{throw new e(r)}};export{r as t};
1
+ import{E as e}from"./routing-walker-DwbmnLCt.js";import{createRequire as t}from"node:module";let n;const r=(r,i=`default`)=>{try{let e=(n??=t(import.meta.url))(r);return i==="default"?e.default===void 0?e:e.default:e[i]}catch{throw new e(r)}};export{r as t};
@@ -82,7 +82,7 @@ interface ProfilerOptions {
82
82
  /** @default formatDuration - adaptive units and limited fraction */
83
83
  formatter?: (ms: number) => string | number;
84
84
  }
85
- /** @desc Built-in console logger with optional colorful inspections */
85
+ /** @desc Built-in console logger for development with optional colorful inspections */
86
86
  declare class BuiltinLogger implements AbstractLogger {
87
87
  protected readonly config: BuiltinLoggerConfig;
88
88
  /** @example new BuiltinLogger({ level: "debug", color: true, depth: 4 }) */
@@ -262,7 +262,7 @@ interface CommonConfig {
262
262
  */
263
263
  errorHandler?: AbstractResultHandler;
264
264
  /**
265
- * @desc Built-in logger configuration or an instance of any compatible logger.
265
+ * @desc Built-in logger configuration (for development only) or any compatible logger instance.
266
266
  * @example { level: "debug", color: true }
267
267
  * @default { level: NODE_ENV === "production" ? "warn" : "debug", color: isSupported(), depth: 2 }
268
268
  * */
@@ -703,8 +703,8 @@ declare class Endpoint<IN extends IOSchema, OUT extends IOSchema, CTX extends Fl
703
703
  summary?: string;
704
704
  getOperationId?: (method: ClientMethod) => string | undefined;
705
705
  methods: FrozenSet<Method>;
706
- scopes?: string[];
707
- tags?: string[];
706
+ scopes: FrozenSet<string>;
707
+ tags: FrozenSet<string>;
708
708
  statusCodes: ReadonlySet<number>;
709
709
  });
710
710
  deprecated(): this;
@@ -0,0 +1 @@
1
+ import{globalRegistry as e,z as t}from"zod";import*as n from"ramda";import{isPromise as r}from"node:util/types";import i,{isHttpError as a}from"http-errors";import o from"express";const s={json:`application/json`,upload:`multipart/form-data`,raw:`application/octet-stream`,sse:`text/event-stream`,form:`application/x-www-form-urlencoded`},c=[`get`,`post`,`put`,`delete`,`patch`,`query`],l=[...c,`head`],u=e=>c.includes(e),d=t.object({}),f=/:([A-Za-z0-9_]+)/g,ee=e=>e.match(f)?.map(e=>e.slice(1))||[],p=(e,t=1)=>e.replace(f,()=>`:${t++}`),te=e=>{let t=(e.header(`content-type`)||``).toLowerCase().startsWith(s.upload);return`files`in e&&t},ne={get:[`query`,`params`],post:[`body`,`params`,`files`],put:[`body`,`params`],patch:[`body`,`params`],delete:[`query`,`params`],query:[`query`,`body`,`params`]},re=[`body`,`query`,`params`],m=e=>e.method.toLowerCase(),h=(e,t={})=>{if(e===`options`)return[];let n=e===`head`?`get`:u(e)?e:void 0;return(n?t[n]||ne[n]:void 0)||re},g=(e,t={})=>{let n=m(e);return h(n,t).filter(t=>t!==`files`||te(e)).reduce((t,n)=>Object.assign(t,e[n]),{})},_=e=>e instanceof Error?e:e instanceof t.ZodError?new t.ZodRealError(e.issues):Error(String(e)),v=e=>e instanceof t.ZodError?e.issues.map(({path:e,message:n})=>`${e.length?`${t.core.toDotPath(e)}: `:``}${n}`).join(`; `):e.message,y=(e,t)=>S(e)&&`_zod`in e&&(!t||n.path([`_zod`,`def`,`type`],e)===t),b=(e,t,r)=>e.length&&t.length?n.xprod(e,t).map(r):e.concat(t),x=e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase(),ie=(...e)=>{let t=n.chain(e=>e.split(/[^A-Z0-9]/gi),e);return n.chain(e=>e.replaceAll(/[A-Z]+/g,e=>`/${e}`).split(`/`),t).map(x).join(``)},ae=n.tryCatch((e,n)=>typeof t.parse(e,n),n.always(void 0)),S=e=>typeof e==`object`&&!!e,C={_cache:void 0,get env(){return C._cache??=process.env.NODE_ENV??`development`},get isProduction(){return C.env===`production`}},oe=(e,t)=>!!t&&e!==`head`,w=`x-brand`,T=t=>{let{[w]:n}=e.get(t)||{};if(typeof n==`symbol`||typeof n==`string`||typeof n==`number`)return n},E=t=>{let{examples:n}=e.get(t)||{};return Array.isArray(n)?n:[]},D=Symbol(`Buffer`),O=()=>t.custom(e=>Buffer.isBuffer(e),{error:`Expected Buffer`}).meta({[w]:D}),k=Symbol(`DateIn`),se=({examples:e,...n}={})=>t.union([t.iso.date(),t.iso.datetime({local:!0,offset:!0})]).meta({examples:e}).transform(e=>new Date(e)).pipe(t.date()).meta({...n,[w]:k}),A=Symbol(`DateOut`),ce=(e={})=>t.date().transform(e=>e.toISOString()).pipe(t.iso.datetime()).meta({...e,[w]:A});var j=class extends Error{name=`RoutingError`;cause;constructor(e,t,n){super(e),this.cause={method:t,path:n}}},le=class extends Error{name=`DocumentationError`;cause;constructor(e,{method:t,path:n,isResponse:r}){super(e),this.cause=`${r?`Response`:`Input`} schema of an Endpoint assigned to ${t.toUpperCase()} method of ${n} path.`}},M=class extends Error{name=`IOSchemaError`},ue=class extends M{cause;name=`DeepCheckError`;constructor(e){super(`Found`,{cause:e}),this.cause=e}},N=class extends M{cause;name=`OutputValidationError`;constructor(e){let n=new t.ZodError(e.issues.map(({path:e,...t})=>({...t,path:[`output`,...e]})));super(v(n),{cause:e}),this.cause=e}},P=class extends M{cause;name=`InputValidationError`;constructor(e){super(v(e),{cause:e}),this.cause=e}},F=class extends Error{cause;handled;name=`ResultHandlerError`;constructor(e,t){super(v(e),{cause:e}),this.cause=e,this.handled=t}},de=class extends Error{name=`MissingPeerError`;constructor(e){super(`Missing peer dependency: ${e}. Please install it to use the feature.`)}};const I=Symbol(`Form`),fe=e=>(e instanceof t.ZodObject?e:t.object(e)).meta({[w]:I}),L=Symbol(`Upload`),pe=e=>S(e)&&`name`in e&&`encoding`in e&&`mimetype`in e&&`data`in e&&`tempFilePath`in e&&`truncated`in e&&`size`in e&&`md5`in e&&`mv`in e,me=()=>t.custom(e=>pe(e)&&typeof e.name==`string`&&typeof e.encoding==`string`&&typeof e.mimetype==`string`&&Buffer.isBuffer(e.data)&&typeof e.tempFilePath==`string`&&typeof e.truncated==`boolean`&&typeof e.size==`number`&&typeof e.md5==`string`&&typeof e.mv==`function`,{error:({input:e})=>({message:`Expected file upload, received ${typeof e}`})}).meta({[w]:L}),R=Symbol(`Raw`),z=t.object({raw:O()}),he=e=>z.extend(e).meta({[w]:R});function ge(e){return e?he(e):z.meta({[w]:R})}const B=(e,{io:r,condition:i})=>n.tryCatch(()=>void t.toJSONSchema(e,{io:r,unrepresentable:`any`,override:({zodSchema:e})=>{if(i(e))throw new ue(e)}}),e=>e.cause)(),_e=(e,{io:r})=>{let i=[t.toJSONSchema(e,{io:r,unrepresentable:`any`})];for(let e=0;e<i.length;e++){let t=i[e];if(n.is(Object,t)){if(t.$ref===`#`)return!0;i.push(...n.values(t))}n.is(Array,t)&&i.push(...n.values(t))}return!1},ve=new Set([L,R,I]),ye=e=>B(e,{condition:e=>{let t=T(e);return typeof t==`symbol`&&ve.has(t)},io:`input`}),be=new Set([`nan`,`symbol`,`map`,`set`,`bigint`,`void`,`promise`,`never`,`function`]),xe=(e,t)=>B(e,{io:t,condition:e=>{let n=T(e),{type:r}=e._zod.def;return!!(be.has(r)||n===D||t===`input`&&(r===`date`||n===A)||t===`output`&&(n===k||n===R||n===L))}});var V=class e extends Set{constructor(e){if(super(),e)for(let t of e)Set.prototype.add.call(this,t)}add(e){throw TypeError(`Can not add to the read only Set`)}delete(e){throw TypeError(`Can not delete from the read only Set`)}clear(){throw TypeError(`Can not clear the read only Set`)}union(t){return new e(super.union(t))}intersection(t){return new e(super.intersection(t))}difference(t){return new e(super.difference(t))}symmetricDifference(t){return new e(super.symmetricDifference(t))}},Se=class{},H=class extends Se{#e;#t;#n;#r;constructor({input:e,security:t,statusCode:n,handler:r}){super(),this.#e=e,this.#t=t,this.#n=new V(typeof n==`number`?[n]:n),this.#r=r}get security(){return this.#t}get schema(){return this.#e}get statusCodes(){return this.#n}async execute({input:e,...n}){try{let t=await(this.#e||d).parseAsync(e);return this.#r({...n,input:t})}catch(e){throw e instanceof t.ZodError?new P(e):e}}},U=class extends H{constructor(e,{provider:t=()=>({}),transformer:n=e=>e,statusCode:i}={}){super({statusCode:i,handler:async({request:i,response:a})=>{let{promise:o,resolve:s,reject:c}=Promise.withResolvers(),l=e=>{if(e&&e instanceof Error)return c(n(e));s(t(i,a))},u=e(i,a,l);return r(u)&&u.catch(l),o}})}};const W={positive:200,negative:400},Ce=Object.keys(W),G=e=>e<400;function we(e){return e instanceof t.ZodType?{schema:e}:e}const Te=(e,{variant:r,args:i})=>{typeof e==`function`&&(e=e(...i));let a={statusCodes:[W[r]],mimeTypes:[s.json]};if(e instanceof t.ZodType)return[{schema:e,...a}];if(Array.isArray(e)&&!e.length)throw new F(Error(`At least one ${r} response schema required.`));let o=(Array.isArray(e)?e:[e]).map(({schema:e,statusCode:t,mimeType:n})=>({schema:e,statusCodes:typeof t==`number`?[t]:t||a.statusCodes,mimeTypes:typeof n==`string`?[n]:n===void 0?a.mimeTypes:n})),c=n.chain(n.prop(`statusCodes`),o),l=c.find(e=>G(e)===(r===`negative`));if(l!==void 0)throw new F(Error(`The status code ${l} is not valid for a ${r} API response.`));if(o.length>1){let e=n.find(e=>c.indexOf(e)!==c.lastIndexOf(e),c);if(e!==void 0)throw new F(Error(`The status code ${e} is used by multiple response schemas.`))}return o},Ee=(e,t,n)=>{let r=new Set(Array.from(t).filter(e=>G(e)===(n===`positive`)));if(!r.size)return e;if(e.length===1)return e.map(e=>({...e,statusCodes:Array.from(r)}));let i=[],a=e.reduce((e,{statusCodes:t,...n})=>{let a=new Set(t).intersection(r);return a.size?(i.push({...n,statusCodes:Array.from(a)}),e.difference(a)):e},new Set(r));if(a.size){let e=Array.from(a).join(`, `),t=a.size>1;throw new F(Error(`The ResultHandler defines multiple ${n} response schemas, but the overriding status code${t?`s`:``} ${e} of the Endpoint ${t?`are`:`is`} not listed for any of them, therefore it is unclear how such override${t?`s`:``} would be handled. Consider adding ${t?`them`:`it`} to ResultHandler.`))}return i},De=(e,t,{url:n},r)=>!e.expose&&t.error(`Server side error`,{error:e,url:n,payload:r}),Oe=e=>a(e)?e:i(e instanceof P?400:500,v(e),{cause:e.cause||e}),ke=e=>C.isProduction&&!e.expose?i(e.statusCode).message:e.message,Ae=e=>Object.entries(e._zod.def.shape).reduce((e,[t,r])=>b(e,E(r).map(n.objOf(t)),([e,t])=>({...e,...t})),[]);var K=class{nest(e){return{...e,"":this}}},je=class r extends K{#e;#t;#n=n.once(()=>{if(E(this.#e.outputSchema).length||!y(this.#e.outputSchema,`object`))return;let t=Ae(this.#e.outputSchema);if(!t.length)return;let n=this.#e.outputSchema.meta();e.remove(this.#e.outputSchema).add(this.#e.outputSchema,{...n,examples:t})});constructor(e){super(),this.#e=e}#r(e){return new r({...this.#e,...e})}deprecated(){return this.#r({deprecated:!0})}get isDeprecated(){return this.#e.deprecated||!1}get description(){return this.#e.description}get summary(){return this.#e.summary}get methods(){return this.#e.methods}get inputSchema(){return this.#e.inputSchema}get outputSchema(){return this.#e.outputSchema}getProbableRequestType(e){return e===`query`?`form`:this.#t??=(()=>{let e=ye(this.#e.inputSchema);if(e){let t=T(e);if(t===L)return`upload`;if(t===R)return`raw`;if(t===I)return`form`}return`json`})()}getResponses(e){e===`positive`&&this.#n();let t=e===`negative`?this.#e.resultHandler.getNegativeResponse():this.#e.resultHandler.getPositiveResponse(this.#e.outputSchema);return Object.freeze(this.#e.statusCodes.size?Ee(t,this.#e.statusCodes,e):t)}get security(){let e=n.pluck(`security`,this.#e.middlewares||[]);return n.reject(n.isNil,e)}get scopes(){return this.#e.scopes}get tags(){return this.#e.tags}getOperationId(e){return this.#e.getOperationId?.(e)}async#i(e){try{return await this.#e.outputSchema.parseAsync(e)}catch(e){throw e instanceof t.ZodError?new N(e):e}}async#a({method:e,logger:t,ctx:n,response:r,...i}){for(let a of this.#e.middlewares||[])if(!(e===`options`&&!(a instanceof U))&&(Object.assign(n,await a.execute({...i,ctx:n,response:r,logger:t})),r.writableEnded)){t.warn(`A middleware has closed the stream. Accumulated context:`,n);break}}async#o({input:e,...n}){let r;try{r=await this.#e.inputSchema.parseAsync(e)}catch(e){throw e instanceof t.ZodError?new P(e):e}return this.#e.handler({...n,input:r})}async#s(e){await this.#e.resultHandler.execute(e)}async execute({request:e,response:t,logger:n,config:r}){let i=m(e),a={},o,s=g(e,r.inputSources);try{if(await this.#a({method:i,input:s,request:e,response:t,logger:n,ctx:a}),t.writableEnded)return;if(i===`options`)return void t.status(200).end();let r=await this.#o({input:s,logger:n,ctx:a});if(t.writableEnded)return;o={output:await this.#i(r),error:null}}catch(e){o={output:null,error:_(e)}}await this.#s({...o,input:s,request:e,response:t,logger:n,ctx:a})}},q=class{#e;constructor(...e){this.#e=e}apply(e,t){return t(e,o.static(...this.#e))}};const J=e=>S(e)&&`or`in e,Y=e=>S(e)&&`and`in e,X=e=>!Y(e)&&!J(e),Me=e=>{let t=n.filter(X,e),r=n.chain(n.prop(`and`),n.filter(Y,e)),[i,a]=n.partition(X,r),o=n.concat(t,i),s=n.filter(J,e);return n.map(n.prop(`or`),n.concat(s,a)).reduce((e,t)=>b(e,n.map(e=>X(e)?[e]:e.and,t),([e,t])=>n.concat(e,t)),n.reject(n.isEmpty,[o]))},Z=(e,t)=>Y(e)?n.chain(e=>Z(e,t),e.and):J(e)?n.chain(e=>Z(e,t),e.or):e.type===t?[e.name]:[],Ne=(e,t)=>new Set(n.chain(e=>Z(e,t),e)),Pe=e=>(t,...n)=>{e(t,...n),t===`get`&&e(`head`,...n)},Fe=e=>{let[t,n]=e.trim().split(/ (.+)/,2);return n&&u(t)?[n,t]:[e]},Ie=e=>e.trim().split(`/`).filter(Boolean).join(`/`),Q=({recognizeMethodDependentRoutes:e=!0},t,n)=>Object.entries(t).map(([t,r])=>{let[i,a]=e&&u(t)&&r instanceof K?[`/`,t]:Fe(t);return[[n||``].concat(Ie(i)||[]).join(`/`)||`/`,r,a]}),Le=(e,t)=>{throw new j(`Route with explicit method can only be assigned with Endpoint`,e,t)},Re=(e,t,n)=>{if(!(!n.size||n.has(e)))throw new j(`Method ${e} is not supported by the assigned Endpoint.`,e,t)},$=(e,t,n)=>{let r=t.includes(`:`)?p(t):t,i=`${e} ${r}`;if(n.has(i))throw new j(`Route has a duplicate: the normalized path "${r}" is already registered`,e,t);n.add(i)},ze=({routing:e,config:t,onEndpoint:n,onStatic:r})=>{let i=Q(t,e),a=new Set;for(let e=0;e<i.length;e++){let[o,s,c]=i[e];if(s instanceof K)if(c)$(c,o,a),Re(c,o,s.methods),n(c,o,s);else{let{methods:e}=s;for(let t of e.size?e:[`get`])$(t,o,a),n(t,o,s)}else c&&Le(c,o),s instanceof q?r&&s.apply(o,r):i.splice(e+1,0,...Q(t,s,o))}};export{x as $,ce as A,_ as B,fe as C,N as D,de as E,D as F,ae as G,h as H,T as I,ie as J,S as K,E as L,se as M,k as N,F as O,O as P,oe as Q,b as R,me as S,P as T,v as U,g as V,ee as W,f as X,p as Y,C as Z,xe as _,q as a,ge as b,ke as c,we as d,l as et,W as f,V as g,H as h,Me as i,A as j,j as k,De as l,U as m,Pe as n,s as nt,je as o,Ce as p,y as q,Ne as r,Oe as s,ze as t,u as tt,Te as u,_e as v,le as w,L as x,R as y,d as z};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "express-zod-api",
3
- "version": "29.3.1",
3
+ "version": "29.3.3",
4
4
  "description": "A Typescript framework to help you get an API server up and running with I/O schema validation and custom middlewares in minutes.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1 +0,0 @@
1
- import{globalRegistry as e,z as t}from"zod";import*as n from"ramda";import{isPromise as r}from"node:util/types";import i,{isHttpError as a}from"http-errors";import o from"express";const s={json:`application/json`,upload:`multipart/form-data`,raw:`application/octet-stream`,sse:`text/event-stream`,form:`application/x-www-form-urlencoded`},c=[`get`,`post`,`put`,`delete`,`patch`,`query`],l=[...c,`head`],u=e=>c.includes(e),d=t.object({}),f=/:([A-Za-z0-9_]+)/g,ee=e=>e.match(f)?.map(e=>e.slice(1))||[],p=(e,t=1)=>e.replace(f,()=>`:${t++}`),te=e=>{let t=(e.header(`content-type`)||``).toLowerCase().startsWith(s.upload);return`files`in e&&t},ne={get:[`query`,`params`],post:[`body`,`params`,`files`],put:[`body`,`params`],patch:[`body`,`params`],delete:[`query`,`params`],query:[`query`,`body`,`params`]},re=[`body`,`query`,`params`],m=e=>e.method.toLowerCase(),h=(e,t={})=>{if(e===`options`)return[];let n=e===`head`?`get`:u(e)?e:void 0;return(n?t[n]||ne[n]:void 0)||re},g=(e,t={})=>{let n=m(e);return h(n,t).filter(t=>t!==`files`||te(e)).reduce((t,n)=>Object.assign(t,e[n]),{})},_=e=>e instanceof Error?e:e instanceof t.ZodError?new t.ZodRealError(e.issues):Error(String(e)),v=e=>e instanceof t.ZodError?e.issues.map(({path:e,message:n})=>`${e.length?`${t.core.toDotPath(e)}: `:``}${n}`).join(`; `):e.message,y=(e,t)=>S(e)&&`_zod`in e&&(!t||n.path([`_zod`,`def`,`type`],e)===t),b=(e,t,r)=>e.length&&t.length?n.xprod(e,t).map(r):e.concat(t),x=e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase(),ie=(...e)=>{let t=n.chain(e=>e.split(/[^A-Z0-9]/gi),e);return n.chain(e=>e.replaceAll(/[A-Z]+/g,e=>`/${e}`).split(`/`),t).map(x).join(``)},ae=n.tryCatch((e,n)=>typeof t.parse(e,n),n.always(void 0)),S=e=>typeof e==`object`&&!!e,C={_cache:void 0,get env(){return C._cache??=process.env.NODE_ENV??`development`},get isProduction(){return C.env===`production`}},oe=(e,t)=>!!t&&e!==`head`,w=`x-brand`,T=t=>{let{[w]:n}=e.get(t)||{};if(typeof n==`symbol`||typeof n==`string`||typeof n==`number`)return n},E=t=>{let{examples:n}=e.get(t)||{};return Array.isArray(n)?n:[]},D=Symbol(`Buffer`),O=()=>t.custom(e=>Buffer.isBuffer(e),{error:`Expected Buffer`}).meta({[w]:D}),k=Symbol(`DateIn`),se=({examples:e,...n}={})=>t.union([t.iso.date(),t.iso.datetime({local:!0,offset:!0})]).meta({examples:e}).transform(e=>new Date(e)).pipe(t.date()).meta({...n,[w]:k}),A=Symbol(`DateOut`),ce=(e={})=>t.date().transform(e=>e.toISOString()).pipe(t.iso.datetime()).meta({...e,[w]:A});var j=class extends Error{name=`RoutingError`;cause;constructor(e,t,n){super(e),this.cause={method:t,path:n}}},le=class extends Error{name=`DocumentationError`;cause;constructor(e,{method:t,path:n,isResponse:r}){super(e),this.cause=`${r?`Response`:`Input`} schema of an Endpoint assigned to ${t.toUpperCase()} method of ${n} path.`}},M=class extends Error{name=`IOSchemaError`},ue=class extends M{cause;name=`DeepCheckError`;constructor(e){super(`Found`,{cause:e}),this.cause=e}},N=class extends M{cause;name=`OutputValidationError`;constructor(e){let n=new t.ZodError(e.issues.map(({path:e,...t})=>({...t,path:[`output`,...e]})));super(v(n),{cause:e}),this.cause=e}},P=class extends M{cause;name=`InputValidationError`;constructor(e){super(v(e),{cause:e}),this.cause=e}},F=class extends Error{cause;handled;name=`ResultHandlerError`;constructor(e,t){super(v(e),{cause:e}),this.cause=e,this.handled=t}},de=class extends Error{name=`MissingPeerError`;constructor(e){super(`Missing peer dependency: ${e}. Please install it to use the feature.`)}};const I=Symbol(`Form`),fe=e=>(e instanceof t.ZodObject?e:t.object(e)).meta({[w]:I}),L=Symbol(`Upload`),pe=e=>S(e)&&`name`in e&&`encoding`in e&&`mimetype`in e&&`data`in e&&`tempFilePath`in e&&`truncated`in e&&`size`in e&&`md5`in e&&`mv`in e,me=()=>t.custom(e=>pe(e)&&typeof e.name==`string`&&typeof e.encoding==`string`&&typeof e.mimetype==`string`&&Buffer.isBuffer(e.data)&&typeof e.tempFilePath==`string`&&typeof e.truncated==`boolean`&&typeof e.size==`number`&&typeof e.md5==`string`&&typeof e.mv==`function`,{error:({input:e})=>({message:`Expected file upload, received ${typeof e}`})}).meta({[w]:L}),R=Symbol(`Raw`),z=t.object({raw:O()}),he=e=>z.extend(e).meta({[w]:R});function ge(e){return e?he(e):z.meta({[w]:R})}const B=(e,{io:r,condition:i})=>n.tryCatch(()=>void t.toJSONSchema(e,{io:r,unrepresentable:`any`,override:({zodSchema:e})=>{if(i(e))throw new ue(e)}}),e=>e.cause)(),_e=(e,{io:r})=>{let i=[t.toJSONSchema(e,{io:r,unrepresentable:`any`})];for(let e=0;e<i.length;e++){let t=i[e];if(n.is(Object,t)){if(t.$ref===`#`)return!0;i.push(...n.values(t))}n.is(Array,t)&&i.push(...n.values(t))}return!1},ve=e=>B(e,{condition:e=>{let t=T(e);return typeof t==`symbol`&&[L,R,I].includes(t)},io:`input`}),ye=new Set([`nan`,`symbol`,`map`,`set`,`bigint`,`void`,`promise`,`never`,`function`]),be=(e,t)=>B(e,{io:t,condition:e=>{let n=T(e),{type:r}=e._zod.def;return!!(ye.has(r)||n===D||t===`input`&&(r===`date`||n===A)||t===`output`&&(n===k||n===R||n===L))}});var V=class e extends Set{constructor(e){if(super(),e)for(let t of e)Set.prototype.add.call(this,t)}add(e){throw TypeError(`Can not add to the read only Set`)}delete(e){throw TypeError(`Can not delete from the read only Set`)}clear(){throw TypeError(`Can not clear the read only Set`)}union(t){return new e(super.union(t))}intersection(t){return new e(super.intersection(t))}difference(t){return new e(super.difference(t))}symmetricDifference(t){return new e(super.symmetricDifference(t))}},xe=class{},H=class extends xe{#e;#t;#n;#r;constructor({input:e,security:t,statusCode:n,handler:r}){super(),this.#e=e,this.#t=t,this.#n=new V(typeof n==`number`?[n]:n),this.#r=r}get security(){return this.#t}get schema(){return this.#e}get statusCodes(){return this.#n}async execute({input:e,...n}){try{let t=await(this.#e||d).parseAsync(e);return this.#r({...n,input:t})}catch(e){throw e instanceof t.ZodError?new P(e):e}}},U=class extends H{constructor(e,{provider:t=()=>({}),transformer:n=e=>e,statusCode:i}={}){super({statusCode:i,handler:async({request:i,response:a})=>{let{promise:o,resolve:s,reject:c}=Promise.withResolvers(),l=e=>{if(e&&e instanceof Error)return c(n(e));s(t(i,a))},u=e(i,a,l);return r(u)&&u.catch(l),o}})}};const W={positive:200,negative:400},Se=Object.keys(W),G=e=>e<400;function Ce(e){return e instanceof t.ZodType?{schema:e}:e}const we=(e,{variant:r,args:i})=>{typeof e==`function`&&(e=e(...i));let a={statusCodes:[W[r]],mimeTypes:[s.json]};if(e instanceof t.ZodType)return[{schema:e,...a}];if(Array.isArray(e)&&!e.length)throw new F(Error(`At least one ${r} response schema required.`));let o=(Array.isArray(e)?e:[e]).map(({schema:e,statusCode:t,mimeType:n})=>({schema:e,statusCodes:typeof t==`number`?[t]:t||a.statusCodes,mimeTypes:typeof n==`string`?[n]:n===void 0?a.mimeTypes:n})),c=n.chain(n.prop(`statusCodes`),o),l=c.find(e=>G(e)===(r===`negative`));if(l!==void 0)throw new F(Error(`The status code ${l} is not valid for a ${r} API response.`));if(o.length>1){let e=n.find(e=>c.indexOf(e)!==c.lastIndexOf(e),c);if(e!==void 0)throw new F(Error(`The status code ${e} is used by multiple response schemas.`))}return o},Te=(e,t,n)=>{let r=new Set(Array.from(t).filter(e=>G(e)===(n===`positive`)));if(!r.size)return e;if(e.length===1)return e.map(e=>({...e,statusCodes:Array.from(r)}));let i=[],a=e.reduce((e,{statusCodes:t,...n})=>{let a=new Set(t).intersection(r);return a.size?(i.push({...n,statusCodes:Array.from(a)}),e.difference(a)):e},new Set(r));if(a.size){let e=Array.from(a).join(`, `),t=a.size>1;throw new F(Error(`The ResultHandler defines multiple ${n} response schemas, but the overriding status code${t?`s`:``} ${e} of the Endpoint ${t?`are`:`is`} not listed for any of them, therefore it is unclear how such override${t?`s`:``} would be handled. Consider adding ${t?`them`:`it`} to ResultHandler.`))}return i},Ee=(e,t,{url:n},r)=>!e.expose&&t.error(`Server side error`,{error:e,url:n,payload:r}),De=e=>a(e)?e:i(e instanceof P?400:500,v(e),{cause:e.cause||e}),Oe=e=>C.isProduction&&!e.expose?i(e.statusCode).message:e.message,ke=e=>Object.entries(e._zod.def.shape).reduce((e,[t,r])=>b(e,E(r).map(n.objOf(t)),([e,t])=>({...e,...t})),[]);var K=class{nest(e){return{...e,"":this}}},Ae=class r extends K{#e;#t;#n=n.once(()=>{if(E(this.#e.outputSchema).length||!y(this.#e.outputSchema,`object`))return;let t=ke(this.#e.outputSchema);if(!t.length)return;let n=this.#e.outputSchema.meta();e.remove(this.#e.outputSchema).add(this.#e.outputSchema,{...n,examples:t})});constructor(e){super(),this.#e=e}#r(e){return new r({...this.#e,...e})}deprecated(){return this.#r({deprecated:!0})}get isDeprecated(){return this.#e.deprecated||!1}get description(){return this.#e.description}get summary(){return this.#e.summary}get methods(){return this.#e.methods}get inputSchema(){return this.#e.inputSchema}get outputSchema(){return this.#e.outputSchema}getProbableRequestType(e){return e===`query`?`form`:this.#t??=(()=>{let e=ve(this.#e.inputSchema);if(e){let t=T(e);if(t===L)return`upload`;if(t===R)return`raw`;if(t===I)return`form`}return`json`})()}getResponses(e){e===`positive`&&this.#n();let t=e===`negative`?this.#e.resultHandler.getNegativeResponse():this.#e.resultHandler.getPositiveResponse(this.#e.outputSchema);return Object.freeze(this.#e.statusCodes.size?Te(t,this.#e.statusCodes,e):t)}get security(){let e=n.pluck(`security`,this.#e.middlewares||[]);return n.reject(n.isNil,e)}get scopes(){return Object.freeze(this.#e.scopes||[])}get tags(){return Object.freeze(this.#e.tags||[])}getOperationId(e){return this.#e.getOperationId?.(e)}async#i(e){try{return await this.#e.outputSchema.parseAsync(e)}catch(e){throw e instanceof t.ZodError?new N(e):e}}async#a({method:e,logger:t,ctx:n,response:r,...i}){for(let a of this.#e.middlewares||[])if(!(e===`options`&&!(a instanceof U))&&(Object.assign(n,await a.execute({...i,ctx:n,response:r,logger:t})),r.writableEnded)){t.warn(`A middleware has closed the stream. Accumulated context:`,n);break}}async#o({input:e,...n}){let r;try{r=await this.#e.inputSchema.parseAsync(e)}catch(e){throw e instanceof t.ZodError?new P(e):e}return this.#e.handler({...n,input:r})}async#s(e){await this.#e.resultHandler.execute(e)}async execute({request:e,response:t,logger:n,config:r}){let i=m(e),a={},o,s=g(e,r.inputSources);try{if(await this.#a({method:i,input:s,request:e,response:t,logger:n,ctx:a}),t.writableEnded)return;if(i===`options`)return void t.status(200).end();let r=await this.#o({input:s,logger:n,ctx:a});if(t.writableEnded)return;o={output:await this.#i(r),error:null}}catch(e){o={output:null,error:_(e)}}await this.#s({...o,input:s,request:e,response:t,logger:n,ctx:a})}},q=class{#e;constructor(...e){this.#e=e}apply(e,t){return t(e,o.static(...this.#e))}};const J=e=>S(e)&&`or`in e,Y=e=>S(e)&&`and`in e,X=e=>!Y(e)&&!J(e),je=e=>{let t=n.filter(X,e),r=n.chain(n.prop(`and`),n.filter(Y,e)),[i,a]=n.partition(X,r),o=n.concat(t,i),s=n.filter(J,e);return n.map(n.prop(`or`),n.concat(s,a)).reduce((e,t)=>b(e,n.map(e=>X(e)?[e]:e.and,t),([e,t])=>n.concat(e,t)),n.reject(n.isEmpty,[o]))},Z=(e,t)=>Y(e)?n.chain(e=>Z(e,t),e.and):J(e)?n.chain(e=>Z(e,t),e.or):e.type===t?[e.name]:[],Me=(e,t)=>new Set(n.chain(e=>Z(e,t),e)),Ne=e=>(t,...n)=>{e(t,...n),t===`get`&&e(`head`,...n)},Pe=e=>{let[t,n]=e.trim().split(/ (.+)/,2);return n&&u(t)?[n,t]:[e]},Fe=e=>e.trim().split(`/`).filter(Boolean).join(`/`),Q=({recognizeMethodDependentRoutes:e=!0},t,n)=>Object.entries(t).map(([t,r])=>{let[i,a]=e&&u(t)&&r instanceof K?[`/`,t]:Pe(t);return[[n||``].concat(Fe(i)||[]).join(`/`)||`/`,r,a]}),Ie=(e,t)=>{throw new j(`Route with explicit method can only be assigned with Endpoint`,e,t)},Le=(e,t,n)=>{if(!(!n.size||n.has(e)))throw new j(`Method ${e} is not supported by the assigned Endpoint.`,e,t)},$=(e,t,n)=>{let r=t.includes(`:`)?p(t):t,i=`${e} ${r}`;if(n.has(i))throw new j(`Route has a duplicate: the normalized path "${r}" is already registered`,e,t);n.add(i)},Re=({routing:e,config:t,onEndpoint:n,onStatic:r})=>{let i=Q(t,e),a=new Set;for(let e=0;e<i.length;e++){let[o,s,c]=i[e];if(s instanceof K)if(c)$(c,o,a),Le(c,o,s.methods),n(c,o,s);else{let{methods:e}=s;for(let t of e.size?e:[`get`])$(t,o,a),n(t,o,s)}else c&&Ie(c,o),s instanceof q?r&&s.apply(o,r):i.splice(e+1,0,...Q(t,s,o))}};export{x as $,ce as A,_ as B,fe as C,N as D,de as E,D as F,ae as G,h as H,T as I,ie as J,S as K,E as L,se as M,k as N,F as O,O as P,oe as Q,b as R,me as S,P as T,v as U,g as V,ee as W,f as X,p as Y,C as Z,be as _,q as a,ge as b,Oe as c,Ce as d,l as et,W as f,V as g,H as h,je as i,A as j,j as k,Ee as l,U as m,Ne as n,s as nt,Ae as o,Se as p,y as q,Me as r,De as s,Re as t,u as tt,we as u,_e as v,le as w,L as x,R as y,d as z};