express-zod-api 29.0.0-beta.6 → 29.0.1
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 +26 -0
- package/dist/documentation.d.ts +8 -7
- package/dist/documentation.js +1 -1
- package/dist/errors-CkGs6EY3.d.ts +79 -0
- package/dist/index.d.ts +11 -42
- package/dist/index.js +3 -3
- package/dist/integration.js +5 -5
- package/dist/{json-schema-helpers-DrRPjVl7.js → json-schema-helpers-BY2DVvm4.js} +1 -1
- package/dist/{peer-helpers-DnGohNyk.js → peer-helpers-CuO0_h1y.js} +1 -1
- package/dist/routing-walker-DjzH37jF.js +1 -0
- package/dist/{security-CK7Z85YT.js → security-ts3gqWG9.js} +1 -1
- package/package.json +3 -3
- package/dist/documentation-helpers-C3vkQCz2.d.ts +0 -31
- package/dist/routing-walker-DJRnc3hk.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## Version 29
|
|
4
4
|
|
|
5
|
+
### v29.0.1
|
|
6
|
+
|
|
7
|
+
- Minor performance tuning for `Documentation` generator:
|
|
8
|
+
- Collecting security headers and cookie names only when the corresponding input sources are enabled;
|
|
9
|
+
- Reduced some calculations required to depict request body and parameters.
|
|
10
|
+
- Deprecating the `DocumentationError` export from `express-zod-api`:
|
|
11
|
+
- This export will be removed in the next major version;
|
|
12
|
+
- Import it from `express-zod-api/documentation` subpath instead.
|
|
13
|
+
|
|
5
14
|
### v29.0.0
|
|
6
15
|
|
|
7
16
|
- Supported Node.js versions: `^22.19.0 || ^24.11.0 || ^26.0.0`;
|
|
@@ -72,6 +81,23 @@
|
|
|
72
81
|
|
|
73
82
|
## Version 28
|
|
74
83
|
|
|
84
|
+
### v28.7.11
|
|
85
|
+
|
|
86
|
+
- Added missing path params check to the Documentation generator:
|
|
87
|
+
- An Endpoint assigned to `get /users/:id` must declare the `id` property on the `input` schema;
|
|
88
|
+
- Similar check is already implemented in runtime (development mode only);
|
|
89
|
+
- Found and reported by [@marco-carvalho](https://github.com/marco-carvalho).
|
|
90
|
+
|
|
91
|
+
### v28.7.10
|
|
92
|
+
|
|
93
|
+
- Fixed issue for routes having differently named path params:
|
|
94
|
+
- In case of same method it will now always throw a RoutingError:
|
|
95
|
+
- Example: having both `get /items/:id` and `get /items/:slug` routes.
|
|
96
|
+
- If methods are different, Documentation generator will throw `DocumentationError`:
|
|
97
|
+
- Example: OpenAPI standard does not allow having both `get /users/:id` and `delete /users/:userId`;
|
|
98
|
+
- See https://spec.openapis.org/oas/v3.1.0#paths-object for details.
|
|
99
|
+
- Found and reported by [@marco-carvalho](https://github.com/marco-carvalho).
|
|
100
|
+
|
|
75
101
|
### v28.7.9
|
|
76
102
|
|
|
77
103
|
- Fixes the issue where the same `.meta({ id })` could be used on different schemas:
|
package/dist/documentation.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { M as ResponseVariant, g as CommonConfig, t as Routing } from "./routing-xQnwfH2D.js";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
o as
|
|
6
|
-
|
|
7
|
-
t as
|
|
8
|
-
|
|
3
|
+
c as IsHeader,
|
|
4
|
+
l as depictTags,
|
|
5
|
+
o as BrandHandling,
|
|
6
|
+
s as Depicter,
|
|
7
|
+
t as DocumentationError,
|
|
8
|
+
u as trimSummary,
|
|
9
|
+
} from "./errors-CkGs6EY3.js";
|
|
9
10
|
import { InfoObject, OpenApiBuilder, ServerObject } from "openapi3-ts/oas32";
|
|
10
11
|
type Component = `${ResponseVariant}Response` | "requestParameter" | "requestBody";
|
|
11
12
|
/** @desc user defined function that creates a component description from its properties */
|
|
@@ -72,4 +73,4 @@ interface DocumentationParams {
|
|
|
72
73
|
declare class Documentation extends OpenApiBuilder {
|
|
73
74
|
constructor({ hasHeadMethod, ...rest }: DocumentationParams);
|
|
74
75
|
}
|
|
75
|
-
export { type Depicter, Documentation };
|
|
76
|
+
export { type Depicter, Documentation, DocumentationError };
|
package/dist/documentation.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as e,G as t,H as n,J as r,K as i,M as a,N as o,O as s,Q as c,U as l,V as u,Y as d,g as f,n as p,o as m,q as h,t as g,v as _,x as v,z as y}from"./routing-walker-DJRnc3hk.js";import{t as b}from"./json-schema-helpers-DrRPjVl7.js";import{n as x,t as S}from"./security-CK7Z85YT.js";import{z as C}from"zod";import*as w from"ramda";import{OpenApiBuilder as T,isReferenceObject as E,isSchemaObject as D}from"openapi3-ts/oas32";let O;const k=()=>O??=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(`.`)),A={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},j=e=>e.replace(h,e=>`{${e.slice(1)}}`),ee=({},e)=>{if(e.isResponse)throw new v(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},te=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),M=({zodSchema:e,jsonSchema:n})=>{if(!t(e,`union`)||!(`discriminator`in e._zod.def))return n;let r=e._zod.def.discriminator;return{...n,discriminator:n.discriminator??{propertyName:r}}},N=w.tryCatch(({jsonSchema:e})=>{if(!e.allOf)throw`no allOf`;return b(e,`throw`)},(e,{jsonSchema:t})=>t),P=({jsonSchema:e})=>{if(!e.anyOf||!e.anyOf.length)return e;let t=e.anyOf[0];return Object.assign(t,{type:V(t.type)})},F=e=>e,I=({jsonSchema:e},t)=>{if(t.isResponse)throw new v(`Please use ez.dateOut() for output.`,t);return e},L=({jsonSchema:e},t)=>{if(!t.isResponse)throw new v(`Please use ez.dateIn() for input.`,t);return e},R=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),z=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,B=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return A?.[t]},V=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],H=({zodSchema:e,jsonSchema:r},i)=>{let a=e._zod.def[i.isResponse?`out`:`in`],o=e._zod.def[i.isResponse?`in`:`out`];if(!t(a,`transform`))return r;let s=F(J(o,{ctx:i}));if(D(s))if(i.isResponse){let e=n(a,B(s));if(e&&[`number`,`string`,`boolean`].includes(e))return{...r,type:e}}else{let{type:e,...t}=s;return{...t,format:`${t.format||e} (preprocessed)`}}return r},U=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!l(t.properties.raw)?e:t.properties.raw},W=e=>e.length?w.fromPairs(w.zip(w.times(e=>`example${e+1}`,e.length),w.map(w.objOf(`dataValue`),e))):void 0,G=(e,t)=>t?.has(e)||e.startsWith(`x-`)||k().has(e),K=({path:e,method:t,request:n,inputSources:r,makeRef:a,composition:o,isHeader:s,securityHeaders:c,securityCookies:d,description:f=`${t.toUpperCase()} ${e} Parameter`})=>{let p=b(n),m=u(e),h=r.includes(`query`),g=r.includes(`params`),_=r.includes(`headers`),v=r.includes(`cookies`)||r.includes(`signedCookies`),y=n=>{if(g&&m.includes(n))return`path`;if(v&&d?.has(n))return`cookie`;if(_&&(s?.(n,t,e)??G(n,c)))return`header`;if(h&&t!==`query`)return`query`};return Object.entries(p.properties).reduce((e,[t,n])=>{if(!l(n))return e;let r=y(t);if(!r)return e;let s=F(n),c=o===`components`?a(n.id||JSON.stringify(n),s,n.id||i(f,t)):s;return e.concat({name:t,in:r,deprecated:n.deprecated,required:p.required?.includes(t)||!1,description:s.description||f,schema:c,examples:W(D(s)&&s.examples?.length?s.examples:w.pluck(t,p.examples?.filter(w.both(l,w.has(t)))||[]))})},[])},q={nullable:P,union:M,bigint:R,intersection:N,tuple:z,pipe:H,[e]:I,[s]:L,[_]:ee,[f]:U,[a]:te},ne=(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(w.is(Object,a)){if(E(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,F(r),t).$ref}continue}r.push(...w.values(a))}w.is(Array,a)&&r.push(...w.values(a))}return e},J=(e,{ctx:t,rules:n=q})=>{let{$defs:r={},properties:i={}}=C.toJSONSchema(C.object({subject:e}),{unrepresentable:`any`,io:t.isResponse?`output`:`input`,override:e=>{let r=C.globalRegistry.get(e.zodSchema)?.id;if(r){let n=t.seenIds.get(r);if(n&&n!==e.zodSchema)throw new v(`The meta id "${r}" is used by two different schemas. Please make the ids unique or reuse the same schema instance.`,t);t.seenIds.set(r,e.zodSchema)}let i=o(e.zodSchema),a=n[i&&i in n?i:e.zodSchema._zod.def.type];if(a){let n={...a(e,t)};for(let t in e.jsonSchema)delete e.jsonSchema[t];Object.assign(e.jsonSchema,n)}}});return ne(l(i.subject)?i.subject:{},r,t)},Y=(e,t)=>{if(E(e))return[e,!1];let n=!1,r=w.map(e=>{let[r,i]=Y(e,t);return n||=i,r}),i=w.omit(t),a={properties:i,examples:w.map(i),required:w.without(t),allOf:r,oneOf:r,anyOf:r},o=w.evolve(a,e);return[o,n||!!o.required?.length]},X=({method:e,path:t,schema:n,mimeTypes:a,variant:o,makeRef:s,composition:l,hasMultipleStatusCodes:u,statusCode:f,brandHandling:p,seenIds:m,description:h=`${e.toUpperCase()} ${t} ${d(o)} response ${u?f:``}`.trim()})=>{if(!r(e,a))return{description:h};let g=F(J(n,{rules:{...p,...q},ctx:{isResponse:!0,makeRef:s,path:t,method:e,seenIds:m}})),_=[];D(g)&&g.examples&&(_.push(...g.examples),delete g.examples);let v=l===`components`?s(n,g,i(h)):g;return{description:h,content:w.fromPairs(a.map(e=>[e,{[e===c.sse?`itemSchema`:`schema`]:v,examples:W(_)}]))}},Z=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},re=({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},ie=({name:e})=>({type:`apiKey`,in:`header`,name:e}),ae=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),oe=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),se=({flows:e={},oauth2MetadataUrl:t})=>({type:`oauth2`,flows:w.map(e=>({...e,scopes:e.scopes||{}}),w.reject(w.isNil,e)),oauth2MetadataUrl:t}),Q=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?Z(e):e.type===`input`?re(e,t):e.type===`header`?ie(e):e.type===`cookie`?ae(e):e.type===`openid`?oe(e):se(e);return e.map(e=>e.map(({deprecated:e,...t})=>({...n(t),deprecated:e})))},ce=(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:[]})},{})),le=({schema:e,brandHandling:t,makeRef:n,path:r,method:i,seenIds:a})=>J(e,{rules:{...t,...q},ctx:{isResponse:!1,makeRef:n,path:r,method:i,seenIds:a}}),ue=({method:e,path:t,schema:n,request:r,mimeType:a,makeRef:o,composition:s,paramNames:u,description:d=`${e.toUpperCase()} ${t} Request body`})=>{let[f,p]=Y(r,u),m=F(f),h=[];D(m)&&m.examples&&(h.push(...m.examples),delete m.examples);let g={schema:s===`components`?o(n,m,i(d)):m,examples:W(h.length?h:b(r).examples?.filter(e=>l(e)&&!Array.isArray(e)).map(w.omit(u))||[])},_={description:d,content:{[a]:g}};return(p||a===c.raw)&&(_.required=!0),_},de=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)},[]),fe=(e,t=50)=>!e||e.length<=t?e:e.slice(0,Math.max(1,t||0)-1)+`…`,$=e=>e.length?e.slice():void 0,pe=({description:e,summary:t=e,trim:n})=>n(t);var me=class extends T{#e=new Map;#t=new Map;#n=new Map;#r(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}`}}#i(e,t,n){let r=n||i(t,e),a=this.#t.get(r);if(a===void 0)return this.#t.set(r,1),r;if(n)throw new v(`Duplicated operationId: "${n}"`,{method:t,isResponse:!1,path:e});return a++,this.#t.set(r,a),`${r}${a}`}#a(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}`}#o({tags:e,server:t,info:n={title:`Generated by Express Zod API`,version:`0.0.0`}}){if(this.addInfo(n),e&&(this.rootDoc.tags=de(e)),t)for(let e of Array.isArray(t)?t:[t])this.addServer(typeof e==`string`?{url:e}:e)}#s({config:e,descriptions:t,brandHandling:n,isHeader:r,summarizer:i=pe,composition:a=`inline`}){let o={composition:a,brandHandling:n,makeRef:this.#r.bind(this),seenIds:new Map};return(n,a,s)=>{let l={...o,path:a,method:n,endpoint:s},{description:u,summary:d,scopes:f,inputSchema:p}=s,h=y(n,e.inputSources),g=this.#i(a,n,s.getOperationId(n)),_=le({...l,schema:p}),v=K({...l,inputSources:h,isHeader:r,securityHeaders:S(s.security,`header`),securityCookies:S(s.security,`cookie`),request:_,description:t?.requestParameter?.({method:n,path:a,operationId:g})}),b={};for(let e of m){let r=s.getResponses(e);for(let{mimeTypes:i,schema:o,statusCodes:s}of r)for(let c of s)b[c]=X({...l,variant:e,schema:o,mimeTypes:i,statusCode:c,hasMultipleStatusCodes:r.length>1||s.length>1,description:t?.[`${e}Response`]?.({method:n,path:a,operationId:g,statusCode:c})})}let C=h.includes(`body`)?ue({...l,request:_,paramNames:w.pluck(`name`,v),schema:p,mimeType:c[s.getProbableRequestType(n)],description:t?.requestBody?.({method:n,path:a,operationId:g})}):void 0,T=ce(Q(x(s.security),h),f,e=>{let t=this.#a(e);return this.addSecurityScheme(t,e),t}),E={operationId:g,summary:i({summary:d,description:u,trim:fe}),description:u,deprecated:s.isDeprecated||void 0,tags:$(s.tags),parameters:$(v),requestBody:C,security:$(T),responses:b};this.addPath(j(a),{[n]:E})}}constructor({hasHeadMethod:e=!0,...t}){super(),this.#o(t);let n=this.#s(t),r=e?p(n):n;g({...t,onEndpoint:r})}};export{me as Documentation};
|
|
1
|
+
import{$ as e,A as t,G as n,H as r,J as i,K as a,M as o,N as s,O as c,U as l,V as u,X as d,Y as f,g as p,n as m,o as h,q as g,t as _,v,x as y,z as b}from"./routing-walker-DjzH37jF.js";import{t as x}from"./json-schema-helpers-BY2DVvm4.js";import{n as S,t as C}from"./security-ts3gqWG9.js";import{z as w}from"zod";import*as T from"ramda";import{OpenApiBuilder as E,isReferenceObject as D,isSchemaObject as O}from"openapi3-ts/oas32";let k;const A=()=>k??=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(`.`)),j={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},M=e=>e.replace(i,e=>`{${e.slice(1)}}`),ee=({},e)=>{if(e.isResponse)throw new y(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},te=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),N=({zodSchema:e,jsonSchema:t})=>{if(!n(e,`union`)||!(`discriminator`in e._zod.def))return t;let r=e._zod.def.discriminator;return{...t,discriminator:t.discriminator??{propertyName:r}}},P=T.tryCatch(({jsonSchema:e})=>{if(!e.allOf)throw`no allOf`;return x(e,`throw`)},(e,{jsonSchema:t})=>t),F=({jsonSchema:e})=>{if(!e.anyOf||!e.anyOf.length)return e;let t=e.anyOf[0];return Object.assign(t,{type:H(t.type)})},I=e=>e,L=({jsonSchema:e},t)=>{if(t.isResponse)throw new y(`Please use ez.dateOut() for output.`,t);return e},R=({jsonSchema:e},t)=>{if(!t.isResponse)throw new y(`Please use ez.dateIn() for input.`,t);return e},z=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),B=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,V=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return j?.[t]},H=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],U=({zodSchema:e,jsonSchema:t},i)=>{let a=e._zod.def[i.isResponse?`out`:`in`],o=e._zod.def[i.isResponse?`in`:`out`];if(!n(a,`transform`))return t;let s=I(Y(o,{ctx:i}));if(O(s))if(i.isResponse){let e=r(a,V(s));if(e&&[`number`,`string`,`boolean`].includes(e))return{...t,type:e}}else{let{type:e,...t}=s;return{...t,format:`${t.format||e} (preprocessed)`}}return t},W=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!l(t.properties.raw)?e:t.properties.raw},G=e=>e.length?T.fromPairs(T.zip(T.times(e=>`example${e+1}`,e.length),T.map(T.objOf(`dataValue`),e))):void 0,K=(e,t)=>t?.has(e)||e.startsWith(`x-`)||A().has(e),q=({path:e,method:t,flatRequest:n,inputSources:r,makeRef:i,composition:o,isHeader:s,security:c,description:d=`${t.toUpperCase()} ${e} Parameter`})=>{let f=new Set(u(e)),p=r.includes(`query`),m=r.includes(`params`),h=r.includes(`headers`),g=r.includes(`cookies`)||r.includes(`signedCookies`),_;h&&c&&(_=C(c,`header`));let v;g&&c&&(v=C(c,`cookie`));let b=n=>{if(m&&f.has(n)&&f.delete(n))return`path`;if(g&&v?.has(n))return`cookie`;if(h&&(s?.(n,t,e)??K(n,_)))return`header`;if(p&&t!==`query`)return`query`},x=Object.entries(n.properties).reduce((e,[t,r])=>{if(!l(r))return e;let s=b(t);if(!s)return e;let c=I(r),u=o===`components`?i(r.id||JSON.stringify(r),c,r.id||a(d,t)):c;return e.concat({name:t,in:s,deprecated:r.deprecated,required:n.required?.includes(t)||!1,description:c.description||d,schema:u,examples:G(O(c)&&c.examples?.length?c.examples:T.pluck(t,n.examples?.filter(T.both(l,T.has(t)))||[]))})},[]);if(f.size)throw new y(`The input schema is missing the path parameter "${[...f][0]}"`,{method:t,path:e,isResponse:!1});return x},J={nullable:F,union:N,bigint:z,intersection:P,tuple:B,pipe:U,[t]:L,[c]:R,[v]:ee,[p]:W,[o]:te},ne=(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(T.is(Object,a)){if(D(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,I(r),t).$ref}continue}r.push(...T.values(a))}T.is(Array,a)&&r.push(...T.values(a))}return e},Y=(e,{ctx:t,rules:n=J})=>{let{$defs:r={},properties:i={}}=w.toJSONSchema(w.object({subject:e}),{unrepresentable:`any`,io:t.isResponse?`output`:`input`,override:e=>{let r=w.globalRegistry.get(e.zodSchema)?.id;if(r){let n=t.seenIds.get(r);if(n&&n!==e.zodSchema)throw new y(`The meta id "${r}" is used by two different schemas. Please make the ids unique or reuse the same schema instance.`,t);t.seenIds.set(r,e.zodSchema)}let i=s(e.zodSchema),a=n[i&&i in n?i:e.zodSchema._zod.def.type];if(a){let n={...a(e,t)};for(let t in e.jsonSchema)delete e.jsonSchema[t];Object.assign(e.jsonSchema,n)}}});return ne(l(i.subject)?i.subject:{},r,t)},X=(e,t)=>{if(D(e))return[e,!1];let n=!1,r=T.map(e=>{let[r,i]=X(e,t);return n||=i,r}),i=T.omit(t),a={properties:i,examples:T.map(i),required:T.without(t),allOf:r,oneOf:r,anyOf:r},o=T.evolve(a,e);return[o,n||!!o.required?.length]},Z=({method:t,path:n,schema:r,mimeTypes:i,variant:o,makeRef:s,composition:c,hasMultipleStatusCodes:l,statusCode:u,brandHandling:p,seenIds:m,description:h=`${t.toUpperCase()} ${n} ${d(o)} response ${l?u:``}`.trim()})=>{if(!f(t,i))return{description:h};let g=I(Y(r,{rules:{...p,...J},ctx:{isResponse:!0,makeRef:s,path:n,method:t,seenIds:m}})),_=[];O(g)&&g.examples&&(_.push(...g.examples),delete g.examples);let v=c===`components`?s(r,g,a(h)):g;return{description:h,content:T.fromPairs(i.map(t=>[t,{[t===e.sse?`itemSchema`:`schema`]:v,examples:G(_)}]))}},re=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},ie=({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},ae=({name:e})=>({type:`apiKey`,in:`header`,name:e}),oe=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),se=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),Q=({flows:e={},oauth2MetadataUrl:t})=>({type:`oauth2`,flows:T.map(e=>({...e,scopes:e.scopes||{}}),T.reject(T.isNil,e)),oauth2MetadataUrl:t}),ce=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?re(e):e.type===`input`?ie(e,t):e.type===`header`?ae(e):e.type===`cookie`?oe(e):e.type===`openid`?se(e):Q(e);return e.map(e=>e.map(({deprecated:e,...t})=>({...n(t),deprecated:e})))},le=(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:[]})},{})),ue=({schema:e,brandHandling:t,makeRef:n,path:r,method:i,seenIds:a})=>Y(e,{rules:{...t,...J},ctx:{isResponse:!1,makeRef:n,path:r,method:i,seenIds:a}}),de=({method:t,path:n,schema:r,bodyJsonSchema:i,hasRequiredBodyProps:o,flatRequest:s,mimeType:c,makeRef:u,composition:d,paramNames:f,description:p=`${t.toUpperCase()} ${n} Request body`})=>{let m=I(i),h=[];O(m)&&m.examples&&(h.push(...m.examples),delete m.examples);let g={schema:d===`components`?u(r,m,a(p)):m,examples:G(h.length?h:s.examples?.filter(e=>l(e)&&!Array.isArray(e)).map(T.omit(f))||[])},_={description:p,content:{[c]:g}};return(o||c===e.raw)&&(_.required=!0),_},fe=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)},[]),pe=(e,t=50)=>!e||e.length<=t?e:e.slice(0,Math.max(1,t||0)-1)+`…`,$=e=>e.length?e.slice():void 0,me=({description:e,summary:t=e,trim:n})=>n(t);var he=class extends E{#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,t,n){let r=n||a(t,e),i=this.#t.get(r);if(i===void 0)return this.#t.set(r,1),r;if(n)throw new y(`Duplicated operationId: "${n}"`,{method:t,isResponse:!1,path:e});return i++,this.#t.set(r,i),`${r}${i}`}#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=fe(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 n=g(t),r=this.#r.get(n);if(r!==void 0&&r!==t)throw new y(`Path has a duplicate: the normalized path "${n}" is already registered with different parameter names at "${r}"`,{method:e,path:t,isResponse:!1});r===void 0&&this.#r.set(n,t)}#l({config:t,descriptions:n,brandHandling:r,isHeader:i,summarizer:a=me,composition:o=`inline`}){let s={composition:o,brandHandling:r,makeRef:this.#i.bind(this),seenIds:new Map};return(r,o,c)=>{this.#c(r,o);let l={...s,path:o,method:r,endpoint:c},{description:u,summary:d,scopes:f,inputSchema:p,security:m}=c,g=b(r,t.inputSources),_=this.#a(o,r,c.getOperationId(r)),v=ue({...l,schema:p}),y=x(v),C=q({...l,inputSources:g,isHeader:i,flatRequest:y,security:m,description:n?.requestParameter?.({method:r,path:o,operationId:_})}),w={};for(let e of h){let t=c.getResponses(e);for(let{mimeTypes:i,schema:a,statusCodes:s}of t)for(let c of s)w[c]=Z({...l,variant:e,schema:a,mimeTypes:i,statusCode:c,hasMultipleStatusCodes:t.length>1||s.length>1,description:n?.[`${e}Response`]?.({method:r,path:o,operationId:_,statusCode:c})})}let E;if(g.includes(`body`)){let t=T.pluck(`name`,C),[i,a]=X(v,t);E=de({...l,bodyJsonSchema:i,hasRequiredBodyProps:a,flatRequest:y,paramNames:t,schema:p,mimeType:e[c.getProbableRequestType(r)],description:n?.requestBody?.({method:r,path:o,operationId:_})})}let D=le(ce(S(m),g),f,e=>{let t=this.#o(e);return this.addSecurityScheme(t,e),t}),O={operationId:_,summary:a({summary:d,description:u,trim:pe}),description:u,deprecated:c.isDeprecated||void 0,tags:$(c.tags),parameters:$(C),requestBody:E,security:$(D),responses:w};this.addPath(M(o),{[r]:O})}}constructor({hasHeadMethod:e=!0,...t}){super(),this.#s(t);let n=this.#l(t),r=e?m(n):n;_({...t,onEndpoint:r})}};export{he as Documentation,y as DocumentationError};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { D as ClientMethod, O as Method, f as Tag } from "./routing-xQnwfH2D.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { ReferenceObject, SchemaObjectValue, TagObject } from "openapi3-ts/oas32";
|
|
4
|
+
interface ReqResCommons {
|
|
5
|
+
makeRef: (key: object | string, value: SchemaObjectValue | ReferenceObject, proposedName?: string) => ReferenceObject;
|
|
6
|
+
path: string;
|
|
7
|
+
method: ClientMethod;
|
|
8
|
+
seenIds: Map<string, z.core.$ZodType>;
|
|
9
|
+
}
|
|
10
|
+
interface OpenAPIContext extends ReqResCommons {
|
|
11
|
+
isResponse: boolean;
|
|
12
|
+
}
|
|
13
|
+
type Depicter = (
|
|
14
|
+
zodCtx: {
|
|
15
|
+
zodSchema: z.core.$ZodType;
|
|
16
|
+
jsonSchema: z.core.JSONSchema.BaseSchema;
|
|
17
|
+
},
|
|
18
|
+
oasCtx: OpenAPIContext,
|
|
19
|
+
) => z.core.JSONSchema.BaseSchema | SchemaObjectValue;
|
|
20
|
+
/** @desc Using defaultIsHeader when returns null or undefined */
|
|
21
|
+
type IsHeader = (name: string, method: ClientMethod, path: string) => boolean | null | undefined;
|
|
22
|
+
type BrandHandling = Record<string | symbol, Depicter>;
|
|
23
|
+
interface TagDetails extends Pick<TagObject, "summary" | "description" | "externalDocs" | "kind"> {
|
|
24
|
+
/** @desc shorthand for externalDocs.url */
|
|
25
|
+
url?: string;
|
|
26
|
+
parent?: Tag;
|
|
27
|
+
}
|
|
28
|
+
declare const depictTags: (tags: Partial<Record<Tag, string | TagDetails>>) => TagObject[];
|
|
29
|
+
/** @desc Ensures the summary string does not exceed the limit */
|
|
30
|
+
declare const trimSummary: (summary?: string, limit?: number) => string | undefined;
|
|
31
|
+
/** @desc An error related to the wrong Routing declaration */
|
|
32
|
+
declare class RoutingError extends Error {
|
|
33
|
+
name: string;
|
|
34
|
+
readonly cause: {
|
|
35
|
+
method: Method;
|
|
36
|
+
path: string;
|
|
37
|
+
};
|
|
38
|
+
constructor(message: string, method: Method, path: string);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* @desc An error related to the generating of the documentation
|
|
42
|
+
* */
|
|
43
|
+
declare class DocumentationError extends Error {
|
|
44
|
+
name: string;
|
|
45
|
+
readonly cause: string;
|
|
46
|
+
constructor(message: string, { method, path, isResponse }: Pick<OpenAPIContext, "path" | "method" | "isResponse">);
|
|
47
|
+
}
|
|
48
|
+
/** @desc An error related to the input and output schemas declaration */
|
|
49
|
+
declare class IOSchemaError extends Error {
|
|
50
|
+
name: string;
|
|
51
|
+
}
|
|
52
|
+
/** @desc An error of validating the Endpoint handler's returns against the Endpoint output schema */
|
|
53
|
+
declare class OutputValidationError extends IOSchemaError {
|
|
54
|
+
readonly cause: z.ZodError;
|
|
55
|
+
name: string;
|
|
56
|
+
constructor(cause: z.ZodError);
|
|
57
|
+
}
|
|
58
|
+
/** @desc An error of validating the input sources against the Middleware or Endpoint input schema */
|
|
59
|
+
declare class InputValidationError extends IOSchemaError {
|
|
60
|
+
readonly cause: z.ZodError;
|
|
61
|
+
name: string;
|
|
62
|
+
constructor(cause: z.ZodError);
|
|
63
|
+
}
|
|
64
|
+
declare class MissingPeerError extends Error {
|
|
65
|
+
name: string;
|
|
66
|
+
constructor(module: string);
|
|
67
|
+
}
|
|
68
|
+
export {
|
|
69
|
+
RoutingError as a,
|
|
70
|
+
IsHeader as c,
|
|
71
|
+
OutputValidationError as i,
|
|
72
|
+
depictTags as l,
|
|
73
|
+
InputValidationError as n,
|
|
74
|
+
BrandHandling as o,
|
|
75
|
+
MissingPeerError as r,
|
|
76
|
+
Depicter as s,
|
|
77
|
+
DocumentationError as t,
|
|
78
|
+
trimSummary as u,
|
|
79
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -32,7 +32,13 @@ import {
|
|
|
32
32
|
x as arrayResultHandler,
|
|
33
33
|
y as AbstractResultHandler,
|
|
34
34
|
} from "./routing-xQnwfH2D.js";
|
|
35
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
a as RoutingError,
|
|
37
|
+
i as OutputValidationError,
|
|
38
|
+
n as InputValidationError,
|
|
39
|
+
r as MissingPeerError,
|
|
40
|
+
t as DocumentationError,
|
|
41
|
+
} from "./errors-CkGs6EY3.js";
|
|
36
42
|
import { z } from "zod";
|
|
37
43
|
import express, { CookieOptions, Request, Response } from "express";
|
|
38
44
|
import http from "node:http";
|
|
@@ -457,53 +463,16 @@ declare const attachRouting: (
|
|
|
457
463
|
import("qs").ParsedQs,
|
|
458
464
|
Record<string, any>
|
|
459
465
|
>;
|
|
460
|
-
logger:
|
|
466
|
+
logger: BuiltinLogger | AbstractLogger;
|
|
461
467
|
};
|
|
462
468
|
declare const createServer: (
|
|
463
469
|
config: ServerConfig,
|
|
464
470
|
routing: Routing,
|
|
465
471
|
) => {
|
|
466
472
|
app: import("express-serve-static-core").Express;
|
|
467
|
-
logger:
|
|
473
|
+
logger: BuiltinLogger | AbstractLogger;
|
|
468
474
|
servers: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>[];
|
|
469
475
|
};
|
|
470
|
-
/** @desc An error related to the wrong Routing declaration */
|
|
471
|
-
declare class RoutingError extends Error {
|
|
472
|
-
name: string;
|
|
473
|
-
readonly cause: {
|
|
474
|
-
method: Method;
|
|
475
|
-
path: string;
|
|
476
|
-
};
|
|
477
|
-
constructor(message: string, method: Method, path: string);
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* @desc An error related to the generating of the documentation
|
|
481
|
-
* */
|
|
482
|
-
declare class DocumentationError extends Error {
|
|
483
|
-
name: string;
|
|
484
|
-
readonly cause: string;
|
|
485
|
-
constructor(message: string, { method, path, isResponse }: Pick<OpenAPIContext, "path" | "method" | "isResponse">);
|
|
486
|
-
}
|
|
487
|
-
/** @desc An error related to the input and output schemas declaration */
|
|
488
|
-
declare class IOSchemaError extends Error {
|
|
489
|
-
name: string;
|
|
490
|
-
}
|
|
491
|
-
/** @desc An error of validating the Endpoint handler's returns against the Endpoint output schema */
|
|
492
|
-
declare class OutputValidationError extends IOSchemaError {
|
|
493
|
-
readonly cause: z.ZodError;
|
|
494
|
-
name: string;
|
|
495
|
-
constructor(cause: z.ZodError);
|
|
496
|
-
}
|
|
497
|
-
/** @desc An error of validating the input sources against the Middleware or Endpoint input schema */
|
|
498
|
-
declare class InputValidationError extends IOSchemaError {
|
|
499
|
-
readonly cause: z.ZodError;
|
|
500
|
-
name: string;
|
|
501
|
-
constructor(cause: z.ZodError);
|
|
502
|
-
}
|
|
503
|
-
declare class MissingPeerError extends Error {
|
|
504
|
-
name: string;
|
|
505
|
-
constructor(module: string);
|
|
506
|
-
}
|
|
507
476
|
interface TestingProps<REQ, LOG> {
|
|
508
477
|
/**
|
|
509
478
|
* @desc Additional properties to set on Request mock
|
|
@@ -546,7 +515,7 @@ declare const testEndpoint: <LOG extends FlatObject, REQ extends RequestOptions>
|
|
|
546
515
|
responseMock: import("node-mocks-http").MockResponse<Response<any, Record<string, any>>>;
|
|
547
516
|
loggerMock: AbstractLogger &
|
|
548
517
|
LOG & {
|
|
549
|
-
_getLogs: () => Record<"error" | "
|
|
518
|
+
_getLogs: () => Record<"error" | "warn" | "info" | "debug", unknown[]>;
|
|
550
519
|
};
|
|
551
520
|
}>;
|
|
552
521
|
interface MiddlewareLike<RET extends FlatObject> {
|
|
@@ -576,7 +545,7 @@ declare const testMiddleware: <LOG extends FlatObject, REQ extends RequestOption
|
|
|
576
545
|
responseMock: import("node-mocks-http").MockResponse<Response<any, Record<string, any>>>;
|
|
577
546
|
loggerMock: AbstractLogger &
|
|
578
547
|
LOG & {
|
|
579
|
-
_getLogs: () => Record<"error" | "
|
|
548
|
+
_getLogs: () => Record<"error" | "warn" | "info" | "debug", unknown[]>;
|
|
580
549
|
};
|
|
581
550
|
}>;
|
|
582
551
|
type EventsMap = Record<string, z.ZodType>;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{B as e,C as t,D as n,E as r,I as i,L as a,P as o,Q as s,R as c,S as l,T as u,U as d,V as f,W as p,Z as ee,_ as te,a as m,b as ne,c as h,d as g,f as _,i as re,j as ie,k as ae,l as v,m as y,o as oe,p as b,r as se,s as ce,t as le,u as x,w as ue,x as de,y as fe}from"./routing-walker-DJRnc3hk.js";import{t as S}from"./peer-helpers-DnGohNyk.js";import{t as pe}from"./json-schema-helpers-DrRPjVl7.js";import{globalRegistry as C,z as w}from"zod";import*as me from"ramda";import T,{isHttpError as he}from"http-errors";import ge,{blue as _e,cyanBright as ve,green as ye,hex as E,italic as be,red as xe,whiteBright as D}from"ansis";import{inspect as Se}from"node:util";import{performance as O}from"node:perf_hooks";import k from"express";import Ce from"node:http";import we from"node:https";import{setInterval as Te}from"node:timers/promises";import{createRequest as Ee,createResponse as De}from"node-mocks-http";function Oe(e){return e}const ke=(e,t)=>e&&t?e.and(t):e||t,Ae=(e,t)=>e?e.and(t):t;var je=class e{#e;constructor(e){this.#e=e}async execute(...t){try{return await this.#e(...t)}catch(n){let{response:r,logger:i,error:o}=t[0],s=new u(a(n),o||void 0);e.lastResort({response:r,logger:i,error:s})}}static lastResort({error:e,logger:t,response:n}){t.error(`Result handler failure`,e);let r=v(T(500,`An error occurred while serving the result: ${e.message}.`+(e.handled?`\nOriginal error: ${e.handled.message}.`:``),{expose:he(e.cause)?e.cause.expose:!1}));n.status(500).type(`text/plain`).end(r)}},A=class extends je{#e;#t;constructor(e){super(e.handler),this.#e=e.positive,this.#t=e.negative}getPositiveResponse(e){return g(this.#e,{variant:`positive`,args:[e],statusCodes:[m.positive],mimeTypes:[s.json]})}getNegativeResponse(){return g(this.#t,{variant:`negative`,args:[],statusCodes:[m.negative],mimeTypes:[s.json]})}};const j=w.object({status:w.literal(`error`),error:w.object({message:w.string()})});C.add(j,{examples:[{status:`error`,error:{message:`Sample error message`}}]});const M=new A({positive:e=>{let t=w.object({status:w.literal(`success`),data:e}),n=o(e);return n.length&&C.add(t,{examples:n.map(e=>({status:`success`,data:e}))}),t},negative:j,handler:({error:e,input:t,output:n,request:r,response:i,logger:a})=>{if(e){let n=h(e);x(n,a,r,t),i.status(n.statusCode).set(n.headers).json({status:`error`,error:{message:v(n)}});return}i.status(m.positive).json({status:`success`,data:n})}}),N=w.string();C.add(N,{examples:[`Sample error message`]});const P=new A({positive:e=>{let t=e instanceof w.ZodObject&&`items`in e.shape&&e.shape.items instanceof w.ZodArray?e.shape.items:w.array(w.any());if(o(t).length)return t;let n=o(e).filter(e=>d(e)&&`items`in e&&Array.isArray(e.items)).map(e=>e.items);if(n?.length){let e=t.meta();C.remove(t).add(t,{...e,examples:n})}return t},negative:{schema:N,mimeType:`text/plain`},handler:({response:e,output:t,error:n,logger:r,request:i,input:a})=>{if(n){let t=h(n);x(t,r,i,a),e.status(t.statusCode).type(`text/plain`).send(v(t));return}if(`items`in t&&Array.isArray(t.items)){e.status(m.positive).json(t.items);return}throw Error(`Property 'items' is missing in the endpoint output`)}}),F=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(`, `)},Me={"max-age":`maxAge`,"max-stale":`maxStale`,"min-fresh":`minFresh`,"stale-if-error":`staleIfError`},Ne={"no-cache":`noCache`,"no-store":`noStore`,"no-transform":`noTransform`,"only-if-cached":`onlyIfCached`},Pe=e=>{if(!e)return;let t={};for(let n of e.toLowerCase().split(`,`)){let[e,r]=n.split(`=`),i=Me[e.trim()];if(i){let e=parseInt(r?.trim()??``,10);isNaN(e)||(t[i]=e);continue}let a=Ne[e.trim()];a&&(t[a]=!0)}return t},I=e=>new b({handler:async({request:t,response:n})=>(e&&n.setHeader(`Cache-Control`,F(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 Pe(t.headers[`cache-control`])},addCachePolicy:t=>{n.setHeader(`Cache-Control`,F({...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()}})}),L=e=>new b({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})}})}),R=e=>{let t=S(`express-rate-limit`)({...e,handler:(e,t,n,r)=>{n(T(429,r.message))}}),{getKey:n,resetKey:r}=t,i={getKey:n,resetKey:r};return new _(t,{provider:t=>({rateLimit:{...i,...t[e?.requestPropertyName??`rateLimit`]}})})};var z=class e{resultHandler;schema=void 0;middlewares=[];constructor(e){this.resultHandler=e}#e(t){let n=new e(this.resultHandler);return n.middlewares=this.middlewares.concat(t),n.schema=ke(this.schema,t.schema),n}addMiddleware(e){return this.#e(e instanceof b?e:new b(e))}useCookies(...e){return this.#e(L(...e))}useCache(...e){return this.#e(I(...e))}useRateLimit(...e){return this.#e(R(...e))}use=this.addExpressMiddleware;addExpressMiddleware(...e){return this.#e(new _(...e))}addContext(e){return this.#e(new b({handler:({ctx:t})=>e(t)}))}build({input:e=i,output:t,operationId:n,scope:r,tag:a,method:o,...s}){let{middlewares:c,resultHandler:l}=this,u=typeof o==`string`?[o]:o,d=typeof n==`function`?n:e=>n&&`${n}${e===`head`?`__HEAD`:``}`,f=typeof r==`string`?[r]:r||[],p=typeof a==`string`?[a]:a||[];return new ce({...s,middlewares:c,outputSchema:t,resultHandler:l,scopes:f,tags:p,methods:u,getOperationId:d,inputSchema:Ae(this.schema,e)})}buildVoid({handler:e,...t}){return this.build({...t,output:i,handler:async t=>(await e(t),{})})}};const Fe=new z(M),Ie=new z(P),B={debug:_e,info:ye,warn:E(`#FFA500`),error:xe,ctx:ve},V={debug:10,info:20,warn:30,error:40},Le=e=>d(e)&&Object.keys(V).some(t=>t in e),Re=e=>e in V,ze=(e,t)=>V[e]<V[t],H=me.memoizeWith((e,t)=>`${e}${t}`,(e,t=0)=>Intl.NumberFormat(void 0,{useGrouping:!1,minimumFractionDigits:0,maximumFractionDigits:t,style:`unit`,unitDisplay:`long`,unit:e})),Be=e=>e<1e-6?H(`nanosecond`,3).format(e/1e-6):e<.001?H(`nanosecond`).format(e/1e-6):e<1?H(`microsecond`).format(e/.001):e<1e3?H(`millisecond`).format(e):e<6e4?H(`second`,2).format(e/1e3):H(`minute`,2).format(e/6e4);var U=class e{config;constructor({color:e=ge.isSupported(),level:t=p()?`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 Se(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`||ze(e,r))return;let s=[new Date().toISOString()];i&&s.push(o?B.ctx(i):i),s.push(o?`${B[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=O.now();return()=>{let n=O.now()-t,{message:r,severity:i=`debug`,formatter:a=Be}=typeof e==`object`?e:{message:e};this.print(typeof i==`function`?i(n):i,r,a(n))}}},Ve=class{logger;#e=new WeakMap;constructor(e){this.logger=e}#t(e,t,n){if(!e.isSchemaChecked){for(let e of[`input`,`output`]){let r=[w.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=y(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 oe)for(let{mimeTypes:r,schema:i}of t.getResponses(e)){if(!r?.includes(s.json))continue;let t=y(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){if(e.paths.has(n))return;let i=f(n);if(i.length!==0){e.flat??=pe(w.toJSONSchema(t.inputSchema,{unrepresentable:`any`,io:`input`}));for(let t of i)t in e.flat.properties||this.logger.warn(`The input schema of the endpoint is most likely missing the parameter of the path it's assigned to.`,{...r,path:n,param:t});e.paths.add(n)}}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,t,{method:e})}};const W=e=>e.sort((e,t)=>ee(t)-+ee(e)||e.localeCompare(t)).join(`, `).toUpperCase(),He=e=>({method:t},n,r)=>{let i=W(e);n.set({Allow:i}),r(T(405,`${t} is not allowed`,{headers:{Allow:i}}))},Ue=({app:e,getLogger:t,config:n,routing:r})=>{let i=p()?void 0:new Ve(t()),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},G=({app:e,config:t,getLogger:n,...r})=>{let i=Ue({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`,W(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,He(i))}for(let[t,n]of a)e.all(t,n)},We=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`,Ge=e=>`server`in e&&typeof e.server==`object`&&e.server!==null&&`close`in e.server&&typeof e.server.close==`function`,Ke=e=>`encrypted`in e&&typeof e.encrypted==`boolean`&&e.encrypted,qe=({},e)=>void(!e.headersSent&&e.setHeader(`connection`,`close`)),Je=e=>{let{promise:t,resolve:n,reject:r}=Promise.withResolvers();return e.close(e=>e?r(e):n()),t},Ye=({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(We(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`,qe);t?.info(`Graceful shutdown`,{sockets:i.size,timeout:e});for(let e of i)(Ke(e)||Ge(e))&&s(e);for await(let t of Te(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(Je))},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},K=Symbol.for(`express-zod-api`),Xe=({errorHandler:e,getLogger:t})=>async(n,r,i,o)=>n?e.execute({error:a(n),request:r,response:i,input:null,output:null,ctx:{},logger:t(r)}):o(),Ze=({errorHandler:e,getLogger:t})=>async(n,r)=>{let i=T(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:{}})},Qe=e=>(t,{},n)=>{if(Object.values(t?.files||[]).flat().find(({truncated:e})=>e))return n(e);n()},$e=({config:e})=>{let t=S(`cookie-parser`),{secret:n,...r}={...typeof e.cookies==`object`&&e.cookies};return t(n,Object.keys(r).length?r:void 0)},q=e=>typeof e==`function`?e:({},e,t)=>{e.set({"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Headers":`content-type`}),t()},et=e=>({log:t=>{/not eligible/i.test(t)||e.debug(t)}}),tt=({getLogger:e,config:t})=>{let n=S(`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:et(s)})(t,r,o)}),r&&o.push(Qe(r)),o},nt=(e,{},t)=>{Buffer.isBuffer(e.body)&&(e.body={raw:e.body}),t()},rt=({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[K]={logger:o}),a()},it=e=>t=>t?.res?.locals[K]?.logger||e;let J=!1;const at=e=>{J||(J=!0,process.on(`deprecation`,({message:t,namespace:n,name:r,stack:i})=>e.warn(`${r} (${n}): ${t}`,i.split(`
|
|
1
|
+
import{$ as e,B as t,C as n,D as r,E as i,I as a,L as o,P as s,Q as c,R as l,S as u,T as d,U as f,V as p,W as ee,_ as te,a as m,b as ne,c as h,d as g,f as _,i as re,j as ie,k as ae,l as v,m as y,o as oe,p as b,r as se,s as ce,t as le,u as x,w as ue,x as de,y as fe}from"./routing-walker-DjzH37jF.js";import{t as S}from"./peer-helpers-CuO0_h1y.js";import{t as pe}from"./json-schema-helpers-BY2DVvm4.js";import{globalRegistry as C,z as w}from"zod";import*as me from"ramda";import T,{isHttpError as he}from"http-errors";import ge,{blue as _e,cyanBright as ve,green as ye,hex as E,italic as be,red as xe,whiteBright as D}from"ansis";import{inspect as Se}from"node:util";import{performance as O}from"node:perf_hooks";import k from"express";import Ce from"node:http";import we from"node:https";import{setInterval as Te}from"node:timers/promises";import{createRequest as Ee,createResponse as De}from"node-mocks-http";function Oe(e){return e}const ke=(e,t)=>e&&t?e.and(t):e||t,Ae=(e,t)=>e?e.and(t):t;var je=class e{#e;constructor(e){this.#e=e}async execute(...t){try{return await this.#e(...t)}catch(n){let{response:r,logger:i,error:a}=t[0],s=new d(o(n),a||void 0);e.lastResort({response:r,logger:i,error:s})}}static lastResort({error:e,logger:t,response:n}){t.error(`Result handler failure`,e);let r=v(T(500,`An error occurred while serving the result: ${e.message}.`+(e.handled?`\nOriginal error: ${e.handled.message}.`:``),{expose:he(e.cause)?e.cause.expose:!1}));n.status(500).type(`text/plain`).end(r)}},A=class extends je{#e;#t;constructor(e){super(e.handler),this.#e=e.positive,this.#t=e.negative}getPositiveResponse(t){return g(this.#e,{variant:`positive`,args:[t],statusCodes:[m.positive],mimeTypes:[e.json]})}getNegativeResponse(){return g(this.#t,{variant:`negative`,args:[],statusCodes:[m.negative],mimeTypes:[e.json]})}};const j=w.object({status:w.literal(`error`),error:w.object({message:w.string()})});C.add(j,{examples:[{status:`error`,error:{message:`Sample error message`}}]});const M=new A({positive:e=>{let t=w.object({status:w.literal(`success`),data:e}),n=s(e);return n.length&&C.add(t,{examples:n.map(e=>({status:`success`,data:e}))}),t},negative:j,handler:({error:e,input:t,output:n,request:r,response:i,logger:a})=>{if(e){let n=h(e);x(n,a,r,t),i.status(n.statusCode).set(n.headers).json({status:`error`,error:{message:v(n)}});return}i.status(m.positive).json({status:`success`,data:n})}}),N=w.string();C.add(N,{examples:[`Sample error message`]});const P=new A({positive:e=>{let t=e instanceof w.ZodObject&&`items`in e.shape&&e.shape.items instanceof w.ZodArray?e.shape.items:w.array(w.any());if(s(t).length)return t;let n=s(e).filter(e=>f(e)&&`items`in e&&Array.isArray(e.items)).map(e=>e.items);if(n?.length){let e=t.meta();C.remove(t).add(t,{...e,examples:n})}return t},negative:{schema:N,mimeType:`text/plain`},handler:({response:e,output:t,error:n,logger:r,request:i,input:a})=>{if(n){let t=h(n);x(t,r,i,a),e.status(t.statusCode).type(`text/plain`).send(v(t));return}if(`items`in t&&Array.isArray(t.items)){e.status(m.positive).json(t.items);return}throw Error(`Property 'items' is missing in the endpoint output`)}}),F=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(`, `)},Me={"max-age":`maxAge`,"max-stale":`maxStale`,"min-fresh":`minFresh`,"stale-if-error":`staleIfError`},Ne={"no-cache":`noCache`,"no-store":`noStore`,"no-transform":`noTransform`,"only-if-cached":`onlyIfCached`},Pe=e=>{if(!e)return;let t={};for(let n of e.toLowerCase().split(`,`)){let[e,r]=n.split(`=`),i=Me[e.trim()];if(i){let e=parseInt(r?.trim()??``,10);isNaN(e)||(t[i]=e);continue}let a=Ne[e.trim()];a&&(t[a]=!0)}return t},I=e=>new b({handler:async({request:t,response:n})=>(e&&n.setHeader(`Cache-Control`,F(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 Pe(t.headers[`cache-control`])},addCachePolicy:t=>{n.setHeader(`Cache-Control`,F({...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()}})}),L=e=>new b({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})}})}),R=e=>{let t=S(`express-rate-limit`)({...e,handler:(e,t,n,r)=>{n(T(429,r.message))}}),{getKey:n,resetKey:r}=t,i={getKey:n,resetKey:r};return new _(t,{provider:t=>({rateLimit:{...i,...t[e?.requestPropertyName??`rateLimit`]}})})};var z=class e{resultHandler;schema=void 0;middlewares=[];constructor(e){this.resultHandler=e}#e(t){let n=new e(this.resultHandler);return n.middlewares=this.middlewares.concat(t),n.schema=ke(this.schema,t.schema),n}addMiddleware(e){return this.#e(e instanceof b?e:new b(e))}useCookies(...e){return this.#e(L(...e))}useCache(...e){return this.#e(I(...e))}useRateLimit(...e){return this.#e(R(...e))}use=this.addExpressMiddleware;addExpressMiddleware(...e){return this.#e(new _(...e))}addContext(e){return this.#e(new b({handler:({ctx:t})=>e(t)}))}build({input:e=a,output:t,operationId:n,scope:r,tag:i,method:o,...s}){let{middlewares:c,resultHandler:l}=this,u=typeof o==`string`?[o]:o,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 ce({...s,middlewares:c,outputSchema:t,resultHandler:l,scopes:f,tags:p,methods:u,getOperationId:d,inputSchema:Ae(this.schema,e)})}buildVoid({handler:e,...t}){return this.build({...t,output:a,handler:async t=>(await e(t),{})})}};const Fe=new z(M),Ie=new z(P),B={debug:_e,info:ye,warn:E(`#FFA500`),error:xe,ctx:ve},V={debug:10,info:20,warn:30,error:40},Le=e=>f(e)&&Object.keys(V).some(t=>t in e),Re=e=>e in V,ze=(e,t)=>V[e]<V[t],H=me.memoizeWith((e,t)=>`${e}${t}`,(e,t=0)=>Intl.NumberFormat(void 0,{useGrouping:!1,minimumFractionDigits:0,maximumFractionDigits:t,style:`unit`,unitDisplay:`long`,unit:e})),Be=e=>e<1e-6?H(`nanosecond`,3).format(e/1e-6):e<.001?H(`nanosecond`).format(e/1e-6):e<1?H(`microsecond`).format(e/.001):e<1e3?H(`millisecond`).format(e):e<6e4?H(`second`,2).format(e/1e3):H(`minute`,2).format(e/6e4);var U=class e{config;constructor({color:e=ge.isSupported(),level:t=ee()?`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 Se(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`||ze(e,r))return;let s=[new Date().toISOString()];i&&s.push(o?B.ctx(i):i),s.push(o?`${B[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=O.now();return()=>{let n=O.now()-t,{message:r,severity:i=`debug`,formatter:a=Be}=typeof e==`object`?e:{message:e};this.print(typeof i==`function`?i(n):i,r,a(n))}}},Ve=class{logger;#e=new WeakMap;constructor(e){this.logger=e}#t(t,n,r){if(!t.isSchemaChecked){for(let e of[`input`,`output`]){let t=[w.toJSONSchema(n[`${e}Schema`],{unrepresentable:`any`})];for(let n of t){n.type&&n.type!==`object`&&this.logger.warn(`Endpoint ${e} schema is not object-based`,r);for(let e of[`allOf`,`oneOf`,`anyOf`])n[e]&&t.push(...n[e])}}if(n.getProbableRequestType()===`json`){let e=y(n.inputSchema,`input`);e&&this.logger.warn(`The final input schema of the endpoint contains an unsupported JSON payload type.`,{...r,reason:e})}for(let t of oe)for(let{mimeTypes:i,schema:a}of n.getResponses(t)){if(!i?.includes(e.json))continue;let n=y(a,`output`);n&&this.logger.warn(`The final ${t} response schema of the endpoint contains an unsupported JSON payload type.`,{...r,reason:n})}t.isSchemaChecked=!0}}#n(e,t,n,r){if(e.paths.has(n))return;let i=p(n);if(i.length!==0){e.flat??=pe(w.toJSONSchema(t.inputSchema,{unrepresentable:`any`,io:`input`}));for(let t of i)t in e.flat.properties||this.logger.warn(`The input schema of the endpoint is most likely missing the parameter of the path it's assigned to.`,{...r,path:n,param:t});e.paths.add(n)}}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,t,{method:e})}};const W=e=>e.sort((e,t)=>c(t)-+c(e)||e.localeCompare(t)).join(`, `).toUpperCase(),He=e=>({method:t},n,r)=>{let i=W(e);n.set({Allow:i}),r(T(405,`${t} is not allowed`,{headers:{Allow:i}}))},Ue=({app:e,getLogger:t,config:n,routing:r})=>{let i=ee()?void 0:new Ve(t()),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},G=({app:e,config:t,getLogger:n,...r})=>{let i=Ue({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`,W(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,He(i))}for(let[t,n]of a)e.all(t,n)},We=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`,Ge=e=>`server`in e&&typeof e.server==`object`&&e.server!==null&&`close`in e.server&&typeof e.server.close==`function`,Ke=e=>`encrypted`in e&&typeof e.encrypted==`boolean`&&e.encrypted,qe=({},e)=>void(!e.headersSent&&e.setHeader(`connection`,`close`)),Je=e=>{let{promise:t,resolve:n,reject:r}=Promise.withResolvers();return e.close(e=>e?r(e):n()),t},Ye=({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(We(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`,qe);t?.info(`Graceful shutdown`,{sockets:i.size,timeout:e});for(let e of i)(Ke(e)||Ge(e))&&s(e);for await(let t of Te(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(Je))},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},K=Symbol.for(`express-zod-api`),Xe=({errorHandler:e,getLogger:t})=>async(n,r,i,a)=>n?e.execute({error:o(n),request:r,response:i,input:null,output:null,ctx:{},logger:t(r)}):a(),Ze=({errorHandler:e,getLogger:t})=>async(n,r)=>{let i=T(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:{}})},Qe=e=>(t,{},n)=>{if(Object.values(t?.files||[]).flat().find(({truncated:e})=>e))return n(e);n()},$e=({config:e})=>{let t=S(`cookie-parser`),{secret:n,...r}={...typeof e.cookies==`object`&&e.cookies};return t(n,Object.keys(r).length?r:void 0)},q=e=>typeof e==`function`?e:({},e,t)=>{e.set({"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Headers":`content-type`}),t()},et=e=>({log:t=>{/not eligible/i.test(t)||e.debug(t)}}),tt=({getLogger:e,config:t})=>{let n=S(`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:et(s)})(t,r,o)}),r&&o.push(Qe(r)),o},nt=(e,{},t)=>{Buffer.isBuffer(e.body)&&(e.body={raw:e.body}),t()},rt=({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[K]={logger:o}),a()},it=e=>t=>t?.res?.locals[K]?.logger||e;let J=!1;const at=e=>{J||(J=!0,process.on(`deprecation`,({message:t,namespace:n,name:r,stack:i})=>e.warn(`${r} (${n}): ${t}`,i.split(`
|
|
2
2
|
`).slice(1))))};let Y,X,Z;const ot=({servers:e,logger:t,options:{timeout:n,beforeExit:r,events:i=[`SIGINT`,`SIGTERM`]}})=>{Y??=Ye({logger:t,timeout:n}),Y.add(...e),r&&(Z??=new Set).add(r),X??=async()=>{Y?.isShuttingDown||(await Y?.shutdown(),Z&&await Promise.allSettled(Z.values().map(async e=>e())),process.exit())};for(let e of i)process.listeners(e).includes(X)||process.on(e,X)},st=e=>{if(e.columns<62)return;let t=be(`for Angie`.padStart(52)),n=E(`#F5A9B8`),r=E(`#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`,D`8888888888 888 888 88888P" 888 "Y8888 88888P' 88888P'`,D` 888`,D`8888888888P 888 888 d8888 8888888b. 8888888`,D` 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
|
-
`)},Q=e=>{e.startupLogo!==!1&&st(process.stdout);let t=e.errorHandler||M,n=Le(e.logger)?e.logger:new U(e.logger);n.debug(`Running`,{build:`v29.0.
|
|
7
|
-
`)).parse({event:t,data:n}),
|
|
6
|
+
`)},Q=e=>{e.startupLogo!==!1&&st(process.stdout);let t=e.errorHandler||M,n=Le(e.logger)?e.logger:new U(e.logger);n.debug(`Running`,{build:`v29.0.1`,env:process.env.NODE_ENV||`development`}),at(n);let r=rt({logger:n,config:e}),i={getLogger:it(n),errorHandler:t},a=Ze(i),o=Xe(i);return{...i,logger:n,notFoundHandler:a,catcher:o,loggingMiddleware:r}},ct=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,loggingMiddleware:a}=Q(e),o=e.app.use(a);return e.cors&&o.use(q(e.cors)),G({app:o,routing:t,getLogger:r,config:e}),{notFoundHandler:i,logger:n}},lt=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,catcher:a,loggingMiddleware:o}=Q(e),s=k().disable(`x-powered-by`).set(`query parser`,e.queryParser??`simple`).use(o);if(e.beforeParsers?.({app:s,getLogger:r}),e.compression){let t=S(`compression`);s.use(t(typeof e.compression==`object`?e.compression:void 0))}return e.cookies&&s.use($e({config:e})),e.cors&&s.use(q(e.cors)),s.use(e.jsonParser||k.json()).use(e.formParser||k.urlencoded()).use(e.rawParser||k.raw(),nt),e.upload&&s.use(...tt({config:e,getLogger:r})),e.beforeRouting?.({app:s,getLogger:r}),G({app:s,routing:t,getLogger:r,config:e}),e.afterRouting?.({app:s,getLogger:r}),s.use(a,i),{app:s,logger:n}},ut=(e,t)=>{let{app:n,logger:r}=lt(e,t),i=[],a=(e,t)=>()=>e.listen(t,()=>r.info(`Listening`,t)),o=[];if(e.http){let t=Ce.createServer(n);i.push(t),o.push(a(t,e.http.listen))}if(e.https){let t=we.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&&ot({logger:r,servers:i,options:e.gracefulShutdown===!0?{}:e.gracefulShutdown}),{app:n,logger:r,servers:o.map(e=>e())}},dt=t=>Ee({...t,headers:{"content-type":e.json,...t?.headers}}),ft=e=>De(e),pt=e=>{let t={warn:[],error:[],info:[],debug:[]};return new Proxy(e||{},{get(e,n,r){return n===`_getLogs`?()=>t:Re(n)?(...e)=>t[n].push(e):Reflect.get(e,n,r)}})},$=({requestProps:e,responseOptions:t,configProps:n,loggerProps:r})=>{let i=dt(e),a=ft({req:i,...t});a.req=t?.req||i,i.res=a;let o=pt(r);return{requestMock:i,responseMock:a,loggerMock:o,configMock:{cors:!1,logger:o,...n}}},mt=async({endpoint:e,...t})=>{let{requestMock:n,responseMock:r,loggerMock:i,configMock:a}=$(t);return await e.execute({request:n,response:r,config:a,logger:i}),{requestMock:n,responseMock:r,loggerMock:i}},ht=async({middleware:e,ctx:t={},...n})=>{let{configMock:{inputSources:r,errorHandler:i=M},...a}=$(n),s=l(a.requestMock,r),c={request:a.requestMock,response:a.responseMock,logger:a.loggerMock,input:s,ctx:t};try{let t=await e.execute(c);return{...a,output:t}}catch(e){return await i.execute({...c,error:o(e),output:null}),{...a,output:{}}}},gt=(e,t)=>w.object({data:t,event:w.literal(e),id:w.string().optional(),retry:w.int().positive().optional()}),_t=(e,t,n)=>gt(String(t),e[t]).transform(e=>[`event: ${e.event}`,`data: ${JSON.stringify(e.data)}`,``,``].join(`
|
|
7
|
+
`)).parse({event:t,data:n}),vt=t=>t.headersSent||t.writeHead(200,{connection:`keep-alive`,"content-type":e.sse,"cache-control":`no-cache`}),yt=e=>new b({handler:async({request:t,response:n})=>{let r=new AbortController,i=setTimeout(()=>vt(n),1e4);return t.once(`close`,()=>{clearTimeout(i),r.abort()}),{isClosed:()=>n.writableEnded||n.closed,signal:r.signal,emit:(t,r)=>{vt(n),n.write(_t(e,t,r),`utf-8`),n.flush?.()}}}}),bt=t=>new A({positive:()=>{let[n,...r]=Object.entries(t).map(([e,t])=>gt(e,t));if(!n)throw new d(Error(`At least one SSE event is required.`));return{mimeType:e.sse,schema:r.length?w.discriminatedUnion(`event`,[n,...r]):n}},negative:{mimeType:`text/plain`,schema:w.string()},handler:async({response:e,error:t,logger:n,request:r,input:i})=>{if(t){let a=h(t);x(a,n,r,i),e.headersSent||e.status(a.statusCode).type(`text/plain`).write(v(a),`utf-8`)}e.end()}});var xt=class extends z{constructor(e){super(bt(e)),this.middlewares=[yt(e)]}};const St=[`total`,`limit`,`offset`],Ct=[`nextCursor`,`limit`];function wt({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`&&St.includes(n))throw Error(`ez.paginated: itemsName must not match reserved keys for offset output (${St.join(`, `)})`);if(e===`cursor`&&Ct.includes(n))throw Error(`ez.paginated: itemsName must not match reserved keys for cursor output (${Ct.join(`, `)})`);let a=w.coerce.number().int().min(1).max(r).default(i).describe(`Page size (number of ${n} per page)`);if(e===`offset`){let e=w.coerce.number().int().min(0).default(0).describe(`Number of ${n} to skip`);return{input:w.object({limit:a,offset:e}),output:w.object({[n]:w.array(t).describe(`Page of ${n}`),total:w.number().int().min(0).describe(`Total number of ${n}`),limit:w.number().int().min(1).describe(`Page size used`),offset:w.number().int().min(0).describe(`Offset used`)})}}let o=w.string().optional().describe(`Cursor for the next page; omit for first page`);return{input:w.object({cursor:o,limit:a}),output:w.object({[n]:w.array(t).describe(`Page of ${n}`),nextCursor:w.string().nullable().describe(`Cursor for the next page, or null if no more pages`),limit:w.number().int().min(1).describe(`Page size used`)})}}const Tt={dateIn:ae,dateOut:r,form:ne,upload:fe,raw:te,buffer:ie,paginated:wt};export{U as BuiltinLogger,de as DocumentationError,z as EndpointsFactory,xt as EventStreamFactory,u as InputValidationError,b as Middleware,n as MissingPeerError,ue as OutputValidationError,A as ResultHandler,i as RoutingError,se as ServeStatic,Ie as arrayEndpointsFactory,P as arrayResultHandler,ct as attachRouting,re as createApiResponse,I as createCacheMiddleware,Oe as createConfig,L as createCookieMiddleware,R as createRateLimitMiddleware,ut as createServer,Fe as defaultEndpointsFactory,M as defaultResultHandler,h as ensureHttpError,Tt as ez,t as getMessageFromError,mt as testEndpoint,ht as testMiddleware};
|
package/dist/integration.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{$ as e,A as t,G as n,H as r,K as i,M as a,N as o,O as s,Y as c,Z as l,g as u,h as d,n as f,o as p,t as m}from"./routing-walker-DjzH37jF.js";import{t as h}from"./peer-helpers-CuO0_h1y.js";import{t as g}from"./security-ts3gqWG9.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 T=class{serverUrl;paths=new Set;tags=new Map;registry=new Map;constructor(e){this.serverUrl=e}makeMethodType=()=>{let e=C(l).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(`
|
|
5
5
|
`)};makePaginationType=()=>{let e=w(`nextCursor`),t=w(`total`),n=w(`limit`),r=w(`offset`),i=`{ ${e}: string | null }`,a=`{ ${t}: number; ${n}: number; ${r}: number }`;return`type ${x.Pagination} = ${i} | ${a}`};makeClientClass=e=>{let t=w(`nextCursor`),n=w(`offset`),r=w(`limit`),i=w(`total`),a=`${x.method}, ...${x.substitute}(${x.path}, ${x.params}), ${x.ctx}`;return[`export class ${e}<T extends Record<string, unknown> = ${x.DefaultContext}> {`,` public constructor(`,` protected readonly ${x.implementation}: ${x.Implementation}<T> = ${x.defaultImplementation},`,` ) {}`,` public ${x.provide}<K extends ${x.Request}>(`,` ${x.request}: K,`,` ${x.params}: ${S.input}[K],`,` ${x.ctx}?: T,`,` ): Promise<${S.response}[K]> {`,` const [${x.method}, ${x.path}] = ${x.parseRequest}(${x.request});`,` return this.${x.implementation}(${a});`,` }`,` public static hasMore(${x.response}: ${x.Pagination}): boolean {`,` if ("${t}" in ${x.response}) return ${x.response}.${t} !== null;`,` return ${x.response}.${n} + ${x.response}.${r} < ${x.response}.${i};`,` }`,`}`].join(`
|
|
6
|
-
`)};makeDefaultImplementation=
|
|
6
|
+
`)};makeDefaultImplementation=t=>{let n=`${x.method}, ${x.path}, ${x.params}, ${x.ctx}`,r=C([`get`,`head`,`delete`]).join(`, `),i=`!${x.hasBody} || ${x.hasFiles} ? ${x.undefined} : { "Content-Type": ${x.isBlob} ? "${e.raw}" : "${e.json}" };`,a=`${x.response}.${w(`headers`)}.${w(`get`)}("content-type")`,o=`\`?\${new ${URLSearchParams.name}(${x.params})}\``;return[`const ${x.defaultImplementation}: ${x.Implementation}<${x.DefaultContext}> = async (${n}) => {`,` 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} = ![${r}].includes(${x.method});`,` const ${x.searchParams} = ${x.isBlob} || ${x.hasBody} ? "" : ${o};`,` const ${x.headers} = ${i}`,` 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`)}: ${t?`"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} = ${a};`,` if (!${x.contentType}) return;`,` if (${x.contentType}.${w(`startsWith`)}("${e.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 E=b.factory,D=/^[A-Za-z_$][A-Za-z0-9_$]*$/,ee=[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`?E.createNumericLiteral(e):typeof e==`bigint`?E.createBigIntLiteral(e.toString()):typeof e==`boolean`?e?E.createTrue():E.createFalse():e===null?E.createNull():E.createStringLiteral(e),k=e=>E.createIdentifier(e),A=e=>typeof e==`string`&&D.test(e)?k(e):O(e),j=(e,t)=>typeof e==`number`?E.createKeywordTypeNode(e):typeof e==`string`||b.isIdentifier(e)?E.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 E.createUnionTypeNode(Array.from(t.values()))},N=e=>ee.includes(e.kind),te=(e,t)=>b.addSyntheticLeadingComment(e,b.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0),P=(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)},F=(e,t,{isOptional:n,hasUndefined:r=n,isDeprecated:i,comment:a}={})=>{let o=j(t),s=E.createPropertySignature(void 0,A(e),n?E.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?te(s,c.join(` `)):s},I=e=>E.createLiteralTypeNode(O(e)),L=(e,{rules:t,onMissing:n,ctx:r={}})=>{let i=o(e),a=i&&i in t?t[i]:t[e._zod.def.type],s=e=>L(e,{ctx:r,rules:t,onMissing:n});return a?a(e,{...r,next:s}):n(e,r)},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:
|
|
10
|
-
`)});let h=p.reduce((t,i)=>{let
|
|
11
|
-
`)}\n}`),Object.assign(t,{[i]:
|
|
9
|
+
`)};const E=b.factory,D=/^[A-Za-z_$][A-Za-z0-9_$]*$/,ee=[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`?E.createNumericLiteral(e):typeof e==`bigint`?E.createBigIntLiteral(e.toString()):typeof e==`boolean`?e?E.createTrue():E.createFalse():e===null?E.createNull():E.createStringLiteral(e),k=e=>E.createIdentifier(e),A=e=>typeof e==`string`&&D.test(e)?k(e):O(e),j=(e,t)=>typeof e==`number`?E.createKeywordTypeNode(e):typeof e==`string`||b.isIdentifier(e)?E.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 E.createUnionTypeNode(Array.from(t.values()))},N=e=>ee.includes(e.kind),te=(e,t)=>b.addSyntheticLeadingComment(e,b.SyntaxKind.MultiLineCommentTrivia,`* ${t} `,!0),P=(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)},F=(e,t,{isOptional:n,hasUndefined:r=n,isDeprecated:i,comment:a}={})=>{let o=j(t),s=E.createPropertySignature(void 0,A(e),n?E.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?te(s,c.join(` `)):s},I=e=>E.createLiteralTypeNode(O(e)),L=(e,{rules:t,onMissing:n,ctx:r={}})=>{let i=o(e),a=i&&i in t?t[i]:t[e._zod.def.type],s=e=>L(e,{ctx:r,rules:t,onMissing:n});return a?a(e,{...r,next:s}):n(e,r)},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:r}=e,i=0,a=()=>{let e=``;for(;i<r.length;){let t=r[i];if(n(t))break;i++,e+=t??``}return e},o=E.createTemplateHead(a()),s=[];for(;i<r.length;){let e=t(r[i++]),n=a(),o=i<r.length?E.createTemplateMiddle:E.createTemplateTail;s.push(E.createTemplateLiteralTypeSpan(e,o(n)))}return s.length?E.createTemplateLiteralType(o,s):I(o.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 F(e,n(r),{comment:i,isDeprecated:a,isOptional:o,hasUndefined:s})});return E.createTypeLiteralNode(r)};return d(e,{io:t?`output`:`input`})?r(e,i):i()},H=({_zod:{def:e}},{next:t})=>E.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})=>E.createTupleTypeNode(e.items.map(t).concat(e.rest===null?[]:E.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`?E.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 E.createTypeLiteralNode(n)},(e,t)=>E.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:t,isResponse:i})=>{let a=e[i?`out`:`in`],o=e[i?`in`:`out`];if(!n(a,`transform`))return t(a);let s=t(o),c={[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}[s.kind],l=r(a,c),u={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(l&&u[l]||Q(i))},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),[t]: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,[a]:ae,[u]:oe},$=(e,{brandHandling:t,ctx:n})=>L(e,{rules:{...t,...se},onMissing:({},{isResponse:e})=>Q(e),ctx:n});var ce=class extends T{#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} = ${P(r,e)};`)}return j(n)}constructor({routing:e,config:t,brandHandling:n,variant:r=`client`,clientClassName:a=`Client`,subscriptionClassName:o=`Subscription`,serverUrl:s=`https://example.com`,noBodySchema:l=v.undefined(),hasHeadMethod:u=!0,hasCredentials:d=!1}){super(s);let h={makeAlias:this.#r.bind(this)},_={brandHandling:n,ctx:{...h,isResponse:!1}},y={brandHandling:n,ctx:{...h,isResponse:!0}},b=!1,x=(e,t,n)=>{let r=i.bind(null,e,t),{isDeprecated:a,inputSchema:o,tags:s}=n,u=`${e} ${t}`,d=r(`input`),f=g(n.security,`cookie`);f.size&&(b=!0);let m=$(o,_);this.#e.push(e=>{let t=P(m,e);return[`/** ${u} */`,`type ${d} = ${f.size?this.makeOmit(t,f,`security cookies`):t};`].join(`
|
|
10
|
+
`)});let h=p.reduce((t,i)=>{let a=n.getResponses(i),o=[];for(let[t,{schema:n,mimeTypes:s,statusCodes:d}]of a.entries()){let a=c(e,s),f=r(i,`variant`,`${t+1}`),p=$(a?n:l,y);this.#e.push(e=>`/** ${u} */\ntype ${f} = ${P(p,e)};`);for(let e of d)o.push(` ${e}: ${f};`)}let s=r(i,`response`,`variants`);return this.#e.push(`/** ${u} */\ninterface ${s} {\n${o.join(`
|
|
11
|
+
`)}\n}`),Object.assign(t,{[i]:s})},{});this.paths.add(t);let v={input:d,positive:this.someOf(h.positive),negative:this.someOf(h.negative),response:`${S.positive}["${u}"] | ${S.negative}["${u}"]`,encoded:`${h.positive} & ${h.negative}`};this.registry.set(u,{isDeprecated:a,store:v}),this.tags.set(u,s)};m({routing:e,config:t,onEndpoint:u?f(x):x}),this.#e.push(this.makeSomeOfType(),this.makePathType(),this.makeMethodType(),...this.makePublicInterfaces(),this.makeRequestType()),r!==`types`&&(this.#e.push(this.makeEndpointTags(),this.makeParseRequestFn(),this.makeSubstituteFn(),this.makeImplementationType(),this.makePaginationType(),this.makeDefaultContextType(),this.makeDefaultImplementation(d&&b),this.makeClientClass(a),this.makeSubscriptionClass(o,d&&b)),this.#n=this.makeUsageStatements(a,o))}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
|
|
|
13
13
|
`)}async printFormatted({printerOptions:e,format:t}={}){let n=t;if(!n)try{let e=h(`prettier`).format;n=t=>e(t,{filepath:`client.ts`})}catch{}this.#n&&n&&(this.#n=await n(this.#n));let r=this.print(e);return n?n(r):r}};export{ce as Integration};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{F as e,U as t}from"./routing-walker-
|
|
1
|
+
import{F as e,U as t}from"./routing-walker-DjzH37jF.js";import*as n from"ramda";const r=e=>e.type===`object`,i=n.mergeDeepWith((e,t)=>{if(Array.isArray(e)&&Array.isArray(t))return n.concat(e,t);if(e===t)return t;throw Error(`Can not flatten properties`,{cause:{a:e,b:t}})}),a=new Set([`type`,`properties`,`required`,`examples`,`description`,`additionalProperties`]),o=e=>{for(let t of Object.keys(e))if(!a.has(t))return!1;return!0},s=n.pair(!0),c=(e,t,r)=>!(`allOf`in e)||!e.allOf?[]:e.allOf.map(e=>{if(t===`throw`&&!(e.type===`object`&&o(e)))throw Error(`Can not merge`);return n.pair(r,e)}),l=e=>{let t=[];return e.anyOf&&t.push(...n.map(s,e.anyOf)),e.oneOf&&t.push(...n.map(s,e.oneOf)),t},u=(e,n,r,i)=>{if(!t(e.propertyNames))return;let a=[];typeof e.propertyNames.const==`string`&&a.push(e.propertyNames.const),e.propertyNames.enum&&a.push(...e.propertyNames.enum.filter(e=>typeof e==`string`));let o={...Object(e.additionalProperties)};for(let e of a)n.properties[e]??=o;i||r.push(...a)},d=(r,i,a)=>{i.examples?.length&&(a?r.examples=n.concat(r.examples||[],i.examples):r.examples=e(r.examples?.filter(t)||[],i.examples.filter(t),([e,t])=>n.mergeDeepRight(e,t)))},f=(e,t=`coerce`)=>{let a=[n.pair(!1,e)],o={type:`object`,properties:{}},s=[];for(let[e,f]of a)f.description&&(o.description??=f.description),a.push(...c(f,t,e)),a.push(...l(f)),d(o,f,e),r(f)&&(a.push([e,{examples:p(f)}]),f.properties&&(o.properties=(t===`throw`?i:n.mergeDeepRight)(o.properties,f.properties),!e&&f.required&&s.push(...f.required)),u(f,o,s,e));return s.length&&(o.required=[...new Set(s)]),o},p=r=>Object.entries(r.properties||{}).reduce((r,[i,a])=>{let{examples:o=[]}=t(a)?a:{};return e(r,o.map(n.objOf(i)),([e,t])=>({...e,...t}))},[]);export{f as t};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e}from"./routing-walker-
|
|
1
|
+
import{C as e}from"./routing-walker-DjzH37jF.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};
|
|
@@ -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`]},m=[`body`,`query`,`params`],h=e=>e.method.toLowerCase(),g=(e,t={})=>{if(e===`options`)return[];let n=e===`head`?`get`:u(e)?e:void 0;return(n?t[n]||ne[n]:void 0)||m},_=(e,t={})=>{let n=h(e);return g(n,t).filter(t=>t!==`files`||te(e)).reduce((t,n)=>Object.assign(t,e[n]),{})},v=e=>e instanceof Error?e:e instanceof t.ZodError?new t.ZodRealError(e.issues):Error(String(e)),y=e=>e instanceof t.ZodError?e.issues.map(({path:e,message:n})=>`${e.length?`${t.core.toDotPath(e)}: `:``}${n}`).join(`; `):e.message,b=(e,t)=>w(e)&&`_zod`in e&&(!t||n.path([`_zod`,`def`,`type`],e)===t),x=(e,t,r)=>e.length&&t.length?n.xprod(e,t).map(r):e.concat(t),S=e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase(),C=(...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(S).join(``)},re=n.tryCatch((e,n)=>typeof t.parse(e,n),n.always(void 0)),w=e=>typeof e==`object`&&!!e,T=n.memoizeWith(()=>`static`,()=>process.env.NODE_ENV===`production`),ie=(e,t)=>!!t&&e!==`head`,E=`x-brand`,D=t=>{let{[E]:n}=e.get(t)||{};if(typeof n==`symbol`||typeof n==`string`||typeof n==`number`)return n},O=t=>{let{examples:n}=e.get(t)||{};return Array.isArray(n)?n:[]},k=Symbol(`Buffer`),A=()=>t.custom(e=>Buffer.isBuffer(e),{error:`Expected Buffer`}).meta({[E]:k}),j=Symbol(`DateIn`),ae=({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,[E]:j}),M=Symbol(`DateOut`),oe=(e={})=>t.date().transform(e=>e.toISOString()).pipe(t.iso.datetime()).meta({...e,[E]:M});var N=class extends Error{name=`RoutingError`;cause;constructor(e,t,n){super(e),this.cause={method:t,path:n}}},P=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.`}},F=class extends Error{name=`IOSchemaError`},se=class extends F{cause;name=`DeepCheckError`;constructor(e){super(`Found`,{cause:e}),this.cause=e}},I=class extends F{cause;name=`OutputValidationError`;constructor(e){let n=new t.ZodError(e.issues.map(({path:e,...t})=>({...t,path:[`output`,...e]})));super(y(n),{cause:e}),this.cause=e}},L=class extends F{cause;name=`InputValidationError`;constructor(e){super(y(e),{cause:e}),this.cause=e}},R=class extends Error{cause;handled;name=`ResultHandlerError`;constructor(e,t){super(y(e),{cause:e}),this.cause=e,this.handled=t}},ce=class extends Error{name=`MissingPeerError`;constructor(e){super(`Missing peer dependency: ${e}. Please install it to use the feature.`)}};const z=Symbol(`Form`),le=e=>(e instanceof t.ZodObject?e:t.object(e)).meta({[E]:z}),B=Symbol(`Upload`),V=e=>w(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,H=()=>t.custom(e=>V(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({[E]:B}),U=Symbol(`Raw`),W=t.object({raw:A()}),ue=e=>W.extend(e).meta({[E]:U});function G(e){return e?ue(e):W.meta({[E]:U})}const K=(e,{io:r,condition:i})=>n.tryCatch(()=>void t.toJSONSchema(e,{io:r,unrepresentable:`any`,override:({zodSchema:e})=>{if(i(e))throw new se(e)}}),e=>e.cause)(),de=(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},fe=e=>K(e,{condition:e=>{let t=D(e);return typeof t==`symbol`&&[B,U,z].includes(t)},io:`input`}),pe=[`nan`,`symbol`,`map`,`set`,`bigint`,`void`,`promise`,`never`,`function`],me=(e,t)=>K(e,{io:t,condition:e=>{let n=D(e),{type:r}=e._zod.def;return!!(pe.includes(r)||n===k||t===`input`&&(r===`date`||n===M)||t===`output`&&(n===j||n===U||n===B))}});var he=class{},q=class extends he{#e;#t;#n;constructor({input:e,security:t,handler:n}){super(),this.#e=e,this.#t=t,this.#n=n}get security(){return this.#t}get schema(){return this.#e}async execute({input:e,...n}){try{let t=await(this.#e||d).parseAsync(e);return this.#n({...n,input:t})}catch(e){throw e instanceof t.ZodError?new L(e):e}}},J=class extends q{constructor(e,{provider:t=()=>({}),transformer:n=e=>e}={}){super({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 ge=(e,{variant:n,args:r,...i})=>{if(typeof e==`function`&&(e=e(...r)),e instanceof t.ZodType)return[{schema:e,...i}];if(Array.isArray(e)&&!e.length)throw new R(Error(`At least one ${n} response schema required.`));return(Array.isArray(e)?e:[e]).map(({schema:e,statusCode:t,mimeType:n})=>({schema:e,statusCodes:typeof t==`number`?[t]:t||i.statusCodes,mimeTypes:typeof n==`string`?[n]:n===void 0?i.mimeTypes:n}))},_e=(e,t,{url:n},r)=>!e.expose&&t.error(`Server side error`,{error:e,url:n,payload:r}),ve=e=>a(e)?e:i(e instanceof L?400:500,y(e),{cause:e.cause||e}),ye=e=>T()&&!e.expose?i(e.statusCode).message:e.message,be=e=>Object.entries(e._zod.def.shape).reduce((e,[t,r])=>x(e,O(r).map(n.objOf(t)),([e,t])=>({...e,...t})),[]);var Y=class{nest(e){return{...e,"":this}}},xe=class r extends Y{#e;#t;#n=n.once(()=>{if(O(this.#e.outputSchema).length||!b(this.#e.outputSchema,`object`))return;let t=be(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 Object.freeze(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=fe(this.#e.inputSchema);if(e){let t=D(e);if(t===B)return`upload`;if(t===U)return`raw`;if(t===z)return`form`}return`json`})()}getResponses(e){return e===`positive`&&this.#n(),Object.freeze(e===`negative`?this.#e.resultHandler.getNegativeResponse():this.#e.resultHandler.getPositiveResponse(this.#e.outputSchema))}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 I(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 J))&&(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 L(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=h(e),a={},o,s=_(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:v(e)}}await this.#s({...o,input:s,request:e,response:t,logger:n,ctx:a})}};const X={positive:200,negative:400},Se=Object.keys(X);function Ce(e){return e instanceof t.ZodType?{schema:e}:e}var Z=class{#e;constructor(...e){this.#e=e}apply(e,t){return t(e,o.static(...this.#e))}};const we=e=>(t,...n)=>{e(t,...n),t===`get`&&e(`head`,...n)},Te=e=>{let[t,n]=e.trim().split(/ (.+)/,2);return n&&u(t)?[n,t]:[e]},Ee=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 Y?[`/`,t]:Te(t);return[[n||``].concat(Ee(i)||[]).join(`/`)||`/`,r,a]}),De=(e,t)=>{throw new N(`Route with explicit method can only be assigned with Endpoint`,e,t)},Oe=(e,t,n)=>{if(!(!n||n.includes(e)))throw new N(`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 N(`Route has a duplicate: the normalized path "${r}" is already registered`,e,t);n.add(i)},ke=({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 Y)if(c)$(c,o,a),Oe(c,o,s.methods),n(c,o,s);else{let{methods:e=[`get`]}=s;for(let t of e)$(t,o,a),n(t,o,s)}else c&&De(c,o),s instanceof Z?r&&s.apply(o,r):i.splice(e+1,0,...Q(t,s,o))}};export{s as $,j as A,y as B,ce as C,oe as D,N as E,x as F,b as G,re as H,d as I,f as J,C as K,v as L,k as M,D as N,M as O,O as P,u as Q,_ as R,L as S,R as T,w as U,ee as V,T as W,S as X,ie as Y,l as Z,G as _,X as a,le as b,ve as c,ge as d,J as f,U as g,de as h,Ce as i,A as j,ae as k,ye as l,me as m,we as n,Se as o,q as p,p as q,Z as r,xe as s,ke as t,_e as u,B as v,I as w,P as x,H as y,g as z};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{F as e,U as t}from"./routing-walker-
|
|
1
|
+
import{F as e,U as t}from"./routing-walker-DjzH37jF.js";import*as n from"ramda";const r=e=>t(e)&&`or`in e,i=e=>t(e)&&`and`in e,a=e=>!i(e)&&!r(e),o=t=>{let o=n.filter(a,t),s=n.chain(n.prop(`and`),n.filter(i,t)),[c,l]=n.partition(a,s),u=n.concat(o,c),d=n.filter(r,t);return n.map(n.prop(`or`),n.concat(d,l)).reduce((t,r)=>e(t,n.map(e=>a(e)?[e]:e.and,r),([e,t])=>n.concat(e,t)),n.reject(n.isEmpty,[u]))},s=(e,t)=>i(e)?n.chain(e=>s(e,t),e.and):r(e)?n.chain(e=>s(e,t),e.or):e.type===t?[e.name]:[],c=(e,t)=>new Set(n.chain(e=>s(e,t),e));export{o as n,c as t};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-zod-api",
|
|
3
|
-
"version": "29.0.
|
|
3
|
+
"version": "29.0.1",
|
|
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": {
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"http-errors": "^2.0.1",
|
|
65
65
|
"typescript": "^5.1.3 || ^6.0.2",
|
|
66
66
|
"zod": "^4.3.4",
|
|
67
|
-
"@express-zod-api/zod-plugin": "^6.0.
|
|
67
|
+
"@express-zod-api/zod-plugin": "^6.0.1"
|
|
68
68
|
},
|
|
69
69
|
"peerDependenciesMeta": {
|
|
70
70
|
"@express-zod-api/zod-plugin": {
|
|
@@ -125,7 +125,7 @@
|
|
|
125
125
|
"typescript": "^6.0.2",
|
|
126
126
|
"undici": "^8.2.0",
|
|
127
127
|
"zod": "^4.4.3",
|
|
128
|
-
"@express-zod-api/zod-plugin": "^6.0.
|
|
128
|
+
"@express-zod-api/zod-plugin": "^6.0.1"
|
|
129
129
|
},
|
|
130
130
|
"keywords": [
|
|
131
131
|
"nodejs",
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { D as ClientMethod, f as Tag } from "./routing-xQnwfH2D.js";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import { ReferenceObject, SchemaObjectValue, TagObject } from "openapi3-ts/oas32";
|
|
4
|
-
interface ReqResCommons {
|
|
5
|
-
makeRef: (key: object | string, value: SchemaObjectValue | ReferenceObject, proposedName?: string) => ReferenceObject;
|
|
6
|
-
path: string;
|
|
7
|
-
method: ClientMethod;
|
|
8
|
-
seenIds: Map<string, z.core.$ZodType>;
|
|
9
|
-
}
|
|
10
|
-
interface OpenAPIContext extends ReqResCommons {
|
|
11
|
-
isResponse: boolean;
|
|
12
|
-
}
|
|
13
|
-
type Depicter = (
|
|
14
|
-
zodCtx: {
|
|
15
|
-
zodSchema: z.core.$ZodType;
|
|
16
|
-
jsonSchema: z.core.JSONSchema.BaseSchema;
|
|
17
|
-
},
|
|
18
|
-
oasCtx: OpenAPIContext,
|
|
19
|
-
) => z.core.JSONSchema.BaseSchema | SchemaObjectValue;
|
|
20
|
-
/** @desc Using defaultIsHeader when returns null or undefined */
|
|
21
|
-
type IsHeader = (name: string, method: ClientMethod, path: string) => boolean | null | undefined;
|
|
22
|
-
type BrandHandling = Record<string | symbol, Depicter>;
|
|
23
|
-
interface TagDetails extends Pick<TagObject, "summary" | "description" | "externalDocs" | "kind"> {
|
|
24
|
-
/** @desc shorthand for externalDocs.url */
|
|
25
|
-
url?: string;
|
|
26
|
-
parent?: Tag;
|
|
27
|
-
}
|
|
28
|
-
declare const depictTags: (tags: Partial<Record<Tag, string | TagDetails>>) => TagObject[];
|
|
29
|
-
/** @desc Ensures the summary string does not exceed the limit */
|
|
30
|
-
declare const trimSummary: (summary?: string, limit?: number) => string | undefined;
|
|
31
|
-
export { depictTags as a, OpenAPIContext as i, Depicter as n, trimSummary as o, IsHeader as r, BrandHandling as t };
|
|
@@ -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))||[],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`]},p=[`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)||p},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)=>C(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(),S=(...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(``)},re=n.tryCatch((e,n)=>typeof t.parse(e,n),n.always(void 0)),C=e=>typeof e==`object`&&!!e,w=n.memoizeWith(()=>`static`,()=>process.env.NODE_ENV===`production`),ie=(e,t)=>!!t&&e!==`head`,T=`x-brand`,E=t=>{let{[T]:n}=e.get(t)||{};if(typeof n==`symbol`||typeof n==`string`||typeof n==`number`)return n},D=t=>{let{examples:n}=e.get(t)||{};return Array.isArray(n)?n:[]},O=Symbol(`Buffer`),k=()=>t.custom(e=>Buffer.isBuffer(e),{error:`Expected Buffer`}).meta({[T]:O}),A=Symbol(`DateIn`),ae=({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,[T]:A}),j=Symbol(`DateOut`),M=(e={})=>t.date().transform(e=>e.toISOString()).pipe(t.iso.datetime()).meta({...e,[T]:j});var N=class extends Error{name=`RoutingError`;cause;constructor(e,t,n){super(e),this.cause={method:t,path:n}}},oe=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.`}},P=class extends Error{name=`IOSchemaError`},se=class extends P{cause;name=`DeepCheckError`;constructor(e){super(`Found`,{cause:e}),this.cause=e}},F=class extends P{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}},I=class extends P{cause;name=`InputValidationError`;constructor(e){super(v(e),{cause:e}),this.cause=e}},L=class extends Error{cause;handled;name=`ResultHandlerError`;constructor(e,t){super(v(e),{cause:e}),this.cause=e,this.handled=t}},ce=class extends Error{name=`MissingPeerError`;constructor(e){super(`Missing peer dependency: ${e}. Please install it to use the feature.`)}};const R=Symbol(`Form`),le=e=>(e instanceof t.ZodObject?e:t.object(e)).meta({[T]:R}),z=Symbol(`Upload`),B=e=>C(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,V=()=>t.custom(e=>B(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({[T]:z}),H=Symbol(`Raw`),U=t.object({raw:k()}),W=e=>U.extend(e).meta({[T]:H});function ue(e){return e?W(e):U.meta({[T]:H})}const G=(e,{io:r,condition:i})=>n.tryCatch(()=>void t.toJSONSchema(e,{io:r,unrepresentable:`any`,override:({zodSchema:e})=>{if(i(e))throw new se(e)}}),e=>e.cause)(),de=(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},fe=e=>G(e,{condition:e=>{let t=E(e);return typeof t==`symbol`&&[z,H,R].includes(t)},io:`input`}),pe=[`nan`,`symbol`,`map`,`set`,`bigint`,`void`,`promise`,`never`,`function`],me=(e,t)=>G(e,{io:t,condition:e=>{let n=E(e),{type:r}=e._zod.def;return!!(pe.includes(r)||n===O||t===`input`&&(r===`date`||n===j)||t===`output`&&(n===A||n===H||n===z))}});var he=class{},K=class extends he{#e;#t;#n;constructor({input:e,security:t,handler:n}){super(),this.#e=e,this.#t=t,this.#n=n}get security(){return this.#t}get schema(){return this.#e}async execute({input:e,...n}){try{let t=await(this.#e||d).parseAsync(e);return this.#n({...n,input:t})}catch(e){throw e instanceof t.ZodError?new I(e):e}}},q=class extends K{constructor(e,{provider:t=()=>({}),transformer:n=e=>e}={}){super({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 ge=(e,{variant:n,args:r,...i})=>{if(typeof e==`function`&&(e=e(...r)),e instanceof t.ZodType)return[{schema:e,...i}];if(Array.isArray(e)&&!e.length)throw new L(Error(`At least one ${n} response schema required.`));return(Array.isArray(e)?e:[e]).map(({schema:e,statusCode:t,mimeType:n})=>({schema:e,statusCodes:typeof t==`number`?[t]:t||i.statusCodes,mimeTypes:typeof n==`string`?[n]:n===void 0?i.mimeTypes:n}))},_e=(e,t,{url:n},r)=>!e.expose&&t.error(`Server side error`,{error:e,url:n,payload:r}),ve=e=>a(e)?e:i(e instanceof I?400:500,v(e),{cause:e.cause||e}),ye=e=>w()&&!e.expose?i(e.statusCode).message:e.message,be=e=>Object.entries(e._zod.def.shape).reduce((e,[t,r])=>b(e,D(r).map(n.objOf(t)),([e,t])=>({...e,...t})),[]);var J=class{nest(e){return{...e,"":this}}},xe=class r extends J{#e;#t;#n=n.once(()=>{if(D(this.#e.outputSchema).length||!y(this.#e.outputSchema,`object`))return;let t=be(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 Object.freeze(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=fe(this.#e.inputSchema);if(e){let t=E(e);if(t===z)return`upload`;if(t===H)return`raw`;if(t===R)return`form`}return`json`})()}getResponses(e){return e===`positive`&&this.#n(),Object.freeze(e===`negative`?this.#e.resultHandler.getNegativeResponse():this.#e.resultHandler.getPositiveResponse(this.#e.outputSchema))}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 F(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 q))&&(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 I(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})}};const Y={positive:200,negative:400},Se=Object.keys(Y);function Ce(e){return e instanceof t.ZodType?{schema:e}:e}var X=class{#e;constructor(...e){this.#e=e}apply(e,t){return t(e,o.static(...this.#e))}};const we=e=>(t,...n)=>{e(t,...n),t===`get`&&e(`head`,...n)},Z=e=>{let[t,n]=e.trim().split(/ (.+)/,2);return n&&u(t)?[n,t]:[e]},Te=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 J?[`/`,t]:Z(t);return[[n||``].concat(Te(i)||[]).join(`/`)||`/`,r,a]}),Ee=(e,t)=>{throw new N(`Route with explicit method can only be assigned with Endpoint`,e,t)},De=(e,t,n)=>{if(!(!n||n.includes(e)))throw new N(`Method ${e} is not supported by the assigned Endpoint.`,e,t)},$=(e,t,n)=>{let r=`${e} ${t}`;if(n.has(r))throw new N(`Route has a duplicate`,e,t);n.add(r)},Oe=({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 J)if(c)$(c,o,a),De(c,o,s.methods),n(c,o,s);else{let{methods:e=[`get`]}=s;for(let t of e)$(t,o,a),n(t,o,s)}else c&&Ee(c,o),s instanceof X?r&&s.apply(o,r):i.splice(e+1,0,...Q(t,s,o))}};export{A,v as B,ce as C,M as D,N as E,b as F,y as G,re as H,d as I,ie as J,S as K,_ as L,O as M,E as N,j as O,D as P,s as Q,g as R,I as S,L as T,C as U,ee as V,w as W,l as X,x as Y,u as Z,ue as _,Y as a,le as b,ve as c,ge as d,q as f,H as g,de as h,Ce as i,k as j,ae as k,ye as l,me as m,we as n,Se as o,K as p,f as q,X as r,xe as s,Oe as t,_e as u,z as v,F as w,oe as x,V as y,h as z};
|