express-zod-api 29.1.1 → 29.2.0
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 +12 -0
- package/README.md +3 -3
- package/dist/documentation-helpers-CYQ7k1Oy.js +1 -0
- package/dist/documentation.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/integration.d.ts +1 -1
- package/dist/integration.js +1 -1
- package/package.json +1 -1
- package/dist/documentation-helpers-D20ugUYK.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## Version 29
|
|
4
4
|
|
|
5
|
+
### v29.2.0
|
|
6
|
+
|
|
7
|
+
- Added support for the `oxfmt` formatter in `Integration::printFormatted()`:
|
|
8
|
+
- The generator also tries `oxfmt` after `prettier` when `oxfmt` is installed.
|
|
9
|
+
|
|
10
|
+
### v29.1.2
|
|
11
|
+
|
|
12
|
+
- Fixed the generated Documentation having `composition: "components"`:
|
|
13
|
+
- For routes sharing same input schema but having differed path parameters;
|
|
14
|
+
- The generator produced a single body component referenced by both operations;
|
|
15
|
+
- Found and reported by [@marco-carvalho](https://github.com/marco-carvalho).
|
|
16
|
+
|
|
5
17
|
### v29.1.1
|
|
6
18
|
|
|
7
19
|
- Fixed an issue for path parameters having `.optional()` schema:
|
package/README.md
CHANGED
|
@@ -1218,8 +1218,8 @@ import "@express-zod-api/zod-plugin"; // in your routing.ts file
|
|
|
1218
1218
|
## End-to-End Type Safety
|
|
1219
1219
|
|
|
1220
1220
|
You can generate a TypeScript file containing the IO types of your API and a client for it, giving you end-to-end type
|
|
1221
|
-
safety between your API and frontend. Make sure you have `typescript` installed. Consider also installing
|
|
1222
|
-
|
|
1221
|
+
safety between your API and frontend. Make sure you have `typescript` installed. Consider also installing either
|
|
1222
|
+
`prettier` or `oxfmt` for using the async `printFormatted()` method.
|
|
1223
1223
|
|
|
1224
1224
|
```ts
|
|
1225
1225
|
import { Integration } from "express-zod-api/integration";
|
|
@@ -1230,7 +1230,7 @@ const client = new Integration({
|
|
|
1230
1230
|
variant: "client", // <— optional, see also "types" for a DIY solution
|
|
1231
1231
|
});
|
|
1232
1232
|
|
|
1233
|
-
const
|
|
1233
|
+
const formattedTypescriptCode = await client.printFormatted(); // or just .print() for unformatted
|
|
1234
1234
|
```
|
|
1235
1235
|
|
|
1236
1236
|
Alternatively, you can supply your own `format` function into that method or use a regular `print()` method instead.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{A as e,C as t,F as n,G as r,J as i,L as a,M as o,P as s,Q as c,U as l,W as u,X as d,Z as f,b as p,q as m,r as h,tt as g,v as _}from"./routing-walker-DEXhtG7U.js";import{z as v}from"zod";import*as y from"ramda";import{isReferenceObject as b,isSchemaObject as x}from"openapi3-ts/oas32";const S=e=>e.type===`object`,C=y.mergeDeepWith((e,t)=>{if(Array.isArray(e)&&Array.isArray(t))return y.concat(e,t);if(e===t)return t;throw Error(`Can not flatten properties`,{cause:{a:e,b:t}})}),w=new Set([`type`,`properties`,`required`,`examples`,`description`,`additionalProperties`]),T=e=>{for(let t of Object.keys(e))if(!w.has(t))return!1;return!0},E=y.pair(!0),ee=(e,t,n)=>!(`allOf`in e)||!e.allOf?[]:e.allOf.map(e=>{if(t===`throw`&&!(e.type===`object`&&T(e)))throw Error(`Can not merge`);return y.pair(n,e)}),te=e=>{let t=[];return e.anyOf&&t.push(...y.map(E,e.anyOf)),e.oneOf&&t.push(...y.map(E,e.oneOf)),t},ne=(e,t,n,i)=>{if(!r(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)t.properties[e]??=o;i||n.push(...a)},re=(e,t,n)=>{t.examples?.length&&(e.examples=n?y.concat(e.examples||[],t.examples):a(e.examples?.filter(r)||[],t.examples.filter(r),([e,t])=>y.mergeDeepRight(e,t)))},D=(e,t=`coerce`)=>{let n=[y.pair(!1,e)],r={type:`object`,properties:{}},i=[];for(let[e,a]of n)a.description&&(r.description??=a.description),n.push(...ee(a,t,e)),n.push(...te(a)),re(r,a,e),S(a)&&(n.push([e,{examples:O(a)}]),a.properties&&(r.properties=(t===`throw`?C:y.mergeDeepRight)(r.properties,a.properties),!e&&a.required&&i.push(...a.required)),ne(a,r,i,e));return i.length&&(r.required=[...new Set(i)]),r},O=e=>Object.entries(e.properties||{}).reduce((e,[t,n])=>{let{examples:i=[]}=r(n)?n:{};return a(e,i.map(y.objOf(t)),([e,t])=>({...e,...t}))},[]),k=`x-coerce`,A=(e,t)=>{if(e[`x-coerce`]===!0)return!0;if(e.anyOf)return e.anyOf.some(e=>A(e,t));if(e.oneOf)return e.oneOf.some(e=>A(e,t));if(e.allOf)return e.allOf.every(e=>A(e,t));if(e.type===void 0||e.type===`string`)return!0;if(t===`query`&&[`array`,`object`].includes(e.type)){let n=[e.items,e.prefixItems,e.additionalItems,Object.values(e.properties??{}),e.additionalProperties,e.propertyNames];for(let e of n){if(!r(e))continue;let n=Array.isArray(e)?e:[e];for(let e of n)if(r(e)&&!A(e,t))return!1}return!0}return!1};let j;const M=()=>j??=new Set(`a-im.accept.accept-additions.accept-charset.accept-datetime.accept-encoding.accept-features.accept-language.accept-signature.access-control.access-control-request-headers.access-control-request-method.alpn.alt-used.amp-cache-transform.apply-to-redirect-ref.authorization.available-dictionary.c-ext.c-man.c-opt.c-pep.c-pep-info.cache-control.cal-managed-id.caldav-timezones.capsule-protocol.cdn-loop.cert-not-after.cert-not-before.client-cert.client-cert-chain.close.cmcd-object.cmcd-request.cmcd-session.cmcd-status.cmsd-dynamic.cmsd-static.concealed-auth-export.configuration-context.connection.content-digest.content-disposition.content-encoding.content-id.content-language.content-length.content-location.content-md5.content-range.content-script-type.content-type.cookie.cookie2.cta-common-access-token.dasl.date.dav.default-style.delta-base.deprecation.depth.derived-from.destination.detached-jws.dictionary-id.differential-id.digest.dpop.early-data.ediint-features.expect.expect-ct.ext.forwarded.from.getprofile.hobareg.host.http2-settings.if.if-match.if-modified-since.if-none-match.if-range.if-schedule-tag-match.if-unmodified-since.im.include-referred-token-binding-id.incremental.isolation.keep-alive.label.last-event-id.link.link-template.lock-token.man.max-forwards.memento-datetime.meter.method-check.method-check-expires.mime-version.negotiate.odata-entityid.odata-isolation.odata-maxversion.odata-version.opt.ordering-type.origin.origin-agent-cluster.oscore.oslc-core-version.overwrite.pep.pep-info.permissions-policy.pics-label.ping-from.ping-to.position.pragma.prefer.preference-applied.priority.profileobject.protocol.protocol-info.protocol-query.protocol-request.proxy-authorization.proxy-features.proxy-instruction.range.redirect-ref.referer.referer-root.referrer-policy.repeatability-client-id.repeatability-first-sent.repeatability-request-id.repeatability-result.replay-nonce.reporting-endpoints.repr-digest.safe.schedule-reply.schedule-tag.sec-fetch-storage-access.sec-gpc.sec-purpose.sec-token-binding.sec-websocket-extensions.sec-websocket-key.sec-websocket-protocol.sec-websocket-version.security-scheme.signature.signature-input.slug.soapaction.status-uri.sunset.surrogate-capability.tcn.te.timeout.topic.traceparent.tracestate.trailer.transfer-encoding.ttl.upgrade.urgency.uri.user-agent.variant-vary.via.want-content-digest.want-digest.want-repr-digest.want-unencoded-digest.warning.x-content-type-options.x-frame-options`.split(`.`)),N={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},P=e=>e.replace(d,e=>`{${e.slice(1)}}`),F=({},e)=>{if(e.isResponse)throw new t(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},I=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),L=({zodSchema:e,jsonSchema:t})=>{if(!m(e,`union`)||!(`discriminator`in e._zod.def))return t;let n=e._zod.def.discriminator;return{...t,discriminator:t.discriminator??{propertyName:n}}},R=y.tryCatch(({jsonSchema:e})=>{if(!e.allOf)throw`no allOf`;return D(e,`throw`)},(e,{jsonSchema:t})=>t),z=({jsonSchema:e})=>{if(!e.anyOf||!e.anyOf.length)return e;let t=e.anyOf[0];return Object.assign(t,{type:K(t.type)})},B=e=>e,V=({jsonSchema:e},n)=>{if(n.isResponse)throw new t(`Please use ez.dateOut() for output.`,n);return e},H=({jsonSchema:e},n)=>{if(!n.isResponse)throw new t(`Please use ez.dateIn() for input.`,n);return e},U=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),W=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,G=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return N?.[t]},K=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],ie=({zodSchema:e,jsonSchema:t},n)=>{let r=e._zod.def[n.isResponse?`out`:`in`],i=e._zod.def[n.isResponse?`in`:`out`];if(!m(r,`transform`))return t;let a=B(Z(i,{ctx:n}));if(x(a))if(n.isResponse){let e=u(r,G(a));if(e&&[`number`,`string`,`boolean`].includes(e))return{...t,type:e}}else{let{type:e,...t}=a;return{...t,format:`${t.format||e} (preprocessed)`}}return t},q=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!r(t.properties.raw)?e:t.properties.raw},J=e=>e.length?y.fromPairs(y.zip(y.times(e=>`example${e+1}`,e.length),y.map(y.objOf(`dataValue`),e))):void 0,Y=(e,t)=>t?.has(e)||e.startsWith(`x-`)||M().has(e),ae=({method:e,path:t,security:n,inputSources:r,isHeader:i})=>{let a=new Set(l(t)),o=r.includes(`query`),s=r.includes(`params`),c=r.includes(`headers`),u=r.includes(`cookies`)||r.includes(`signedCookies`),d;c&&n&&(d=h(n,`header`));let f;return u&&n&&(f=h(n,`cookie`)),{pathParams:a,getLocation:n=>{if(s&&a.has(n)&&a.delete(n))return`path`;if(u&&f?.has(n))return`cookie`;if(c&&(i?.(n,e,t)??Y(n,d)))return`header`;if(o&&e!==`query`)return`query`},isQueryEnabled:o}},oe=({path:e,method:t,flatRequest:n,makeRef:a,composition:o,getLocation:s,description:c=`${t.toUpperCase()} ${e} Parameter`})=>{let l=[];for(let[e,t]of Object.entries(n.properties)){if(!r(t))continue;let u=s(e);if(!u)continue;let d=B(t),f=o===`components`?a(t.id||JSON.stringify(t),d,t.id||i(c,e)):d;l.push({name:e,in:u,deprecated:t.deprecated,required:n.required?.includes(e)||u===`path`,description:d.description||c,schema:f,examples:J(x(d)&&d.examples?.length?d.examples:y.pluck(e,n.examples?.filter(y.both(r,y.has(e)))||[]))})}return l},X={nullable:z,union:L,bigint:U,intersection:R,tuple:W,pipe:ie,[o]:V,[e]:H,[p]:F,[_]:q,[s]:I},se=(e,t,n)=>{let r=[e,t],i=e=>/schema\d+$/.test(e)?void 0:e;for(let e=0;e<r.length;e++){let a=r[e];if(y.is(Object,a)){if(b(a)&&!a.$ref.startsWith(`#/components`)){let e=a.$ref.split(`/`).pop(),r=t[e];if(r){let t=r.id||i(e);a.$ref=n.makeRef(t||r,B(r),t).$ref}continue}r.push(...y.values(a))}y.is(Array,a)&&r.push(...y.values(a))}return e},Z=(e,{ctx:i,rules:a=X})=>{let{$defs:o={},properties:s={}}=v.toJSONSchema(v.object({subject:e}),{unrepresentable:`any`,io:i.isResponse?`output`:`input`,override:e=>{let r=v.globalRegistry.get(e.zodSchema)?.id;if(r){let n=i.seenIds.get(r);if(n&&n!==e.zodSchema)throw new t(`The meta id "${r}" is used by two different schemas. Please make the ids unique or reuse the same schema instance.`,i);i.seenIds.set(r,e.zodSchema)}let o=n(e.zodSchema),s=a[o&&o in a?o:e.zodSchema._zod.def.type];if(s){let t={...s(e,i)};for(let t in e.jsonSchema)delete e.jsonSchema[t];Object.assign(e.jsonSchema,t)}}});return se(r(s.subject)?s.subject:{},o,i)},Q=(e,t)=>{if(b(e))return[e,!1];let n=!1,r=y.map(e=>{let[r,i]=Q(e,t);return n||=i,r}),i=y.omit(t),a={properties:i,examples:y.map(i),required:y.without(t),allOf:r,oneOf:r,anyOf:r},o=y.evolve(a,e);return[o,n||!!o.required?.length]},ce=({method:e,path:t,schema:n,mimeTypes:r,variant:a,makeRef:o,composition:s,hasMultipleStatusCodes:l,statusCode:u,brandHandling:d,seenIds:p,description:m=`${e.toUpperCase()} ${t} ${c(a)} response ${l?u:``}`.trim()})=>{if(!f(e,r))return{description:m};let h=B(Z(n,{rules:{...d,...X},ctx:{isResponse:!0,makeRef:o,path:t,method:e,seenIds:p}})),_=[];x(h)&&h.examples&&(_.push(...h.examples),delete h.examples);let v=s===`components`?o(n,h,i(m)):h;return{description:m,content:y.fromPairs(r.map(e=>[e,{[e===g.sse?`itemSchema`:`schema`]:v,examples:J(_)}]))}},le=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},ue=({name:e},t)=>{let n={type:`apiKey`,in:`query`,name:e};return t?.includes(`body`)&&(t?.includes(`query`)?(n[`x-in-alternative`]=`body`,n.description=`${e} CAN also be supplied within the request body`):(n[`x-in-actual`]=`body`,n.description=`${e} MUST be supplied within the request body instead of query`)),n},de=({name:e})=>({type:`apiKey`,in:`header`,name:e}),fe=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),pe=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),$=({flows:e={},oauth2MetadataUrl:t})=>({type:`oauth2`,flows:y.map(e=>({...e,scopes:e.scopes||{}}),y.reject(y.isNil,e)),oauth2MetadataUrl:t}),me=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?le(e):e.type===`input`?ue(e,t):e.type===`header`?de(e):e.type===`cookie`?fe(e):e.type===`openid`?pe(e):$(e);return e.map(e=>e.map(({deprecated:e,...t})=>({...n(t),deprecated:e})))},he=(e,t,n)=>e.map(e=>e.reduce((e,r)=>{let i=n(r),a=[`oauth2`,`openIdConnect`].includes(r.type);return Object.assign(e,{[i]:a?t:[]})},{})),ge=({schema:e,brandHandling:t,makeRef:n,path:r,method:i,seenIds:a})=>Z(e,{rules:{...t,...X},ctx:{isResponse:!1,makeRef:n,path:r,method:i,seenIds:a}}),_e=({method:e,path:t,bodyJsonSchema:n,hasRequiredBodyProps:a,flatRequest:o,mimeType:s,makeRef:c,composition:l,paramNames:u,description:d=`${e.toUpperCase()} ${t} Request body`})=>{let f=B(n),p=[];x(f)&&f.examples&&(p.push(...f.examples),delete f.examples);let m={schema:l===`components`?c(JSON.stringify(f),f,i(d)):f,examples:J(p.length?p:o.examples?.filter(e=>r(e)&&!Array.isArray(e)).map(y.omit(u))||[])},h={description:d,content:{[s]:m}};return(a||s===g.raw)&&(h.required=!0),h},ve=e=>Object.entries(e).reduce((e,[t,n])=>{if(!n)return e;if(typeof n==`string`)return e.concat({name:t,description:n});let{url:r,...i}=n,a={...i,name:t};return r&&(a.externalDocs={...a.externalDocs,url:r}),e.concat(a)},[]),ye=(e,t=50)=>!e||e.length<=t?e:e.slice(0,Math.max(1,t||0)-1)+`…`,be=e=>e.length?e.slice():void 0;export{me as a,Q as c,P as d,ye as f,A as h,ce as i,ae as l,D as m,ge as n,he as o,k as p,oe as r,ve as s,_e as t,be as u};
|
package/dist/documentation.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C as e,J as t,V as n,Y as r,c as i,i as a,n as o,t as s,tt as c}from"./routing-walker-DEXhtG7U.js";import{a as l,c as u,d,f,i as p,l as m,m as h,n as g,o as _,r as v,s as y,t as b,u as x}from"./documentation-helpers-
|
|
1
|
+
import{C as e,J as t,V as n,Y as r,c as i,i as a,n as o,t as s,tt as c}from"./routing-walker-DEXhtG7U.js";import{a as l,c as u,d,f,i as p,l as m,m as h,n as g,o as _,r as v,s as y,t as b,u as x}from"./documentation-helpers-CYQ7k1Oy.js";import"zod";import*as S from"ramda";import{OpenApiBuilder as C}from"openapi3-ts/oas32";const w=({description:e,summary:t=e,trim:n})=>n(t);var T=class extends C{#e=new Map;#t=new Map;#n=new Map;#r=new Map;#i(e,t,n){let r=this.#n.get(e);if(!r){let t=+!n;do r=`${n??`Schema`}${t?this.#n.size+t:``}`,t++;while(this.rootDoc.components?.schemas?.[r]);this.#n.set(e,r)}return this.addSchema(r,t),{$ref:`#/components/schemas/${r}`}}#a(n,r,i){let a=i||t(r,n),o=this.#t.get(a);if(o===void 0)return this.#t.set(a,1),a;if(i)throw new e(`Duplicated operationId: "${i}"`,{method:r,isResponse:!1,path:n});return o++,this.#t.set(a,o),`${a}${o}`}#o(e){let t=JSON.stringify(e);for(let e in this.rootDoc.components?.securitySchemes||{})if(t===JSON.stringify(this.rootDoc.components?.securitySchemes?.[e]))return e;let n=(this.#e.get(e.type)||0)+1;return this.#e.set(e.type,n),`${e.type.toUpperCase()}_${n}`}#s({tags:e,server:t,info:n={title:`Generated by Express Zod API`,version:`0.0.0`}}){if(this.addInfo(n),e&&(this.rootDoc.tags=y(e)),t)for(let e of Array.isArray(t)?t:[t])this.addServer(typeof e==`string`?{url:e}:e)}#c(t,n){if(t===`head`||!n.includes(`:`))return;let i=r(n),a=this.#r.get(i);if(a!==void 0&&a!==n)throw new e(`Path has a duplicate: the normalized path "${i}" is already registered with different parameter names at "${a}"`,{method:t,path:n,isResponse:!1});a===void 0&&this.#r.set(i,n)}#l({config:t,descriptions:r,brandHandling:o,isHeader:s,summarizer:y=w,composition:C=`inline`}){let T={composition:C,brandHandling:o,makeRef:this.#i.bind(this),seenIds:new Map};return(o,C,w)=>{this.#c(o,C);let E={...T,path:C,method:o,endpoint:w},{description:D,summary:O,scopes:k,inputSchema:A,security:j}=w,M=n(o,t.inputSources),{pathParams:N,getLocation:P}=m({method:o,path:C,security:j,inputSources:M,isHeader:s}),F=this.#a(C,o,w.getOperationId(o)),I=g({...E,schema:A}),L=h(I),R=v({...E,getLocation:P,flatRequest:L,description:r?.requestParameter?.({method:o,path:C,operationId:F})});if(N.size)throw new e(`The input schema is missing the path parameter "${[...N][0]}"`,{method:o,path:C,isResponse:!1});let z={};for(let e of i){let t=w.getResponses(e);for(let{mimeTypes:n,schema:i,statusCodes:a}of t)for(let s of a)z[s]=p({...E,variant:e,schema:i,mimeTypes:n,statusCode:s,hasMultipleStatusCodes:t.length>1||a.length>1,description:r?.[`${e}Response`]?.({method:o,path:C,operationId:F,statusCode:s})})}let B;if(M.includes(`body`)){let e=S.pluck(`name`,R),[t,n]=u(I,e);B=b({...E,bodyJsonSchema:t,hasRequiredBodyProps:n,flatRequest:L,paramNames:e,mimeType:c[w.getProbableRequestType(o)],description:r?.requestBody?.({method:o,path:C,operationId:F})})}let V=_(l(a(j),M),k,e=>{let t=this.#o(e);return this.addSecurityScheme(t,e),t}),H={operationId:F,summary:y({summary:O,description:D,trim:f}),description:D,deprecated:w.isDeprecated||void 0,tags:x(w.tags),parameters:x(R),requestBody:B,security:x(V),responses:z};this.addPath(d(C),{[o]:H})}}constructor({hasHeadMethod:e=!0,...t}){super(),this.#s(t);let n=this.#l(t),r=e?o(n):n;s({...t,onEndpoint:r})}};export{T as Documentation,e as DocumentationError};
|
package/dist/index.d.ts
CHANGED
|
@@ -515,7 +515,7 @@ declare const testEndpoint: <LOG extends FlatObject, REQ extends RequestOptions>
|
|
|
515
515
|
responseMock: import("node-mocks-http").MockResponse<Response<any, Record<string, any>>>;
|
|
516
516
|
loggerMock: AbstractLogger &
|
|
517
517
|
LOG & {
|
|
518
|
-
_getLogs: () => Record<"
|
|
518
|
+
_getLogs: () => Record<"debug" | "info" | "warn" | "error", unknown[]>;
|
|
519
519
|
};
|
|
520
520
|
}>;
|
|
521
521
|
interface MiddlewareLike<RET extends FlatObject> {
|
|
@@ -545,7 +545,7 @@ declare const testMiddleware: <LOG extends FlatObject, REQ extends RequestOption
|
|
|
545
545
|
responseMock: import("node-mocks-http").MockResponse<Response<any, Record<string, any>>>;
|
|
546
546
|
loggerMock: AbstractLogger &
|
|
547
547
|
LOG & {
|
|
548
|
-
_getLogs: () => Record<"
|
|
548
|
+
_getLogs: () => Record<"debug" | "info" | "warn" | "error", unknown[]>;
|
|
549
549
|
};
|
|
550
550
|
}>;
|
|
551
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,G as i,H as a,I as o,K as s,N as c,O as l,R as u,S as ee,T as d,V as f,a as te,c as ne,d as p,et as re,f as m,g as h,h as g,j as ie,k as ae,l as oe,m as _,o as se,p as v,s as y,t as ce,tt as b,u as x,w as le,x as ue,y as de,z as S}from"./routing-walker-DEXhtG7U.js";import{t as C}from"./peer-helpers-rB2euA-8.js";import{h as fe,l as pe,m as me,p as he}from"./documentation-helpers-D20ugUYK.js";import{globalRegistry as w,z as T}from"zod";import*as ge from"ramda";import E,{isHttpError as _e}from"http-errors";import ve,{blue as ye,cyanBright as be,green as xe,hex as D,italic as Se,red as Ce,whiteBright as O}from"ansis";import{inspect as we}from"node:util";import{performance as k}from"node:perf_hooks";import A from"express";import Te from"node:http";import Ee from"node:https";import{setInterval as De}from"node:timers/promises";import{createRequest as Oe,createResponse as ke}from"node-mocks-http";function Ae(e){return e}const je=(e,t)=>e&&t?e.and(t):e||t,Me=(e,t)=>e?e.and(t):t;var Ne=class e{#e;constructor(e){this.#e=e}async execute(...t){try{return await this.#e(...t)}catch(r){let{response:i,logger:a,error:o}=t[0],s=new n(S(r),o||void 0);e.lastResort({response:i,logger:a,error:s})}}static lastResort({error:e,logger:t,response:n}){t.error(`Result handler failure`,e);let r=p(E(500,`An error occurred while serving the result: ${e.message}.`+(e.handled?`\nOriginal error: ${e.handled.message}.`:``),{expose:_e(e.cause)?e.cause.expose:!1}));n.status(500).type(`text/plain`).end(r)}},j=class extends Ne{#e;#t;constructor(e){super(e.handler),this.#e=e.positive,this.#t=e.negative}getPositiveResponse(e){return v(this.#e,{variant:`positive`,args:[e],statusCodes:[y.positive],mimeTypes:[b.json]})}getNegativeResponse(){return v(this.#t,{variant:`negative`,args:[],statusCodes:[y.negative],mimeTypes:[b.json]})}};const M=T.object({status:T.literal(`error`),error:T.object({message:T.string()})});w.add(M,{examples:[{status:`error`,error:{message:`Sample error message`}}]});const N=new j({positive:e=>{let t=T.object({status:T.literal(`success`),data:e}),n=o(e);return n.length&&w.add(t,{examples:n.map(e=>({status:`success`,data:e}))}),t},negative:M,handler:({error:e,input:t,output:n,request:r,response:i,logger:a})=>{if(e){let n=x(e);m(n,a,r,t),i.status(n.statusCode).set(n.headers).json({status:`error`,error:{message:p(n)}});return}i.status(y.positive).json({status:`success`,data:n})}}),P=T.string();w.add(P,{examples:[`Sample error message`]});const F=new j({positive:e=>{let t=e instanceof T.ZodObject&&`items`in e.shape&&e.shape.items instanceof T.ZodArray?e.shape.items:T.array(T.any());if(o(t).length)return t;let n=o(e).filter(e=>i(e)&&`items`in e&&Array.isArray(e.items)).map(e=>e.items);if(n?.length){let e=t.meta();w.remove(t).add(t,{...e,examples:n})}return t},negative:{schema:P,mimeType:`text/plain`},handler:({response:e,output:t,error:n,logger:r,request:i,input:a})=>{if(n){let t=x(n);m(t,r,i,a),e.status(t.statusCode).type(`text/plain`).send(p(t));return}if(`items`in t&&Array.isArray(t.items)){e.status(y.positive).json(t.items);return}throw Error(`Property 'items' is missing in the endpoint output`)}}),I=e=>{let t=[];return e.scope&&t.push(e.scope),e.noStore&&t.push(`no-store`),e.noCache&&t.push(`no-cache`),e.maxAge!==void 0&&t.push(`max-age=${e.maxAge}`),e.sMaxAge!==void 0&&t.push(`s-maxage=${e.sMaxAge}`),e.mustRevalidate&&t.push(`must-revalidate`),e.proxyRevalidate&&t.push(`proxy-revalidate`),e.mustUnderstand&&t.push(`must-understand`),e.immutable&&t.push(`immutable`),e.noTransform&&t.push(`no-transform`),e.staleWhileRevalidate!==void 0&&t.push(`stale-while-revalidate=${e.staleWhileRevalidate}`),e.staleIfError!==void 0&&t.push(`stale-if-error=${e.staleIfError}`),t.join(`, `)},Pe={"max-age":`maxAge`,"max-stale":`maxStale`,"min-fresh":`minFresh`,"stale-if-error":`staleIfError`},Fe={"no-cache":`noCache`,"no-store":`noStore`,"no-transform":`noTransform`,"only-if-cached":`onlyIfCached`},Ie=e=>{if(!e)return;let t={};for(let n of e.toLowerCase().split(`,`)){let[e,r]=n.split(`=`),i=Pe[e.trim()];if(i){let e=parseInt(r?.trim()??``,10);isNaN(e)||(t[i]=e);continue}let a=Fe[e.trim()];a&&(t[a]=!0)}return t},L=e=>new g({handler:async({request:t,response:n})=>(e&&n.setHeader(`Cache-Control`,I(e)),{get ifNoneMatch(){let e=t.headers[`if-none-match`];if(!e)return;let n=e.trim();return n===`*`?n:n.split(`,`).map(e=>e.trim().replace(/^(?:W\/)?"/,``).replace(/"$/,``))},get ifModifiedSince(){let e=t.headers[`if-modified-since`];if(!e)return;let n=new Date(e);return isNaN(n.getTime())?void 0:n},get cacheControl(){return Ie(t.headers[`cache-control`])},addCachePolicy:t=>{n.setHeader(`Cache-Control`,I({...e,...t}))},setETag:e=>{n.setHeader(`ETag`,e.startsWith(`"`)?e:`"${e}"`)},setLastModified:e=>{n.setHeader(`Last-Modified`,e.toUTCString())},setVary:(...e)=>{n.setHeader(`Vary`,e.join(`, `))},setExpires:e=>{n.setHeader(`Expires`,e.toUTCString())},clearSiteData:()=>{n.setHeader(`Clear-Site-Data`,`"cache"`)},notModified:()=>{n.status(304).end()}})}),R=e=>new g({handler:async({request:t,response:n})=>({getCookie:e=>t.signedCookies?.[e]??t.cookies?.[e],setCookie:(t,r,i)=>{n.cookie(t,r,{...e,...i})},clearCookie:(t,r)=>{n.clearCookie(t,{...e,...r})}})}),z=e=>{let t=C(`express-rate-limit`)({...e,handler:(e,t,n,r)=>{n(E(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 B=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=je(this.schema,t.schema),n}addMiddleware(e){return this.#e(e instanceof g?e:new g(e))}useCookies(...e){return this.#e(R(...e))}useCache(...e){return this.#e(L(...e))}useRateLimit(...e){return this.#e(z(...e))}use=this.addExpressMiddleware;addExpressMiddleware(...e){return this.#e(new _(...e))}addContext(e){return this.#e(new g({handler:({ctx:t})=>e(t)}))}build({input:e=u,output:t,operationId:n,scope:r,tag:i,method:a,...o}){let{middlewares:s,resultHandler:c}=this,l=typeof a==`string`?[a]:a,ee=typeof n==`function`?n:e=>n&&`${n}${e===`head`?`__HEAD`:``}`,d=typeof r==`string`?[r]:r||[],f=typeof i==`string`?[i]:i||[];return new oe({...o,middlewares:s,outputSchema:t,resultHandler:c,scopes:d,tags:f,methods:l,getOperationId:ee,inputSchema:Me(this.schema,e)})}buildVoid({handler:e,...t}){return this.build({...t,output:u,handler:async t=>(await e(t),{})})}};const Le=new B(N),Re=new B(F),V={debug:ye,info:xe,warn:D(`#FFA500`),error:Ce,ctx:be},H={debug:10,info:20,warn:30,error:40},ze=e=>i(e)&&Object.keys(H).some(t=>t in e),Be=e=>e in H,Ve=(e,t)=>H[e]<H[t],U=ge.memoizeWith((e,t)=>`${e}${t}`,(e,t=0)=>Intl.NumberFormat(void 0,{useGrouping:!1,minimumFractionDigits:0,maximumFractionDigits:t,style:`unit`,unitDisplay:`long`,unit:e})),He=e=>e<1e-6?U(`nanosecond`,3).format(e/1e-6):e<.001?U(`nanosecond`).format(e/1e-6):e<1?U(`microsecond`).format(e/.001):e<1e3?U(`millisecond`).format(e):e<6e4?U(`second`,2).format(e/1e3):U(`minute`,2).format(e/6e4);var W=class e{config;constructor({color:e=ve.isSupported(),level:t=s()?`warn`:`debug`,depth:n=2,ctx:r={}}={}){this.config={color:e,level:t,depth:n,ctx:r}}format(e){let{depth:t,color:n,level:r}=this.config;return we(e,{depth:t,colors:n,breakLength:r===`debug`?80:1/0,compact:r!==`debug`||3})}print(e,t,n){let{level:r,ctx:{requestId:i,...a},color:o}=this.config;if(r===`silent`||Ve(e,r))return;let s=[new Date().toISOString()];i&&s.push(o?V.ctx(i):i),s.push(o?`${V[e](e)}:`:`${e}:`,t),n!==void 0&&s.push(this.format(n)),Object.keys(a).length>0&&s.push(this.format(a)),console.log(s.join(` `))}debug(e,t){this.print(`debug`,e,t)}info(e,t){this.print(`info`,e,t)}warn(e,t){this.print(`warn`,e,t)}error(e,t){this.print(`error`,e,t)}child(t){return new e({...this.config,ctx:t})}get ctx(){return this.config.ctx}profile(e){let t=k.now();return()=>{let n=k.now()-t,{message:r,severity:i=`debug`,formatter:a=He}=typeof e==`object`?e:{message:e};this.print(typeof i==`function`?i(n):i,r,a(n))}}},Ue=class{logger;config;#e=new WeakMap;constructor(e,t){this.logger=e,this.config=t}#t(e,t,n){if(!e.isSchemaChecked){for(let e of[`input`,`output`]){let r=[T.toJSONSchema(t[`${e}Schema`],{unrepresentable:`any`})];for(let t of r){t.type&&t.type!==`object`&&this.logger.warn(`Endpoint ${e} schema is not object-based`,n);for(let e of[`allOf`,`oneOf`,`anyOf`])t[e]&&r.push(...t[e])}}if(t.getProbableRequestType()===`json`){let e=h(t.inputSchema,`input`);e&&this.logger.warn(`The final input schema of the endpoint contains an unsupported JSON payload type.`,{...n,reason:e})}for(let e of ne)for(let{mimeTypes:r,schema:i}of t.getResponses(e)){if(!r?.includes(b.json))continue;let t=h(i,`output`);t&&this.logger.warn(`The final ${e} response schema of the endpoint contains an unsupported JSON payload type.`,{...n,reason:t})}e.isSchemaChecked=!0}}#n(e,t,n,r,a){if(e.paths.has(r))return;let{pathParams:o,getLocation:s,isQueryEnabled:c}=pe({method:n,path:r,security:t.security,inputSources:f(n,this.config.inputSources)});if(!(o.size===0&&!c)){e.flat??=me(T.toJSONSchema(t.inputSchema,{unrepresentable:`any`,io:`input`,override:({zodSchema:e,jsonSchema:t})=>{(e._zod.traits.has(`$ZodPreprocess`)||`coerce`in e._zod.def&&e._zod.def.coerce)&&(t[he]=!0)}}));for(let[t,n]of Object.entries(e.flat.properties)){if(!i(n))continue;let r=s(t);r!==`path`&&r!==`query`||(r===`path`&&!e.flat.required?.includes(t)&&this.logger.warn(`The path parameter "${t}" is declared optional in the input schema, but path parameters are always required since Express matches the route only when the segment is present.`,{...a,name:t}),!fe(n,r)&&this.logger.warn(`The ${r} parameter "${t}" has a schema that most likely would not accept the parsed data, ${r===`path`?`since path parameters always arrive as strings`:`depending on the "queryParser" config option`}. Convert the parsed value from "z.string()" using ".transform()" method, or use "z.coerce" at least.`,{...a,name:t,jsonSchema:n}))}for(let e of o)this.logger.warn(`The input schema of the endpoint is most likely missing the parameter of the path it's assigned to.`,{...a,param:e});e.paths.add(r)}}check=(e,t,n)=>{let r=this.#e.get(n);r||(r={isSchemaChecked:!1,paths:new Set},this.#e.set(n,r)),this.#t(r,n,{method:e,path:t}),this.#n(r,n,e,t,{method:e,path:t})}};const G=e=>e.sort((e,t)=>re(t)-+re(e)||e.localeCompare(t)).join(`, `).toUpperCase(),We=e=>({method:t},n,r)=>{let i=G(e);n.set({Allow:i}),r(E(405,`${t} is not allowed`,{headers:{Allow:i}}))},Ge=({app:e,getLogger:t,config:n,routing:r})=>{let i=s()?void 0:new Ue(t(),n),a=new Map;return ce({routing:r,config:n,onEndpoint:(e,t,r)=>{i?.check(e,t,r),a.has(t)||a.set(t,new Map(n.cors?[[`options`,r]]:[])),a.get(t)?.set(e,r)},onStatic:e.use.bind(e)}),a},K=({app:e,config:t,getLogger:n,...r})=>{let i=Ge({app:e,getLogger:n,config:t,...r}),a=new Map;for(let[r,o]of i){let i=Array.from(o.keys());i.includes(`get`)&&i.push(`head`);for(let[a,s]of o){let o=[];t.cors&&o.push((e,t,n)=>{t.set(`Access-Control-Allow-Methods`,G(i)),n()}),o.push(async(e,r)=>{let i=n(e);return s.execute({request:e,response:r,logger:i,config:t})}),e[a]?.(r,...o)}t.hintAllowedMethods!==!1&&a.set(r,We(i))}for(let[t,n]of a)e.all(t,n)},Ke=e=>`_httpMessage`in e&&typeof e._httpMessage==`object`&&e._httpMessage!==null&&`headersSent`in e._httpMessage&&typeof e._httpMessage.headersSent==`boolean`&&`setHeader`in e._httpMessage&&typeof e._httpMessage.setHeader==`function`,qe=e=>`server`in e&&typeof e.server==`object`&&e.server!==null&&`close`in e.server&&typeof e.server.close==`function`,Je=e=>`encrypted`in e&&typeof e.encrypted==`boolean`&&e.encrypted,Ye=({},e)=>void(!e.headersSent&&e.setHeader(`connection`,`close`)),Xe=e=>{let{promise:t,resolve:n,reject:r}=Promise.withResolvers();return e.close(e=>e?r(e):n()),t},Ze=({timeout:e=1e3,logger:t}={})=>{let n,r=new Set,i=new Set,a=e=>void i.delete(e),o=e=>a(e.destroy()),s=e=>void(Ke(e)?!e._httpMessage.headersSent&&e._httpMessage.setHeader(`connection`,`close`):o(e)),c=e=>void(n?e.destroy():i.add(e.once(`close`,()=>a(e)).once(`error`,()=>o(e)))),l=async()=>{for(let e of r)e.on(`request`,Ye);t?.info(`Graceful shutdown`,{sockets:i.size,timeout:e});for(let e of i)(Je(e)||qe(e))&&s(e);for await(let t of De(10,Date.now()))if(i.size===0||Date.now()-t>=e)break;for(let e of i)o(e);return Promise.allSettled(r.values().map(Xe))},u={sockets:i,add:(...e)=>{for(let t of e)if(!r.has(t)){r.add(t);for(let e of[`connection`,`secureConnection`])t.on(e,c)}return u},shutdown:()=>n??=l(),get isShuttingDown(){return!!n}};return u},q=Symbol.for(`express-zod-api`),Qe=({errorHandler:e,getLogger:t})=>async(n,r,i,a)=>n?e.execute({error:S(n),request:r,response:i,input:null,output:null,ctx:{},logger:t(r)}):a(),$e=({errorHandler:e,getLogger:t})=>async(n,r)=>{let i=E(404,`Can not ${n.method} ${n.path}`),a=t(n);await e.execute({request:n,response:r,logger:a,error:i,input:null,output:null,ctx:{}})},et=e=>(t,{},n)=>{if(Object.values(t?.files||[]).flat().find(({truncated:e})=>e))return n(e);n()},tt=({config:e})=>{let t=C(`cookie-parser`),{secret:n,...r}={...typeof e.cookies==`object`&&e.cookies};return t(n,Object.keys(r).length?r:void 0)},J=e=>typeof e==`function`?e:({},e,t)=>{e.set({"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Headers":`content-type`}),t()},nt=e=>({log:t=>{/not eligible/i.test(t)||e.debug(t)}}),rt=({getLogger:e,config:t})=>{let n=C(`express-fileupload`),{limitError:r,beforeUpload:i,...a}={...typeof t.upload==`object`&&t.upload},o=[];return o.push(async(t,r,o)=>{let s=e(t);return await i?.({request:t,logger:s}),n({debug:!0,...a,abortOnLimit:!1,parseNested:!0,logger:nt(s)})(t,r,o)}),r&&o.push(et(r)),o},it=(e,{},t)=>{Buffer.isBuffer(e.body)&&(e.body={raw:e.body}),t()},at=({logger:e,config:{childLoggerProvider:t,accessLogger:n=({method:e,path:t},n)=>n.debug(`${e}: ${t}`)}})=>async(r,i,a)=>{let o=await t?.({request:r,parent:e})||e;n?.(r,o),r.res&&(r.res.locals[q]={logger:o}),a()},ot=e=>t=>t?.res?.locals[q]?.logger||e;let Y=!1;const st=e=>{Y||(Y=!0,process.on(`deprecation`,({message:t,namespace:n,name:r,stack:i})=>e.warn(`${r} (${n}): ${t}`,i.split(`
|
|
1
|
+
import{B as e,C as t,D as n,E as r,G as i,H as a,I as o,K as s,N as c,O as l,R as u,S as ee,T as d,V as f,a as te,c as ne,d as p,et as re,f as m,g as h,h as g,j as ie,k as ae,l as oe,m as _,o as se,p as v,s as y,t as ce,tt as b,u as x,w as le,x as ue,y as de,z as S}from"./routing-walker-DEXhtG7U.js";import{t as C}from"./peer-helpers-rB2euA-8.js";import{h as fe,l as pe,m as me,p as he}from"./documentation-helpers-CYQ7k1Oy.js";import{globalRegistry as w,z as T}from"zod";import*as ge from"ramda";import E,{isHttpError as _e}from"http-errors";import ve,{blue as ye,cyanBright as be,green as xe,hex as D,italic as Se,red as Ce,whiteBright as O}from"ansis";import{inspect as we}from"node:util";import{performance as k}from"node:perf_hooks";import A from"express";import Te from"node:http";import Ee from"node:https";import{setInterval as De}from"node:timers/promises";import{createRequest as Oe,createResponse as ke}from"node-mocks-http";function Ae(e){return e}const je=(e,t)=>e&&t?e.and(t):e||t,Me=(e,t)=>e?e.and(t):t;var Ne=class e{#e;constructor(e){this.#e=e}async execute(...t){try{return await this.#e(...t)}catch(r){let{response:i,logger:a,error:o}=t[0],s=new n(S(r),o||void 0);e.lastResort({response:i,logger:a,error:s})}}static lastResort({error:e,logger:t,response:n}){t.error(`Result handler failure`,e);let r=p(E(500,`An error occurred while serving the result: ${e.message}.`+(e.handled?`\nOriginal error: ${e.handled.message}.`:``),{expose:_e(e.cause)?e.cause.expose:!1}));n.status(500).type(`text/plain`).end(r)}},j=class extends Ne{#e;#t;constructor(e){super(e.handler),this.#e=e.positive,this.#t=e.negative}getPositiveResponse(e){return v(this.#e,{variant:`positive`,args:[e],statusCodes:[y.positive],mimeTypes:[b.json]})}getNegativeResponse(){return v(this.#t,{variant:`negative`,args:[],statusCodes:[y.negative],mimeTypes:[b.json]})}};const M=T.object({status:T.literal(`error`),error:T.object({message:T.string()})});w.add(M,{examples:[{status:`error`,error:{message:`Sample error message`}}]});const N=new j({positive:e=>{let t=T.object({status:T.literal(`success`),data:e}),n=o(e);return n.length&&w.add(t,{examples:n.map(e=>({status:`success`,data:e}))}),t},negative:M,handler:({error:e,input:t,output:n,request:r,response:i,logger:a})=>{if(e){let n=x(e);m(n,a,r,t),i.status(n.statusCode).set(n.headers).json({status:`error`,error:{message:p(n)}});return}i.status(y.positive).json({status:`success`,data:n})}}),P=T.string();w.add(P,{examples:[`Sample error message`]});const F=new j({positive:e=>{let t=e instanceof T.ZodObject&&`items`in e.shape&&e.shape.items instanceof T.ZodArray?e.shape.items:T.array(T.any());if(o(t).length)return t;let n=o(e).filter(e=>i(e)&&`items`in e&&Array.isArray(e.items)).map(e=>e.items);if(n?.length){let e=t.meta();w.remove(t).add(t,{...e,examples:n})}return t},negative:{schema:P,mimeType:`text/plain`},handler:({response:e,output:t,error:n,logger:r,request:i,input:a})=>{if(n){let t=x(n);m(t,r,i,a),e.status(t.statusCode).type(`text/plain`).send(p(t));return}if(`items`in t&&Array.isArray(t.items)){e.status(y.positive).json(t.items);return}throw Error(`Property 'items' is missing in the endpoint output`)}}),I=e=>{let t=[];return e.scope&&t.push(e.scope),e.noStore&&t.push(`no-store`),e.noCache&&t.push(`no-cache`),e.maxAge!==void 0&&t.push(`max-age=${e.maxAge}`),e.sMaxAge!==void 0&&t.push(`s-maxage=${e.sMaxAge}`),e.mustRevalidate&&t.push(`must-revalidate`),e.proxyRevalidate&&t.push(`proxy-revalidate`),e.mustUnderstand&&t.push(`must-understand`),e.immutable&&t.push(`immutable`),e.noTransform&&t.push(`no-transform`),e.staleWhileRevalidate!==void 0&&t.push(`stale-while-revalidate=${e.staleWhileRevalidate}`),e.staleIfError!==void 0&&t.push(`stale-if-error=${e.staleIfError}`),t.join(`, `)},Pe={"max-age":`maxAge`,"max-stale":`maxStale`,"min-fresh":`minFresh`,"stale-if-error":`staleIfError`},Fe={"no-cache":`noCache`,"no-store":`noStore`,"no-transform":`noTransform`,"only-if-cached":`onlyIfCached`},Ie=e=>{if(!e)return;let t={};for(let n of e.toLowerCase().split(`,`)){let[e,r]=n.split(`=`),i=Pe[e.trim()];if(i){let e=parseInt(r?.trim()??``,10);isNaN(e)||(t[i]=e);continue}let a=Fe[e.trim()];a&&(t[a]=!0)}return t},L=e=>new g({handler:async({request:t,response:n})=>(e&&n.setHeader(`Cache-Control`,I(e)),{get ifNoneMatch(){let e=t.headers[`if-none-match`];if(!e)return;let n=e.trim();return n===`*`?n:n.split(`,`).map(e=>e.trim().replace(/^(?:W\/)?"/,``).replace(/"$/,``))},get ifModifiedSince(){let e=t.headers[`if-modified-since`];if(!e)return;let n=new Date(e);return isNaN(n.getTime())?void 0:n},get cacheControl(){return Ie(t.headers[`cache-control`])},addCachePolicy:t=>{n.setHeader(`Cache-Control`,I({...e,...t}))},setETag:e=>{n.setHeader(`ETag`,e.startsWith(`"`)?e:`"${e}"`)},setLastModified:e=>{n.setHeader(`Last-Modified`,e.toUTCString())},setVary:(...e)=>{n.setHeader(`Vary`,e.join(`, `))},setExpires:e=>{n.setHeader(`Expires`,e.toUTCString())},clearSiteData:()=>{n.setHeader(`Clear-Site-Data`,`"cache"`)},notModified:()=>{n.status(304).end()}})}),R=e=>new g({handler:async({request:t,response:n})=>({getCookie:e=>t.signedCookies?.[e]??t.cookies?.[e],setCookie:(t,r,i)=>{n.cookie(t,r,{...e,...i})},clearCookie:(t,r)=>{n.clearCookie(t,{...e,...r})}})}),z=e=>{let t=C(`express-rate-limit`)({...e,handler:(e,t,n,r)=>{n(E(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 B=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=je(this.schema,t.schema),n}addMiddleware(e){return this.#e(e instanceof g?e:new g(e))}useCookies(...e){return this.#e(R(...e))}useCache(...e){return this.#e(L(...e))}useRateLimit(...e){return this.#e(z(...e))}use=this.addExpressMiddleware;addExpressMiddleware(...e){return this.#e(new _(...e))}addContext(e){return this.#e(new g({handler:({ctx:t})=>e(t)}))}build({input:e=u,output:t,operationId:n,scope:r,tag:i,method:a,...o}){let{middlewares:s,resultHandler:c}=this,l=typeof a==`string`?[a]:a,ee=typeof n==`function`?n:e=>n&&`${n}${e===`head`?`__HEAD`:``}`,d=typeof r==`string`?[r]:r||[],f=typeof i==`string`?[i]:i||[];return new oe({...o,middlewares:s,outputSchema:t,resultHandler:c,scopes:d,tags:f,methods:l,getOperationId:ee,inputSchema:Me(this.schema,e)})}buildVoid({handler:e,...t}){return this.build({...t,output:u,handler:async t=>(await e(t),{})})}};const Le=new B(N),Re=new B(F),V={debug:ye,info:xe,warn:D(`#FFA500`),error:Ce,ctx:be},H={debug:10,info:20,warn:30,error:40},ze=e=>i(e)&&Object.keys(H).some(t=>t in e),Be=e=>e in H,Ve=(e,t)=>H[e]<H[t],U=ge.memoizeWith((e,t)=>`${e}${t}`,(e,t=0)=>Intl.NumberFormat(void 0,{useGrouping:!1,minimumFractionDigits:0,maximumFractionDigits:t,style:`unit`,unitDisplay:`long`,unit:e})),He=e=>e<1e-6?U(`nanosecond`,3).format(e/1e-6):e<.001?U(`nanosecond`).format(e/1e-6):e<1?U(`microsecond`).format(e/.001):e<1e3?U(`millisecond`).format(e):e<6e4?U(`second`,2).format(e/1e3):U(`minute`,2).format(e/6e4);var W=class e{config;constructor({color:e=ve.isSupported(),level:t=s()?`warn`:`debug`,depth:n=2,ctx:r={}}={}){this.config={color:e,level:t,depth:n,ctx:r}}format(e){let{depth:t,color:n,level:r}=this.config;return we(e,{depth:t,colors:n,breakLength:r===`debug`?80:1/0,compact:r!==`debug`||3})}print(e,t,n){let{level:r,ctx:{requestId:i,...a},color:o}=this.config;if(r===`silent`||Ve(e,r))return;let s=[new Date().toISOString()];i&&s.push(o?V.ctx(i):i),s.push(o?`${V[e](e)}:`:`${e}:`,t),n!==void 0&&s.push(this.format(n)),Object.keys(a).length>0&&s.push(this.format(a)),console.log(s.join(` `))}debug(e,t){this.print(`debug`,e,t)}info(e,t){this.print(`info`,e,t)}warn(e,t){this.print(`warn`,e,t)}error(e,t){this.print(`error`,e,t)}child(t){return new e({...this.config,ctx:t})}get ctx(){return this.config.ctx}profile(e){let t=k.now();return()=>{let n=k.now()-t,{message:r,severity:i=`debug`,formatter:a=He}=typeof e==`object`?e:{message:e};this.print(typeof i==`function`?i(n):i,r,a(n))}}},Ue=class{logger;config;#e=new WeakMap;constructor(e,t){this.logger=e,this.config=t}#t(e,t,n){if(!e.isSchemaChecked){for(let e of[`input`,`output`]){let r=[T.toJSONSchema(t[`${e}Schema`],{unrepresentable:`any`})];for(let t of r){t.type&&t.type!==`object`&&this.logger.warn(`Endpoint ${e} schema is not object-based`,n);for(let e of[`allOf`,`oneOf`,`anyOf`])t[e]&&r.push(...t[e])}}if(t.getProbableRequestType()===`json`){let e=h(t.inputSchema,`input`);e&&this.logger.warn(`The final input schema of the endpoint contains an unsupported JSON payload type.`,{...n,reason:e})}for(let e of ne)for(let{mimeTypes:r,schema:i}of t.getResponses(e)){if(!r?.includes(b.json))continue;let t=h(i,`output`);t&&this.logger.warn(`The final ${e} response schema of the endpoint contains an unsupported JSON payload type.`,{...n,reason:t})}e.isSchemaChecked=!0}}#n(e,t,n,r,a){if(e.paths.has(r))return;let{pathParams:o,getLocation:s,isQueryEnabled:c}=pe({method:n,path:r,security:t.security,inputSources:f(n,this.config.inputSources)});if(!(o.size===0&&!c)){e.flat??=me(T.toJSONSchema(t.inputSchema,{unrepresentable:`any`,io:`input`,override:({zodSchema:e,jsonSchema:t})=>{(e._zod.traits.has(`$ZodPreprocess`)||`coerce`in e._zod.def&&e._zod.def.coerce)&&(t[he]=!0)}}));for(let[t,n]of Object.entries(e.flat.properties)){if(!i(n))continue;let r=s(t);(r===`path`||r===`query`)&&(r===`path`&&!e.flat.required?.includes(t)&&this.logger.warn(`The path parameter "${t}" is declared optional in the input schema, but path parameters are always required since Express matches the route only when the segment is present.`,{...a,name:t}),!fe(n,r)&&this.logger.warn(`The ${r} parameter "${t}" has a schema that most likely would not accept the parsed data, ${r===`path`?`since path parameters always arrive as strings`:`depending on the "queryParser" config option`}. Convert the parsed value from "z.string()" using ".transform()" method, or use "z.coerce" at least.`,{...a,name:t,jsonSchema:n}))}for(let e of o)this.logger.warn(`The input schema of the endpoint is most likely missing the parameter of the path it's assigned to.`,{...a,param:e});e.paths.add(r)}}check=(e,t,n)=>{let r=this.#e.get(n);r||(r={isSchemaChecked:!1,paths:new Set},this.#e.set(n,r)),this.#t(r,n,{method:e,path:t}),this.#n(r,n,e,t,{method:e,path:t})}};const G=e=>e.sort((e,t)=>re(t)-+re(e)||e.localeCompare(t)).join(`, `).toUpperCase(),We=e=>({method:t},n,r)=>{let i=G(e);n.set({Allow:i}),r(E(405,`${t} is not allowed`,{headers:{Allow:i}}))},Ge=({app:e,getLogger:t,config:n,routing:r})=>{let i=s()?void 0:new Ue(t(),n),a=new Map;return ce({routing:r,config:n,onEndpoint:(e,t,r)=>{i?.check(e,t,r),a.has(t)||a.set(t,new Map(n.cors?[[`options`,r]]:[])),a.get(t)?.set(e,r)},onStatic:e.use.bind(e)}),a},K=({app:e,config:t,getLogger:n,...r})=>{let i=Ge({app:e,getLogger:n,config:t,...r}),a=new Map;for(let[r,o]of i){let i=Array.from(o.keys());i.includes(`get`)&&i.push(`head`);for(let[a,s]of o){let o=[];t.cors&&o.push((e,t,n)=>{t.set(`Access-Control-Allow-Methods`,G(i)),n()}),o.push(async(e,r)=>{let i=n(e);return s.execute({request:e,response:r,logger:i,config:t})}),e[a]?.(r,...o)}t.hintAllowedMethods!==!1&&a.set(r,We(i))}for(let[t,n]of a)e.all(t,n)},Ke=e=>`_httpMessage`in e&&typeof e._httpMessage==`object`&&e._httpMessage!==null&&`headersSent`in e._httpMessage&&typeof e._httpMessage.headersSent==`boolean`&&`setHeader`in e._httpMessage&&typeof e._httpMessage.setHeader==`function`,qe=e=>`server`in e&&typeof e.server==`object`&&e.server!==null&&`close`in e.server&&typeof e.server.close==`function`,Je=e=>`encrypted`in e&&typeof e.encrypted==`boolean`&&e.encrypted,Ye=({},e)=>void(!e.headersSent&&e.setHeader(`connection`,`close`)),Xe=e=>{let{promise:t,resolve:n,reject:r}=Promise.withResolvers();return e.close(e=>e?r(e):n()),t},Ze=({timeout:e=1e3,logger:t}={})=>{let n,r=new Set,i=new Set,a=e=>void i.delete(e),o=e=>a(e.destroy()),s=e=>void(Ke(e)?!e._httpMessage.headersSent&&e._httpMessage.setHeader(`connection`,`close`):o(e)),c=e=>void(n?e.destroy():i.add(e.once(`close`,()=>a(e)).once(`error`,()=>o(e)))),l=async()=>{for(let e of r)e.on(`request`,Ye);t?.info(`Graceful shutdown`,{sockets:i.size,timeout:e});for(let e of i)(Je(e)||qe(e))&&s(e);for await(let t of De(10,Date.now()))if(i.size===0||Date.now()-t>=e)break;for(let e of i)o(e);return Promise.allSettled(r.values().map(Xe))},u={sockets:i,add:(...e)=>{for(let t of e)if(!r.has(t)){r.add(t);for(let e of[`connection`,`secureConnection`])t.on(e,c)}return u},shutdown:()=>n??=l(),get isShuttingDown(){return!!n}};return u},q=Symbol.for(`express-zod-api`),Qe=({errorHandler:e,getLogger:t})=>async(n,r,i,a)=>n?e.execute({error:S(n),request:r,response:i,input:null,output:null,ctx:{},logger:t(r)}):a(),$e=({errorHandler:e,getLogger:t})=>async(n,r)=>{let i=E(404,`Can not ${n.method} ${n.path}`),a=t(n);await e.execute({request:n,response:r,logger:a,error:i,input:null,output:null,ctx:{}})},et=e=>(t,{},n)=>{if(Object.values(t?.files||[]).flat().find(({truncated:e})=>e))return n(e);n()},tt=({config:e})=>{let t=C(`cookie-parser`),{secret:n,...r}={...typeof e.cookies==`object`&&e.cookies};return t(n,Object.keys(r).length?r:void 0)},J=e=>typeof e==`function`?e:({},e,t)=>{e.set({"Access-Control-Allow-Origin":`*`,"Access-Control-Allow-Headers":`content-type`}),t()},nt=e=>({log:t=>{/not eligible/i.test(t)||e.debug(t)}}),rt=({getLogger:e,config:t})=>{let n=C(`express-fileupload`),{limitError:r,beforeUpload:i,...a}={...typeof t.upload==`object`&&t.upload},o=[];return o.push(async(t,r,o)=>{let s=e(t);return await i?.({request:t,logger:s}),n({debug:!0,...a,abortOnLimit:!1,parseNested:!0,logger:nt(s)})(t,r,o)}),r&&o.push(et(r)),o},it=(e,{},t)=>{Buffer.isBuffer(e.body)&&(e.body={raw:e.body}),t()},at=({logger:e,config:{childLoggerProvider:t,accessLogger:n=({method:e,path:t},n)=>n.debug(`${e}: ${t}`)}})=>async(r,i,a)=>{let o=await t?.({request:r,parent:e})||e;n?.(r,o),r.res&&(r.res.locals[q]={logger:o}),a()},ot=e=>t=>t?.res?.locals[q]?.logger||e;let Y=!1;const st=e=>{Y||(Y=!0,process.on(`deprecation`,({message:t,namespace:n,name:r,stack:i})=>e.warn(`${r} (${n}): ${t}`,i.split(`
|
|
2
2
|
`).slice(1))))};let X,Z,Q;const ct=({servers:e,logger:t,options:{timeout:n,beforeExit:r,events:i=[`SIGINT`,`SIGTERM`]}})=>{X??=Ze({logger:t,timeout:n}),X.add(...e),r&&(Q??=new Set).add(r),Z??=async()=>{X?.isShuttingDown||(await X?.shutdown(),Q&&await Promise.allSettled(Q.values().map(async e=>e())),process.exit())};for(let e of i)process.listeners(e).includes(Z)||process.on(e,Z)},lt=e=>{if(e.columns<62)return;let t=Se(`for Angie`.padStart(52)),n=D(`#F5A9B8`),r=D(`#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`,O`8888888888 888 888 88888P" 888 "Y8888 88888P' 88888P'`,O` 888`,O`8888888888P 888 888 d8888 8888888b. 8888888`,O` 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
|
-
`)},ut=e=>{e.startupLogo!==!1&<(process.stdout);let t=e.errorHandler||N,n=ze(e.logger)?e.logger:new W(e.logger);n.debug(`Running`,{build:`v29.
|
|
6
|
+
`)},ut=e=>{e.startupLogo!==!1&<(process.stdout);let t=e.errorHandler||N,n=ze(e.logger)?e.logger:new W(e.logger);n.debug(`Running`,{build:`v29.2.0`,env:process.env.NODE_ENV||`development`}),st(n);let r=at({logger:n,config:e}),i={getLogger:ot(n),errorHandler:t},a=$e(i),o=Qe(i);return{...i,logger:n,notFoundHandler:a,catcher:o,loggingMiddleware:r}},dt=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,loggingMiddleware:a}=ut(e),o=e.app.use(a);return e.cors&&o.use(J(e.cors)),K({app:o,routing:t,getLogger:r,config:e}),{notFoundHandler:i,logger:n}},ft=(e,t)=>{let{logger:n,getLogger:r,notFoundHandler:i,catcher:a,loggingMiddleware:o}=ut(e),s=A().disable(`x-powered-by`).set(`query parser`,e.queryParser??`simple`).use(o);if(e.beforeParsers?.({app:s,getLogger:r}),e.compression){let t=C(`compression`);s.use(t(typeof e.compression==`object`?e.compression:void 0))}return e.cookies&&s.use(tt({config:e})),e.cors&&s.use(J(e.cors)),s.use(e.jsonParser||A.json()).use(e.formParser||A.urlencoded()).use(e.rawParser||A.raw(),it),e.upload&&s.use(...rt({config:e,getLogger:r})),e.beforeRouting?.({app:s,getLogger:r}),K({app:s,routing:t,getLogger:r,config:e}),e.afterRouting?.({app:s,getLogger:r}),s.use(a,i),{app:s,logger:n}},pt=(e,t)=>{let{app:n,logger:r}=ft(e,t),i=[],a=(e,t)=>()=>e.listen(t,()=>r.info(`Listening`,t)),o=[];if(e.http){let t=Te.createServer(n);i.push(t),o.push(a(t,e.http.listen))}if(e.https){let t=Ee.createServer(e.https.options,n);i.push(t),o.push(a(t,e.https.listen))}return i.length||r.warn(`No servers configured.`),e.gracefulShutdown&&ct({logger:r,servers:i,options:e.gracefulShutdown===!0?{}:e.gracefulShutdown}),{app:n,logger:r,servers:o.map(e=>e())}},mt=e=>Oe({...e,headers:{"content-type":b.json,...e?.headers}}),ht=e=>ke(e),gt=e=>{let t={warn:[],error:[],info:[],debug:[]};return new Proxy(e||{},{get(e,n,r){return n===`_getLogs`?()=>t:Be(n)?(...e)=>t[n].push(e):Reflect.get(e,n,r)}})},_t=({requestProps:e,responseOptions:t,configProps:n,loggerProps:r})=>{let i=mt(e),a=ht({req:i,...t});a.req=t?.req||i,i.res=a;let o=gt(r);return{requestMock:i,responseMock:a,loggerMock:o,configMock:{cors:!1,logger:o,...n}}},vt=async({endpoint:e,...t})=>{let{requestMock:n,responseMock:r,loggerMock:i,configMock:a}=_t(t);return await e.execute({request:n,response:r,config:a,logger:i}),{requestMock:n,responseMock:r,loggerMock:i}},yt=async({middleware:t,ctx:n={},...r})=>{let{configMock:{inputSources:i,errorHandler:a=N},...o}=_t(r),s=e(o.requestMock,i),c={request:o.requestMock,response:o.responseMock,logger:o.loggerMock,input:s,ctx:n};try{let e=await t.execute(c);return{...o,output:e}}catch(e){return await a.execute({...c,error:S(e),output:null}),{...o,output:{}}}},$=(e,t)=>T.object({data:t,event:T.literal(e),id:T.string().optional(),retry:T.int().positive().optional()}),bt=(e,t,n)=>$(String(t),e[t]).transform(e=>[`event: ${e.event}`,`data: ${JSON.stringify(e.data)}`,``,``].join(`
|
|
7
7
|
`)).parse({event:t,data:n}),xt=e=>e.headersSent||e.writeHead(200,{connection:`keep-alive`,"content-type":b.sse,"cache-control":`no-cache`}),St=e=>new g({handler:async({request:t,response:n})=>{let r=new AbortController,i=setTimeout(()=>xt(n),1e4);return t.once(`close`,()=>{clearTimeout(i),r.abort()}),{isClosed:()=>n.writableEnded||n.closed,signal:r.signal,emit:(t,r)=>{xt(n),n.write(bt(e,t,r),`utf-8`),n.flush?.()}}}}),Ct=e=>new j({positive:()=>{let[t,...r]=Object.entries(e).map(([e,t])=>$(e,t));if(!t)throw new n(Error(`At least one SSE event is required.`));return{mimeType:b.sse,schema:r.length?T.discriminatedUnion(`event`,[t,...r]):t}},negative:{mimeType:`text/plain`,schema:T.string()},handler:async({response:e,error:t,logger:n,request:r,input:i})=>{if(t){let a=x(t);m(a,n,r,i),e.headersSent||e.status(a.statusCode).type(`text/plain`).write(p(a),`utf-8`)}e.end()}});var wt=class extends B{constructor(e){super(Ct(e)),this.middlewares=[St(e)]}};const Tt=[`total`,`limit`,`offset`],Et=[`nextCursor`,`limit`];function Dt({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`&&Tt.includes(n))throw Error(`ez.paginated: itemsName must not match reserved keys for offset output (${Tt.join(`, `)})`);if(e===`cursor`&&Et.includes(n))throw Error(`ez.paginated: itemsName must not match reserved keys for cursor output (${Et.join(`, `)})`);let a=T.coerce.number().int().min(1).max(r).default(i).describe(`Page size (number of ${n} per page)`);if(e===`offset`){let e=T.coerce.number().int().min(0).default(0).describe(`Number of ${n} to skip`);return{input:T.object({limit:a,offset:e}),output:T.object({[n]:T.array(t).describe(`Page of ${n}`),total:T.number().int().min(0).describe(`Total number of ${n}`),limit:T.number().int().min(1).describe(`Page size used`),offset:T.number().int().min(0).describe(`Offset used`)})}}let o=T.string().optional().describe(`Cursor for the next page; omit for first page`);return{input:T.object({cursor:o,limit:a}),output:T.object({[n]:T.array(t).describe(`Page of ${n}`),nextCursor:T.string().nullable().describe(`Cursor for the next page, or null if no more pages`),limit:T.number().int().min(1).describe(`Page size used`)})}}const Ot={dateIn:ie,dateOut:ae,form:ee,upload:ue,raw:de,buffer:c,paginated:Dt};export{W as BuiltinLogger,t as DocumentationError,B as EndpointsFactory,wt as EventStreamFactory,le as InputValidationError,g as Middleware,d as MissingPeerError,r as OutputValidationError,j as ResultHandler,l as RoutingError,te as ServeStatic,Re as arrayEndpointsFactory,F as arrayResultHandler,dt as attachRouting,se as createApiResponse,L as createCacheMiddleware,Ae as createConfig,R as createCookieMiddleware,z as createRateLimitMiddleware,pt as createServer,Le as defaultEndpointsFactory,N as defaultResultHandler,x as ensureHttpError,Ot as ez,a as getMessageFromError,vt as testEndpoint,yt as testMiddleware};
|
package/dist/integration.d.ts
CHANGED
package/dist/integration.js
CHANGED
|
@@ -10,4 +10,4 @@ import{$ as e,A as t,F as n,J as r,M as i,P as a,W as o,Z as s,_ as c,c as l,n a
|
|
|
10
10
|
`)});let g=l.reduce((t,r)=>{let a=n.getResponses(r),o=[];for(let[t,{schema:n,mimeTypes:c,statusCodes:l}]of a.entries()){let a=s(e,c),f=i(r,`variant`,`${t+1}`),p=$(a?n:d,y);this.#e.push(e=>`/** ${u} */\ntype ${f} = ${F(p,e)};`);for(let e of l)o.push(` ${e}: ${f};`)}let c=i(r,`response`,`variants`);return this.#e.push(`/** ${u} */\ninterface ${c} {\n${o.join(`
|
|
11
11
|
`)}\n}`),Object.assign(t,{[r]:c})},{});this.paths.add(t);let v={input:p,positive:this.someOf(g.positive),negative:this.someOf(g.negative),response:`${S.positive}["${u}"] | ${S.negative}["${u}"]`,encoded:`${g.positive} & ${g.negative}`};this.registry.set(u,{isDeprecated:a,store:v}),this.tags.set(u,c)};p({routing:e,config:t,onEndpoint:m?u(x):x}),this.#e.push(this.makeSomeOfType(),this.makePathType(),this.makeMethodType(),...this.makePublicInterfaces(),this.makeRequestType()),i!==`types`&&(this.#e.push(this.makeEndpointTags(),this.makeParseRequestFn(),this.makeSubstituteFn(),this.makeImplementationType(),this.makePaginationType(),this.makeDefaultContextType(),this.makeDefaultImplementation(h&&b),this.makeClientClass(a),this.makeSubscriptionClass(o,h&&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
|
-
`)}async printFormatted({printerOptions:e,format:t}={}){let n=t;if(!n)try{let e=g(`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};
|
|
13
|
+
`)}async printFormatted({printerOptions:e,format:t}={}){let n=t;if(!n){try{let e=g(`prettier`).format;n=t=>e(t,{filepath:`client.ts`})}catch{}try{let e=g(`oxfmt`).format;n=async t=>{let{code:n,errors:r}=await e(`client.ts`,t);if(r.length)throw Error(`OxFmt failed to format the code`,{cause:r});return n}}catch{}}this.#n&&n&&(this.#n=await n(this.#n));let r=this.print(e);return n?n(r):r}};export{ce as Integration};
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{A as e,C as t,F as n,G as r,J as i,L as a,M as o,P as s,Q as c,U as l,W as u,X as d,Z as f,b as p,q as m,r as h,tt as g,v as _}from"./routing-walker-DEXhtG7U.js";import{z as v}from"zod";import*as y from"ramda";import{isReferenceObject as b,isSchemaObject as x}from"openapi3-ts/oas32";const S=e=>e.type===`object`,C=y.mergeDeepWith((e,t)=>{if(Array.isArray(e)&&Array.isArray(t))return y.concat(e,t);if(e===t)return t;throw Error(`Can not flatten properties`,{cause:{a:e,b:t}})}),w=new Set([`type`,`properties`,`required`,`examples`,`description`,`additionalProperties`]),T=e=>{for(let t of Object.keys(e))if(!w.has(t))return!1;return!0},E=y.pair(!0),ee=(e,t,n)=>!(`allOf`in e)||!e.allOf?[]:e.allOf.map(e=>{if(t===`throw`&&!(e.type===`object`&&T(e)))throw Error(`Can not merge`);return y.pair(n,e)}),te=e=>{let t=[];return e.anyOf&&t.push(...y.map(E,e.anyOf)),e.oneOf&&t.push(...y.map(E,e.oneOf)),t},ne=(e,t,n,i)=>{if(!r(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)t.properties[e]??=o;i||n.push(...a)},re=(e,t,n)=>{t.examples?.length&&(n?e.examples=y.concat(e.examples||[],t.examples):e.examples=a(e.examples?.filter(r)||[],t.examples.filter(r),([e,t])=>y.mergeDeepRight(e,t)))},D=(e,t=`coerce`)=>{let n=[y.pair(!1,e)],r={type:`object`,properties:{}},i=[];for(let[e,a]of n)a.description&&(r.description??=a.description),n.push(...ee(a,t,e)),n.push(...te(a)),re(r,a,e),S(a)&&(n.push([e,{examples:O(a)}]),a.properties&&(r.properties=(t===`throw`?C:y.mergeDeepRight)(r.properties,a.properties),!e&&a.required&&i.push(...a.required)),ne(a,r,i,e));return i.length&&(r.required=[...new Set(i)]),r},O=e=>Object.entries(e.properties||{}).reduce((e,[t,n])=>{let{examples:i=[]}=r(n)?n:{};return a(e,i.map(y.objOf(t)),([e,t])=>({...e,...t}))},[]),k=`x-coerce`,A=(e,t)=>{if(e[`x-coerce`]===!0)return!0;if(e.anyOf)return e.anyOf.some(e=>A(e,t));if(e.oneOf)return e.oneOf.some(e=>A(e,t));if(e.allOf)return e.allOf.every(e=>A(e,t));if(e.type===void 0||e.type===`string`)return!0;if(t===`query`&&[`array`,`object`].includes(e.type)){let n=[e.items,e.prefixItems,e.additionalItems,Object.values(e.properties??{}),e.additionalProperties,e.propertyNames];for(let e of n){if(!r(e))continue;let n=Array.isArray(e)?e:[e];for(let e of n)if(r(e)&&!A(e,t))return!1}return!0}return!1};let j;const M=()=>j??=new Set(`a-im.accept.accept-additions.accept-charset.accept-datetime.accept-encoding.accept-features.accept-language.accept-signature.access-control.access-control-request-headers.access-control-request-method.alpn.alt-used.amp-cache-transform.apply-to-redirect-ref.authorization.available-dictionary.c-ext.c-man.c-opt.c-pep.c-pep-info.cache-control.cal-managed-id.caldav-timezones.capsule-protocol.cdn-loop.cert-not-after.cert-not-before.client-cert.client-cert-chain.close.cmcd-object.cmcd-request.cmcd-session.cmcd-status.cmsd-dynamic.cmsd-static.concealed-auth-export.configuration-context.connection.content-digest.content-disposition.content-encoding.content-id.content-language.content-length.content-location.content-md5.content-range.content-script-type.content-type.cookie.cookie2.cta-common-access-token.dasl.date.dav.default-style.delta-base.deprecation.depth.derived-from.destination.detached-jws.dictionary-id.differential-id.digest.dpop.early-data.ediint-features.expect.expect-ct.ext.forwarded.from.getprofile.hobareg.host.http2-settings.if.if-match.if-modified-since.if-none-match.if-range.if-schedule-tag-match.if-unmodified-since.im.include-referred-token-binding-id.incremental.isolation.keep-alive.label.last-event-id.link.link-template.lock-token.man.max-forwards.memento-datetime.meter.method-check.method-check-expires.mime-version.negotiate.odata-entityid.odata-isolation.odata-maxversion.odata-version.opt.ordering-type.origin.origin-agent-cluster.oscore.oslc-core-version.overwrite.pep.pep-info.permissions-policy.pics-label.ping-from.ping-to.position.pragma.prefer.preference-applied.priority.profileobject.protocol.protocol-info.protocol-query.protocol-request.proxy-authorization.proxy-features.proxy-instruction.range.redirect-ref.referer.referer-root.referrer-policy.repeatability-client-id.repeatability-first-sent.repeatability-request-id.repeatability-result.replay-nonce.reporting-endpoints.repr-digest.safe.schedule-reply.schedule-tag.sec-fetch-storage-access.sec-gpc.sec-purpose.sec-token-binding.sec-websocket-extensions.sec-websocket-key.sec-websocket-protocol.sec-websocket-version.security-scheme.signature.signature-input.slug.soapaction.status-uri.sunset.surrogate-capability.tcn.te.timeout.topic.traceparent.tracestate.trailer.transfer-encoding.ttl.upgrade.urgency.uri.user-agent.variant-vary.via.want-content-digest.want-digest.want-repr-digest.want-unencoded-digest.warning.x-content-type-options.x-frame-options`.split(`.`)),N={integer:0,number:0,string:``,boolean:!1,object:{},null:null,array:[]},P=e=>e.replace(d,e=>`{${e.slice(1)}}`),F=({},e)=>{if(e.isResponse)throw new t(`Please use ez.upload() only for input.`,e);return{type:`string`,format:`binary`}},I=({jsonSchema:e})=>({...e,externalDocs:{description:`raw binary data`,url:`https://swagger.io/specification/#working-with-binary-data`}}),L=({zodSchema:e,jsonSchema:t})=>{if(!m(e,`union`)||!(`discriminator`in e._zod.def))return t;let n=e._zod.def.discriminator;return{...t,discriminator:t.discriminator??{propertyName:n}}},R=y.tryCatch(({jsonSchema:e})=>{if(!e.allOf)throw`no allOf`;return D(e,`throw`)},(e,{jsonSchema:t})=>t),z=({jsonSchema:e})=>{if(!e.anyOf||!e.anyOf.length)return e;let t=e.anyOf[0];return Object.assign(t,{type:K(t.type)})},B=e=>e,V=({jsonSchema:e},n)=>{if(n.isResponse)throw new t(`Please use ez.dateOut() for output.`,n);return e},H=({jsonSchema:e},n)=>{if(!n.isResponse)throw new t(`Please use ez.dateIn() for input.`,n);return e},U=()=>({type:`string`,format:`bigint`,pattern:`^-?\\d+$`}),W=({zodSchema:e,jsonSchema:t})=>e._zod.def.rest===null?{...t,items:{not:{}}}:t,G=e=>{let t=Array.isArray(e.type)?e.type[0]:e.type;return N?.[t]},K=e=>e===`null`?e:typeof e==`string`?[e,`null`]:e&&[...new Set(e).add(`null`)],ie=({zodSchema:e,jsonSchema:t},n)=>{let r=e._zod.def[n.isResponse?`out`:`in`],i=e._zod.def[n.isResponse?`in`:`out`];if(!m(r,`transform`))return t;let a=B(Z(i,{ctx:n}));if(x(a))if(n.isResponse){let e=u(r,G(a));if(e&&[`number`,`string`,`boolean`].includes(e))return{...t,type:e}}else{let{type:e,...t}=a;return{...t,format:`${t.format||e} (preprocessed)`}}return t},q=({jsonSchema:e})=>{if(e.type!==`object`)return e;let t=e;return!t.properties||!(`raw`in t.properties)||!r(t.properties.raw)?e:t.properties.raw},J=e=>e.length?y.fromPairs(y.zip(y.times(e=>`example${e+1}`,e.length),y.map(y.objOf(`dataValue`),e))):void 0,Y=(e,t)=>t?.has(e)||e.startsWith(`x-`)||M().has(e),ae=({method:e,path:t,security:n,inputSources:r,isHeader:i})=>{let a=new Set(l(t)),o=r.includes(`query`),s=r.includes(`params`),c=r.includes(`headers`),u=r.includes(`cookies`)||r.includes(`signedCookies`),d;c&&n&&(d=h(n,`header`));let f;return u&&n&&(f=h(n,`cookie`)),{pathParams:a,getLocation:n=>{if(s&&a.has(n)&&a.delete(n))return`path`;if(u&&f?.has(n))return`cookie`;if(c&&(i?.(n,e,t)??Y(n,d)))return`header`;if(o&&e!==`query`)return`query`},isQueryEnabled:o}},oe=({path:e,method:t,flatRequest:n,makeRef:a,composition:o,getLocation:s,description:c=`${t.toUpperCase()} ${e} Parameter`})=>{let l=[];for(let[e,t]of Object.entries(n.properties)){if(!r(t))continue;let u=s(e);if(!u)continue;let d=B(t),f=o===`components`?a(t.id||JSON.stringify(t),d,t.id||i(c,e)):d;l.push({name:e,in:u,deprecated:t.deprecated,required:n.required?.includes(e)||u===`path`,description:d.description||c,schema:f,examples:J(x(d)&&d.examples?.length?d.examples:y.pluck(e,n.examples?.filter(y.both(r,y.has(e)))||[]))})}return l},X={nullable:z,union:L,bigint:U,intersection:R,tuple:W,pipe:ie,[o]:V,[e]:H,[p]:F,[_]:q,[s]:I},se=(e,t,n)=>{let r=[e,t],i=e=>/schema\d+$/.test(e)?void 0:e;for(let e=0;e<r.length;e++){let a=r[e];if(y.is(Object,a)){if(b(a)&&!a.$ref.startsWith(`#/components`)){let e=a.$ref.split(`/`).pop(),r=t[e];if(r){let t=r.id||i(e);a.$ref=n.makeRef(t||r,B(r),t).$ref}continue}r.push(...y.values(a))}y.is(Array,a)&&r.push(...y.values(a))}return e},Z=(e,{ctx:i,rules:a=X})=>{let{$defs:o={},properties:s={}}=v.toJSONSchema(v.object({subject:e}),{unrepresentable:`any`,io:i.isResponse?`output`:`input`,override:e=>{let r=v.globalRegistry.get(e.zodSchema)?.id;if(r){let n=i.seenIds.get(r);if(n&&n!==e.zodSchema)throw new t(`The meta id "${r}" is used by two different schemas. Please make the ids unique or reuse the same schema instance.`,i);i.seenIds.set(r,e.zodSchema)}let o=n(e.zodSchema),s=a[o&&o in a?o:e.zodSchema._zod.def.type];if(s){let t={...s(e,i)};for(let t in e.jsonSchema)delete e.jsonSchema[t];Object.assign(e.jsonSchema,t)}}});return se(r(s.subject)?s.subject:{},o,i)},Q=(e,t)=>{if(b(e))return[e,!1];let n=!1,r=y.map(e=>{let[r,i]=Q(e,t);return n||=i,r}),i=y.omit(t),a={properties:i,examples:y.map(i),required:y.without(t),allOf:r,oneOf:r,anyOf:r},o=y.evolve(a,e);return[o,n||!!o.required?.length]},ce=({method:e,path:t,schema:n,mimeTypes:r,variant:a,makeRef:o,composition:s,hasMultipleStatusCodes:l,statusCode:u,brandHandling:d,seenIds:p,description:m=`${e.toUpperCase()} ${t} ${c(a)} response ${l?u:``}`.trim()})=>{if(!f(e,r))return{description:m};let h=B(Z(n,{rules:{...d,...X},ctx:{isResponse:!0,makeRef:o,path:t,method:e,seenIds:p}})),_=[];x(h)&&h.examples&&(_.push(...h.examples),delete h.examples);let v=s===`components`?o(n,h,i(m)):h;return{description:m,content:y.fromPairs(r.map(e=>[e,{[e===g.sse?`itemSchema`:`schema`]:v,examples:J(_)}]))}},le=({format:e})=>{let t={type:`http`,scheme:`bearer`};return e&&(t.bearerFormat=e),t},ue=({name:e},t)=>{let n={type:`apiKey`,in:`query`,name:e};return t?.includes(`body`)&&(t?.includes(`query`)?(n[`x-in-alternative`]=`body`,n.description=`${e} CAN also be supplied within the request body`):(n[`x-in-actual`]=`body`,n.description=`${e} MUST be supplied within the request body instead of query`)),n},de=({name:e})=>({type:`apiKey`,in:`header`,name:e}),fe=({name:e})=>({type:`apiKey`,in:`cookie`,name:e}),pe=({url:e})=>({type:`openIdConnect`,openIdConnectUrl:e}),$=({flows:e={},oauth2MetadataUrl:t})=>({type:`oauth2`,flows:y.map(e=>({...e,scopes:e.scopes||{}}),y.reject(y.isNil,e)),oauth2MetadataUrl:t}),me=(e,t=[])=>{let n=e=>e.type===`basic`?{type:`http`,scheme:`basic`}:e.type===`bearer`?le(e):e.type===`input`?ue(e,t):e.type===`header`?de(e):e.type===`cookie`?fe(e):e.type===`openid`?pe(e):$(e);return e.map(e=>e.map(({deprecated:e,...t})=>({...n(t),deprecated:e})))},he=(e,t,n)=>e.map(e=>e.reduce((e,r)=>{let i=n(r),a=[`oauth2`,`openIdConnect`].includes(r.type);return Object.assign(e,{[i]:a?t:[]})},{})),ge=({schema:e,brandHandling:t,makeRef:n,path:r,method:i,seenIds:a})=>Z(e,{rules:{...t,...X},ctx:{isResponse:!1,makeRef:n,path:r,method:i,seenIds:a}}),_e=({method:e,path:t,schema:n,bodyJsonSchema:a,hasRequiredBodyProps:o,flatRequest:s,mimeType:c,makeRef:l,composition:u,paramNames:d,description:f=`${e.toUpperCase()} ${t} Request body`})=>{let p=B(a),m=[];x(p)&&p.examples&&(m.push(...p.examples),delete p.examples);let h={schema:u===`components`?l(n,p,i(f)):p,examples:J(m.length?m:s.examples?.filter(e=>r(e)&&!Array.isArray(e)).map(y.omit(d))||[])},_={description:f,content:{[c]:h}};return(o||c===g.raw)&&(_.required=!0),_},ve=e=>Object.entries(e).reduce((e,[t,n])=>{if(!n)return e;if(typeof n==`string`)return e.concat({name:t,description:n});let{url:r,...i}=n,a={...i,name:t};return r&&(a.externalDocs={...a.externalDocs,url:r}),e.concat(a)},[]),ye=(e,t=50)=>!e||e.length<=t?e:e.slice(0,Math.max(1,t||0)-1)+`…`,be=e=>e.length?e.slice():void 0;export{me as a,Q as c,P as d,ye as f,A as h,ce as i,ae as l,D as m,ge as n,he as o,k as p,oe as r,ve as s,_e as t,be as u};
|