@schemavaults/openapi-operations 0.2.0 → 0.3.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/README.md +29 -2
- package/dist/auth-scheme.d.ts +1 -1
- package/dist/auth-scheme.js +11 -7
- package/dist/auth-scheme.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/operation.d.ts +21 -2
- package/dist/operation.js.map +1 -1
- package/dist/runtime/create-operations-app-factory.d.ts +4 -2
- package/dist/runtime/create-operations-app-factory.js +1 -0
- package/dist/runtime/create-operations-app-factory.js.map +1 -1
- package/dist/runtime/create-operations-app.d.ts +20 -3
- package/dist/runtime/create-operations-app.js +31 -13
- package/dist/runtime/create-operations-app.js.map +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/resolve-auth.d.ts +7 -5
- package/dist/runtime/resolve-auth.js +5 -3
- package/dist/runtime/resolve-auth.js.map +1 -1
- package/dist/runtime/validate-request.js +16 -4
- package/dist/runtime/validate-request.js.map +1 -1
- package/dist/zod-openapi.d.ts +22 -1
- package/dist/zod-openapi.js +25 -1
- package/dist/zod-openapi.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -80,6 +80,27 @@ export const health = defineOperation({
|
|
|
80
80
|
`defineOperationGroup({ pathPrefix, tags, operations })` applies a shared prefix and tags.
|
|
81
81
|
Throw `new OperationError(status, { error, message })` from a handler to short-circuit.
|
|
82
82
|
|
|
83
|
+
Schemas built by OTHER packages (e.g. `@schemavaults/auth-common`) may have been constructed
|
|
84
|
+
before this package installed the `.openapi()` extension (zod v4 copies prototype methods onto
|
|
85
|
+
each instance at construction time), in which case `schema.openapi(...)` throws at module load
|
|
86
|
+
depending on import order. Use `withOpenApi(schema, refId?, metadata)` for them:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import { withOpenApi } from "@schemavaults/openapi-operations";
|
|
90
|
+
export const Organization = withOpenApi(organizationDefinitionSchema, "Organization", { description: "..." });
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Request bodies take two extra flags:
|
|
94
|
+
|
|
95
|
+
- `lenientContentType: true` also parses bodies labelled `text/plain` (or carrying no
|
|
96
|
+
`Content-Type` at all) as the declared media type. Browsers send
|
|
97
|
+
`text/plain;charset=UTF-8` for `fetch(url, { body: JSON.stringify(x) })` without an
|
|
98
|
+
explicit header, so JSON endpoints with such callers need it.
|
|
99
|
+
- `documentOnly: true` describes the body in the OpenAPI document but leaves the
|
|
100
|
+
request untouched: `ctx.body` is `undefined` and the handler reads `ctx.request`
|
|
101
|
+
itself. For endpoints whose parsing / error format is mandated by a protocol (the
|
|
102
|
+
OAuth 2.0 token endpoint's `{ error, error_description }`, ...).
|
|
103
|
+
|
|
83
104
|
### Auth schemes
|
|
84
105
|
|
|
85
106
|
An `AuthSchemeDefinition` is a named OpenAPI security scheme plus docs metadata. Built-ins:
|
|
@@ -118,10 +139,14 @@ import { createOperationsApp, toNextRouteHandlers } from "@schemavaults/openapi-
|
|
|
118
139
|
|
|
119
140
|
const app = createOperationsApp<{ dbh: Kysely<AuthDatabase> }, UserData>({
|
|
120
141
|
operations: [getApp, health],
|
|
142
|
+
// Built per request BEFORE credentials are resolved (keep it cheap, open
|
|
143
|
+
// expensive resources lazily); released by disposeContext afterwards.
|
|
121
144
|
context: async () => ({ dbh: await getDbh() }),
|
|
145
|
+
disposeContext: async ({ dbh }) => dbh.destroy(),
|
|
122
146
|
authResolvers: {
|
|
123
|
-
// keyed by scheme name; return null when no credential for that scheme is
|
|
124
|
-
|
|
147
|
+
// keyed by scheme name; return null when no credential for that scheme is
|
|
148
|
+
// present. The third argument is the per-request context.
|
|
149
|
+
"schemavaults-access-token": async (c, _scheme, { dbh }) => {
|
|
125
150
|
const token = c.req.header("authorization")?.replace(/^Bearer /, "");
|
|
126
151
|
if (!token) return null;
|
|
127
152
|
const user = await verifyAccessToken(token); // throw OperationError(401, ...) if invalid
|
|
@@ -137,6 +162,8 @@ const app = createOperationsApp<{ dbh: Kysely<AuthDatabase> }, UserData>({
|
|
|
137
162
|
// Served at GET /openapi.json. Pass a function to build it per request,
|
|
138
163
|
// e.g. to set `servers` from the incoming Host / X-Forwarded-* headers.
|
|
139
164
|
openapi: { document: openApiDocument },
|
|
165
|
+
// Unexpected failures: log / persist them before the generic 500 goes out.
|
|
166
|
+
onError: (error, c, { operation, context }) => reportException(error, operation.operationId),
|
|
140
167
|
});
|
|
141
168
|
|
|
142
169
|
// app/api/[[...route]]/route.ts
|
package/dist/auth-scheme.d.ts
CHANGED
|
@@ -83,7 +83,7 @@ export declare function publicAccess(notes?: string): PublicOperationAuth;
|
|
|
83
83
|
/** Marks an operation as requiring one of the given schemes (+ extra checks). */
|
|
84
84
|
export declare function requireAuth(requirements: AuthRequirements): RequiredOperationAuth;
|
|
85
85
|
export declare function isPublicOperationAuth(auth: OperationAuth): auth is PublicOperationAuth;
|
|
86
|
-
/** `Authorization: Bearer <access token>` issued by the
|
|
86
|
+
/** `Authorization: Bearer <access token>` issued by the auth server. */
|
|
87
87
|
export declare const schemaVaultsAccessTokenBearerScheme: AuthSchemeDefinition<"schemavaults-access-token">;
|
|
88
88
|
/**
|
|
89
89
|
* The first-party access-token cookie set by the auth server / resource
|
package/dist/auth-scheme.js
CHANGED
|
@@ -40,16 +40,20 @@ export function isPublicOperationAuth(auth) {
|
|
|
40
40
|
// ---------------------------------------------------------------------------
|
|
41
41
|
// Built-in SchemaVaults schemes
|
|
42
42
|
// ---------------------------------------------------------------------------
|
|
43
|
-
|
|
43
|
+
// The auth server may be any deployment of @schemavaults/auth-server,
|
|
44
|
+
// including white-label ones, so the docs copy never names SchemaVaults as
|
|
45
|
+
// the issuer. The scheme names (and challenge realms) are protocol
|
|
46
|
+
// identifiers and stay as they are.
|
|
47
|
+
/** `Authorization: Bearer <access token>` issued by the auth server. */
|
|
44
48
|
export const schemaVaultsAccessTokenBearerScheme = defineAuthScheme({
|
|
45
49
|
name: "schemavaults-access-token",
|
|
46
|
-
title: "
|
|
47
|
-
description: "An access token issued by the
|
|
50
|
+
title: "Access token (Bearer)",
|
|
51
|
+
description: "An access token issued by the auth server for this API server, sent as `Authorization: Bearer <token>`.",
|
|
48
52
|
securityScheme: {
|
|
49
53
|
type: "http",
|
|
50
54
|
scheme: "bearer",
|
|
51
55
|
bearerFormat: "JWT",
|
|
52
|
-
description: "Access token issued by the
|
|
56
|
+
description: "Access token issued by the auth server for this API server.",
|
|
53
57
|
},
|
|
54
58
|
challenge: 'Bearer realm="schemavaults"',
|
|
55
59
|
});
|
|
@@ -61,13 +65,13 @@ export const schemaVaultsAccessTokenBearerScheme = defineAuthScheme({
|
|
|
61
65
|
export function schemaVaultsAccessTokenCookieScheme(cookieName) {
|
|
62
66
|
return defineAuthScheme({
|
|
63
67
|
name: "schemavaults-access-token-cookie",
|
|
64
|
-
title: "
|
|
68
|
+
title: "Access token (cookie)",
|
|
65
69
|
description: `The first-party HTTP-only access token cookie \`${cookieName}\` set after login.`,
|
|
66
70
|
securityScheme: {
|
|
67
71
|
type: "apiKey",
|
|
68
72
|
in: "cookie",
|
|
69
73
|
name: cookieName,
|
|
70
|
-
description: "First-party access token cookie set
|
|
74
|
+
description: "First-party access token cookie set after login.",
|
|
71
75
|
},
|
|
72
76
|
});
|
|
73
77
|
}
|
|
@@ -75,7 +79,7 @@ export function schemaVaultsAccessTokenCookieScheme(cookieName) {
|
|
|
75
79
|
export function schemaVaultsRefreshTokenCookieScheme(cookieName) {
|
|
76
80
|
return defineAuthScheme({
|
|
77
81
|
name: "schemavaults-refresh-token-cookie",
|
|
78
|
-
title: "
|
|
82
|
+
title: "Auth server session (refresh token cookie)",
|
|
79
83
|
description: `The auth server's HTTP-only refresh token cookie \`${cookieName}\`; only the auth server itself can resolve it.`,
|
|
80
84
|
securityScheme: {
|
|
81
85
|
type: "apiKey",
|
package/dist/auth-scheme.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-scheme.js","sourceRoot":"","sources":["../src/auth-scheme.ts"],"names":[],"mappings":"AA8BA,MAAM,UAAU,gBAAgB,CAC9B,UAAuC;IAEvC,IAAI,OAAO,UAAU,CAAC,IAAI,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxE,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,SAAS,CACjB,qBAAqB,UAAU,CAAC,IAAI,wEAAwE,CAC7G,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,eAAe,EAAE,OAAO,CAAU,CAAC;AAqDrE,0DAA0D;AAC1D,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AAC9E,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,WAAW,CAAC,YAA8B;IACxD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,YAAY,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9E,MAAM,IAAI,SAAS,CACjB,sFAAsF,CACvF,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,MAAM,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;QAC1C,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,SAAS,CAAC,gBAAgB,MAAM,CAAC,IAAI,gBAAgB,CAAC,CAAC;QACnE,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IACD,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,GAAG,YAAY;QACf,UAAU,EAAE,YAAY,CAAC,UAAU,IAAI,eAAe;KACvD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAmB;IACvD,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC;AAChC,CAAC;AAED,8EAA8E;AAC9E,gCAAgC;AAChC,8EAA8E;
|
|
1
|
+
{"version":3,"file":"auth-scheme.js","sourceRoot":"","sources":["../src/auth-scheme.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { z } from "./zod-openapi";
|
|
2
|
-
export type { ZodType, ZodObject } from "./zod-openapi";
|
|
1
|
+
export { z, withOpenApi } from "./zod-openapi";
|
|
2
|
+
export type { ZodType, ZodObject, OpenApiSchemaMetadata } from "./zod-openapi";
|
|
3
3
|
export { HTTP_METHODS, HTTP_METHODS_WITH_REQUEST_BODY, isHttpMethod } from "./http-method";
|
|
4
4
|
export type { HttpMethod } from "./http-method";
|
|
5
5
|
export { defineAuthScheme, publicAccess, requireAuth, isPublicOperationAuth, ROUTE_GUARD_TYPES, schemaVaultsAccessTokenBearerScheme, schemaVaultsAccessTokenCookieScheme, schemaVaultsRefreshTokenCookieScheme, oidcClientSecretBasicScheme, oidcClientSecretPostScheme, apiKeyHeaderScheme, } from "./auth-scheme";
|
|
@@ -8,6 +8,7 @@ export { defineOperation, createOperationDefiner, defineOperationGroup, defaultO
|
|
|
8
8
|
export type { AnyOperationDefinition, AuthPrincipal, EmptyResponseStatusOf, InferBody, InferParsed, OperationDefiner, OperationDefinition, OperationGroup, OperationHandlerContext, OperationHandlerResult, OperationInput, OperationRequestDefinition, RequestBodyContentType, RequestBodyDefinition, ResponseBodyOf, ResponseDefinition, ResponseStatusOf, ResponsesDefinition, } from "./operation";
|
|
9
9
|
export { buildOpenApiDocument, collectAuthSchemes, toRouteConfig, toSecuritySchemeComponent, } from "./openapi/build-openapi-document";
|
|
10
10
|
export type { BuildOpenApiDocumentOptions } from "./openapi/build-openapi-document";
|
|
11
|
+
export type { OpenAPIObject } from "openapi3-ts/oas31";
|
|
11
12
|
export { SCHEMAVAULTS_AUTH_EXTENSION, SCHEMAVAULTS_SCHEME_TITLE_EXTENSION, SCHEMAVAULTS_SCHEME_CHALLENGE_EXTENSION, toSchemaVaultsAuthExtension, isSchemaVaultsAuthExtension, } from "./openapi/extensions";
|
|
12
13
|
export type { SchemaVaultsAuthExtension } from "./openapi/extensions";
|
|
13
14
|
export { extractPathParameterNames, openApiPathToHonoPath, honoPathToOpenApiPath, isOpenApiPath, } from "./openapi/path-format";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { z } from "./zod-openapi";
|
|
1
|
+
export { z, withOpenApi } from "./zod-openapi";
|
|
2
2
|
export { HTTP_METHODS, HTTP_METHODS_WITH_REQUEST_BODY, isHttpMethod } from "./http-method";
|
|
3
3
|
export { defineAuthScheme, publicAccess, requireAuth, isPublicOperationAuth, ROUTE_GUARD_TYPES, schemaVaultsAccessTokenBearerScheme, schemaVaultsAccessTokenCookieScheme, schemaVaultsRefreshTokenCookieScheme, oidcClientSecretBasicScheme, oidcClientSecretPostScheme, apiKeyHeaderScheme, } from "./auth-scheme";
|
|
4
4
|
export { defineOperation, createOperationDefiner, defineOperationGroup, defaultOperationId, assertUniqueOperations, operationHttpMethods, } from "./operation";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG/C,OAAO,EAAE,YAAY,EAAE,8BAA8B,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG3F,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,iBAAiB,EACjB,mCAAmC,EACnC,mCAAmC,EACnC,oCAAoC,EACpC,2BAA2B,EAC3B,0BAA0B,EAC1B,kBAAkB,GACnB,MAAM,eAAe,CAAC;AAWvB,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAsBrB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,EACb,yBAAyB,GAC1B,MAAM,kCAAkC,CAAC;AAI1C,OAAO,EACL,2BAA2B,EAC3B,mCAAmC,EACnC,uCAAuC,EACvC,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,qBAAqB,EACrB,aAAa,GACd,MAAM,uBAAuB,CAAC;AAE/B,cAAc,WAAW,CAAC;AAI1B,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/operation.d.ts
CHANGED
|
@@ -3,13 +3,30 @@ import type { OrganizationMembershipRoleType } from "@schemavaults/auth-common/o
|
|
|
3
3
|
import { type HttpMethod } from "./http-method";
|
|
4
4
|
import type { OperationAuth, PublicOperationAuth } from "./auth-scheme";
|
|
5
5
|
export type RequestBodyContentType = "application/json" | "application/x-www-form-urlencoded" | "multipart/form-data" | "text/plain" | (string & {});
|
|
6
|
-
export interface RequestBodyDefinition<TSchema extends ZodType = ZodType> {
|
|
6
|
+
export interface RequestBodyDefinition<TSchema extends ZodType = ZodType, TDocumentOnly extends boolean = boolean> {
|
|
7
7
|
/** Media type the body is parsed as (default `application/json`). */
|
|
8
8
|
readonly contentType?: RequestBodyContentType;
|
|
9
9
|
readonly schema: TSchema;
|
|
10
10
|
readonly description?: string;
|
|
11
11
|
/** Default true. */
|
|
12
12
|
readonly required?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Also parse the body as `contentType` when the request labels it
|
|
15
|
+
* `text/plain` or carries no Content-Type header at all. Browsers send
|
|
16
|
+
* `text/plain;charset=UTF-8` for `fetch(url, { body: JSON.stringify(x) })`
|
|
17
|
+
* without an explicit header, so JSON APIs with such callers need this.
|
|
18
|
+
* Default false (415 on a media type mismatch).
|
|
19
|
+
*/
|
|
20
|
+
readonly lenientContentType?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Describe the body in the OpenAPI document but leave the request
|
|
23
|
+
* untouched: the runtime neither reads nor validates it and `ctx.body`
|
|
24
|
+
* is `undefined`, so the handler reads `ctx.request` itself. For
|
|
25
|
+
* endpoints whose error format is mandated by a protocol (the OAuth 2.0
|
|
26
|
+
* token endpoint's `{ error, error_description }`, ...) and endpoints
|
|
27
|
+
* with bespoke parsing that must keep its exact responses.
|
|
28
|
+
*/
|
|
29
|
+
readonly documentOnly?: TDocumentOnly;
|
|
13
30
|
}
|
|
14
31
|
export interface ResponseDefinition<TSchema extends ZodType | undefined = ZodType | undefined> {
|
|
15
32
|
readonly description: string;
|
|
@@ -31,7 +48,9 @@ export interface OperationRequestDefinition<TParams extends ZodObject | undefine
|
|
|
31
48
|
readonly body?: TBody;
|
|
32
49
|
}
|
|
33
50
|
export type InferParsed<T> = T extends ZodType ? z.output<T> : Readonly<Record<string, never>>;
|
|
34
|
-
export type InferBody<T> = T extends
|
|
51
|
+
export type InferBody<T> = T extends {
|
|
52
|
+
readonly documentOnly: true;
|
|
53
|
+
} ? undefined : T extends RequestBodyDefinition<infer S> ? S extends ZodType ? z.output<S> : undefined : undefined;
|
|
35
54
|
export type ResponseStatusOf<TResponses extends ResponsesDefinition> = Extract<keyof TResponses, number>;
|
|
36
55
|
export type ResponseBodyOf<TResponses extends ResponsesDefinition, S extends keyof TResponses> = TResponses[S] extends {
|
|
37
56
|
readonly schema: infer TSchema;
|
package/dist/operation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operation.js","sourceRoot":"","sources":["../src/operation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,8BAA8B,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE9F,OAAO,EAAE,yBAAyB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"operation.js","sourceRoot":"","sources":["../src/operation.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,9 +10,11 @@ export interface CreateOperationsAppFactoryOptions<TContext = unknown, TUser = u
|
|
|
10
10
|
*/
|
|
11
11
|
readonly operations: readonly AnyOperationDefinition[];
|
|
12
12
|
/** Credential resolvers keyed by auth scheme name, shared by every app. */
|
|
13
|
-
readonly authResolvers?: AuthResolvers<TUser>;
|
|
13
|
+
readonly authResolvers?: AuthResolvers<TUser, TContext>;
|
|
14
14
|
/** Builds the per-request context handed to handlers as `ctx.context`. */
|
|
15
15
|
readonly context?: CreateOperationsAppOptions<TContext, TUser>["context"];
|
|
16
|
+
/** Releases the per-request context once the response was produced. */
|
|
17
|
+
readonly disposeContext?: CreateOperationsAppOptions<TContext, TUser>["disposeContext"];
|
|
16
18
|
/** Called for unexpected (non-OperationError) failures before the 500 is sent. */
|
|
17
19
|
readonly onError?: CreateOperationsAppOptions<TContext, TUser>["onError"];
|
|
18
20
|
}
|
|
@@ -22,7 +24,7 @@ export interface OperationsAppFactory<TContext = unknown, TUser = unknown> {
|
|
|
22
24
|
/** The full catalogue the factory was created with. */
|
|
23
25
|
readonly operations: readonly AnyOperationDefinition[];
|
|
24
26
|
/** The shared resolvers every app built by the factory authenticates with. */
|
|
25
|
-
readonly authResolvers: AuthResolvers<TUser>;
|
|
27
|
+
readonly authResolvers: AuthResolvers<TUser, TContext>;
|
|
26
28
|
/**
|
|
27
29
|
* Builds a Hono app serving the given operations (default: the whole
|
|
28
30
|
* catalogue) with the shared resolvers / context / error reporting.
|
|
@@ -50,6 +50,7 @@ export function createOperationsAppFactory(options) {
|
|
|
50
50
|
operations,
|
|
51
51
|
authResolvers: resolvers,
|
|
52
52
|
context: options.context,
|
|
53
|
+
disposeContext: options.disposeContext,
|
|
53
54
|
onError: options.onError,
|
|
54
55
|
basePath: appOptions.basePath,
|
|
55
56
|
configure: appOptions.configure,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-operations-app-factory.js","sourceRoot":"","sources":["../../src/runtime/create-operations-app-factory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EACL,mBAAmB,GAGpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,4BAA4B,EAAsB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"create-operations-app-factory.js","sourceRoot":"","sources":["../../src/runtime/create-operations-app-factory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EACL,mBAAmB,GAGpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,4BAA4B,EAAsB,MAAM,gBAAgB,CAAC;AAgDlF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,0BAA0B,CACxC,OAA2D;IAE3D,MAAM,SAAS,GAAsC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IAC5F,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAClC,MAAM,SAAS,GAAmC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;IAC9E,4BAA4B,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAyB,SAAS,CAAC,CAAC;IAE9D,MAAM,gBAAgB,GAAG,CAAC,UAA6C,EAAQ,EAAE;QAC/E,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,SAAS,CACjB,GAAG,SAAS,CAAC,MAAM,CAAC,WAAW,EAAE,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,WAAW,0IAA0I,CACxN,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,GAAG,GAAiD,CACxD,UAAU,GAAG,SAAS,EACtB,UAAU,GAAG,EAAE,EACf,EAAE;QACF,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAC7B,OAAO,mBAAmB,CAAkB;YAC1C,UAAU;YACV,aAAa,EAAE,SAAS;YACxB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,SAAS,EAAE,UAAU,CAAC,SAAS;YAC/B,OAAO,EAAE,UAAU,CAAC,OAAO;SAC5B,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO;QACL,UAAU,EAAE,SAAS;QACrB,aAAa,EAAE,SAAS;QACxB,GAAG;QACH,kBAAkB,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,UAAU,EAAE,OAAO,EAAE,CAAC;QACrF,gBAAgB;KACjB,CAAC;AACJ,CAAC"}
|
|
@@ -12,6 +12,12 @@ export interface OpenApiDocumentRouteOptions {
|
|
|
12
12
|
*/
|
|
13
13
|
readonly document: OpenAPIObject | ((c: Context) => OpenAPIObject | Promise<OpenAPIObject>);
|
|
14
14
|
}
|
|
15
|
+
/** What `onError` learns about the failed request besides the error itself. */
|
|
16
|
+
export interface OperationFailureInfo<TContext = unknown> {
|
|
17
|
+
readonly operation: AnyOperationDefinition;
|
|
18
|
+
/** The per-request context, when it had been built before the failure. */
|
|
19
|
+
readonly context: TContext | undefined;
|
|
20
|
+
}
|
|
15
21
|
export interface CreateOperationsAppOptions<TContext = unknown, TUser = unknown> {
|
|
16
22
|
readonly operations: readonly AnyOperationDefinition[];
|
|
17
23
|
/**
|
|
@@ -23,13 +29,24 @@ export interface CreateOperationsAppOptions<TContext = unknown, TUser = unknown>
|
|
|
23
29
|
*/
|
|
24
30
|
readonly basePath?: string;
|
|
25
31
|
/** Credential resolvers keyed by auth scheme name. */
|
|
26
|
-
readonly authResolvers?: AuthResolvers<TUser>;
|
|
27
|
-
/**
|
|
32
|
+
readonly authResolvers?: AuthResolvers<TUser, TContext>;
|
|
33
|
+
/**
|
|
34
|
+
* Builds the per-request context handed to auth resolvers and to handlers
|
|
35
|
+
* as `ctx.context`. Built before credentials are resolved, so it should
|
|
36
|
+
* be cheap (open expensive resources lazily) and is released through
|
|
37
|
+
* `disposeContext` once the response has been produced.
|
|
38
|
+
*/
|
|
28
39
|
readonly context?: (c: Context) => Promise<TContext> | TContext;
|
|
40
|
+
/**
|
|
41
|
+
* Releases the per-request context (database handles, cache connections)
|
|
42
|
+
* after the handler returned or failed. Errors thrown here are reported
|
|
43
|
+
* to `onError` (or the console) and never change the response.
|
|
44
|
+
*/
|
|
45
|
+
readonly disposeContext?: (context: TContext, c: Context) => void | Promise<void>;
|
|
29
46
|
/** Serve the OpenAPI document from the app; omit to not expose it. */
|
|
30
47
|
readonly openapi?: OpenApiDocumentRouteOptions;
|
|
31
48
|
/** Called for unexpected (non-OperationError) failures before the 500 is sent. */
|
|
32
|
-
readonly onError?: (error: unknown, c: Context) => void | Promise<void>;
|
|
49
|
+
readonly onError?: (error: unknown, c: Context, info: OperationFailureInfo<TContext>) => void | Promise<void>;
|
|
33
50
|
/** Extra middleware / routes registered before the operations (CORS, logging, ...). */
|
|
34
51
|
readonly configure?: (app: Hono) => void;
|
|
35
52
|
}
|
|
@@ -52,11 +52,29 @@ export function createOperationsApp(options) {
|
|
|
52
52
|
return c.json(resolved);
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
|
+
const report = async (error, c, info) => {
|
|
56
|
+
if (options.onError) {
|
|
57
|
+
try {
|
|
58
|
+
await options.onError(error, c, info);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// never let error reporting mask the response
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
console.error(`[openapi-operations] ${info.operation.method.toUpperCase()} ${info.operation.path} failed:`, error);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
55
68
|
for (const operation of options.operations) {
|
|
56
69
|
app.on(operation.method.toUpperCase(), openApiPathToHonoPath(operation.path), async (c) => {
|
|
70
|
+
let context = undefined;
|
|
71
|
+
let built = false;
|
|
57
72
|
try {
|
|
58
|
-
|
|
59
|
-
|
|
73
|
+
if (options.context) {
|
|
74
|
+
context = await options.context(c);
|
|
75
|
+
built = true;
|
|
76
|
+
}
|
|
77
|
+
const auth = await resolveAuth(c, operation.auth, resolvers, context);
|
|
60
78
|
const validated = await validateRequest(c, operation);
|
|
61
79
|
const ctx = buildHandlerContext(c, operation, validated, auth, context);
|
|
62
80
|
const result = await operation.handler(ctx);
|
|
@@ -68,23 +86,23 @@ export function createOperationsApp(options) {
|
|
|
68
86
|
catch (error) {
|
|
69
87
|
if (error instanceof OperationError)
|
|
70
88
|
return error.toResponse();
|
|
71
|
-
|
|
72
|
-
try {
|
|
73
|
-
await options.onError(error, c);
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
// never let error reporting mask the response
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
console.error(`[openapi-operations] ${operation.method.toUpperCase()} ${operation.path} failed:`, error);
|
|
81
|
-
}
|
|
89
|
+
await report(error, c, { operation, context });
|
|
82
90
|
return jsonResponse(500, {
|
|
83
91
|
success: false,
|
|
84
92
|
error: OPERATION_ERROR_CODES.internal,
|
|
85
93
|
message: "Internal Server Error",
|
|
86
94
|
});
|
|
87
95
|
}
|
|
96
|
+
finally {
|
|
97
|
+
if (built && options.disposeContext) {
|
|
98
|
+
try {
|
|
99
|
+
await options.disposeContext(context, c);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
await report(error, c, { operation, context });
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
88
106
|
});
|
|
89
107
|
}
|
|
90
108
|
return root;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-operations-app.js","sourceRoot":"","sources":["../../src/runtime/create-operations-app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAG1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAsB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"create-operations-app.js","sourceRoot":"","sources":["../../src/runtime/create-operations-app.ts"],"names":[],"mappings":"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"}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createOperationsApp } from "./create-operations-app";
|
|
2
|
-
export type { CreateOperationsAppOptions, OpenApiDocumentRouteOptions, } from "./create-operations-app";
|
|
2
|
+
export type { CreateOperationsAppOptions, OpenApiDocumentRouteOptions, OperationFailureInfo, } from "./create-operations-app";
|
|
3
3
|
export { createOperationsAppFactory } from "./create-operations-app-factory";
|
|
4
4
|
export type { CreateOperationsAppFactoryOptions, OperationsAppFactory, OperationsAppFactoryAppOptions, } from "./create-operations-app-factory";
|
|
5
5
|
export { OperationError, OPERATION_ERROR_CODES, jsonResponse } from "./errors";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAM9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAM7E,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE/E,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE3E,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -5,11 +5,13 @@ import type { AnyOperationDefinition, AuthPrincipal } from "../operation";
|
|
|
5
5
|
* Verifies the credential transported by one auth scheme. Returns null when
|
|
6
6
|
* the request carries no credential for the scheme (so the next accepted
|
|
7
7
|
* scheme is tried); throws {@link OperationError} to reject outright (e.g.
|
|
8
|
-
* a credential that IS present but invalid).
|
|
8
|
+
* a credential that IS present but invalid). Receives the per-request
|
|
9
|
+
* context built by `createOperationsApp({ context })` so it can share the
|
|
10
|
+
* request's database handle / caches with the handler.
|
|
9
11
|
*/
|
|
10
|
-
export type AuthResolver<TUser = unknown> = (c: Context, scheme: AuthSchemeDefinition) => Promise<AuthPrincipal<TUser> | null> | AuthPrincipal<TUser> | null;
|
|
11
|
-
export type AuthResolvers<TUser = unknown> = Readonly<Record<string, AuthResolver<TUser>>>;
|
|
12
|
-
export declare function assertResolversForOperations(operations: readonly AnyOperationDefinition[], resolvers: AuthResolvers): void;
|
|
12
|
+
export type AuthResolver<TUser = unknown, TContext = unknown> = (c: Context, scheme: AuthSchemeDefinition, context: TContext) => Promise<AuthPrincipal<TUser> | null> | AuthPrincipal<TUser> | null;
|
|
13
|
+
export type AuthResolvers<TUser = unknown, TContext = unknown> = Readonly<Record<string, AuthResolver<TUser, TContext>>>;
|
|
14
|
+
export declare function assertResolversForOperations(operations: readonly AnyOperationDefinition[], resolvers: AuthResolvers<any, any>): void;
|
|
13
15
|
export declare function grantedScopes(principal: AuthPrincipal): string[];
|
|
14
16
|
export declare function missingScopes(principal: AuthPrincipal, required: readonly string[]): string[];
|
|
15
17
|
/**
|
|
@@ -18,4 +20,4 @@ export declare function missingScopes(principal: AuthPrincipal, required: readon
|
|
|
18
20
|
* required scopes, and organization membership. Returns the principal, or
|
|
19
21
|
* null for public operations.
|
|
20
22
|
*/
|
|
21
|
-
export declare function resolveAuth<TUser>(c: Context, auth: OperationAuth, resolvers: AuthResolvers<TUser
|
|
23
|
+
export declare function resolveAuth<TUser, TContext = unknown>(c: Context, auth: OperationAuth, resolvers: AuthResolvers<TUser, TContext>, context?: TContext): Promise<AuthPrincipal<TUser> | null>;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { OPERATION_ERROR_CODES, OperationError } from "./errors";
|
|
2
|
-
export function assertResolversForOperations(operations,
|
|
2
|
+
export function assertResolversForOperations(operations,
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
resolvers) {
|
|
3
5
|
for (const operation of operations) {
|
|
4
6
|
if (operation.auth.type !== "required")
|
|
5
7
|
continue;
|
|
@@ -31,7 +33,7 @@ export function missingScopes(principal, required) {
|
|
|
31
33
|
* required scopes, and organization membership. Returns the principal, or
|
|
32
34
|
* null for public operations.
|
|
33
35
|
*/
|
|
34
|
-
export async function resolveAuth(c, auth, resolvers) {
|
|
36
|
+
export async function resolveAuth(c, auth, resolvers, context = undefined) {
|
|
35
37
|
if (auth.type === "public")
|
|
36
38
|
return null;
|
|
37
39
|
let principal = null;
|
|
@@ -39,7 +41,7 @@ export async function resolveAuth(c, auth, resolvers) {
|
|
|
39
41
|
const resolver = resolvers[scheme.name];
|
|
40
42
|
if (!resolver)
|
|
41
43
|
continue;
|
|
42
|
-
principal = await resolver(c, scheme);
|
|
44
|
+
principal = await resolver(c, scheme, context);
|
|
43
45
|
if (principal)
|
|
44
46
|
break;
|
|
45
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-auth.js","sourceRoot":"","sources":["../../src/runtime/resolve-auth.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve-auth.js","sourceRoot":"","sources":["../../src/runtime/resolve-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,6 +50,10 @@ export async function readRequestBody(c, definition) {
|
|
|
50
50
|
const actual = mediaTypeOf(c);
|
|
51
51
|
const contentLength = c.req.header("content-length");
|
|
52
52
|
const looksEmpty = actual === null && (contentLength === undefined || contentLength === "0");
|
|
53
|
+
const lenient = definition.lenientContentType === true;
|
|
54
|
+
// A body labelled text/plain (or not labelled at all) is re-parsed as the
|
|
55
|
+
// expected media type when the operation opted into leniency.
|
|
56
|
+
const relabelled = lenient && (actual === null || actual === "text/plain");
|
|
53
57
|
if (looksEmpty) {
|
|
54
58
|
if (!required)
|
|
55
59
|
return undefined;
|
|
@@ -61,7 +65,9 @@ export async function readRequestBody(c, definition) {
|
|
|
61
65
|
],
|
|
62
66
|
});
|
|
63
67
|
}
|
|
64
|
-
if (actual !== expected &&
|
|
68
|
+
if (actual !== expected &&
|
|
69
|
+
!relabelled &&
|
|
70
|
+
!(expected === "text/plain" && actual?.startsWith("text/"))) {
|
|
65
71
|
throw new OperationError(415, {
|
|
66
72
|
error: OPERATION_ERROR_CODES.unsupportedMediaType,
|
|
67
73
|
message: `Expected a ${expected} request body but received ${actual ?? "none"}`,
|
|
@@ -70,15 +76,21 @@ export async function readRequestBody(c, definition) {
|
|
|
70
76
|
try {
|
|
71
77
|
switch (expected) {
|
|
72
78
|
case "application/json":
|
|
73
|
-
|
|
79
|
+
// c.req.json() trusts the declared media type; parse the raw text
|
|
80
|
+
// ourselves so relabelled text/plain bodies work too.
|
|
81
|
+
return JSON.parse(await c.req.text());
|
|
74
82
|
case "application/x-www-form-urlencoded":
|
|
83
|
+
if (relabelled) {
|
|
84
|
+
return Object.fromEntries(new URLSearchParams(await c.req.text()));
|
|
85
|
+
}
|
|
86
|
+
return await c.req.parseBody({ all: true });
|
|
75
87
|
case "multipart/form-data":
|
|
76
88
|
return await c.req.parseBody({ all: true });
|
|
77
89
|
case "text/plain":
|
|
78
90
|
return await c.req.text();
|
|
79
91
|
default:
|
|
80
92
|
if (expected.endsWith("+json"))
|
|
81
|
-
return await c.req.
|
|
93
|
+
return JSON.parse(await c.req.text());
|
|
82
94
|
return await c.req.text();
|
|
83
95
|
}
|
|
84
96
|
}
|
|
@@ -110,7 +122,7 @@ export async function validateRequest(c, operation) {
|
|
|
110
122
|
? (await parseWith(headers, headersToObject(c), "headers"))
|
|
111
123
|
: EMPTY;
|
|
112
124
|
let parsedBody = undefined;
|
|
113
|
-
if (body) {
|
|
125
|
+
if (body && body.documentOnly !== true) {
|
|
114
126
|
const raw = await readRequestBody(c, body);
|
|
115
127
|
if (raw !== undefined || (body.required ?? true)) {
|
|
116
128
|
parsedBody = await parseWith(body.schema, raw, "body");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-request.js","sourceRoot":"","sources":["../../src/runtime/validate-request.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"validate-request.js","sourceRoot":"","sources":["../../src/runtime/validate-request.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,qBAAqB,EACrB,cAAc,GAEf,MAAM,UAAU,CAAC;AAElB,KAAK,UAAU,SAAS,CACtB,MAAe,EACf,KAAc,EACd,QAA8C;IAE9C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAClD,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC,IAAI,CAAC;IACvC,MAAM,MAAM,GAA+B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC7E,QAAQ;QACR,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAC5D,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC,CAAC,CAAC;IACJ,MAAM,IAAI,cAAc,CAAC,GAAG,EAAE;QAC5B,KAAK,EAAE,qBAAqB,CAAC,UAAU;QACvC,OAAO,EAAE,mBAAmB,QAAQ,EAAE;QACtC,MAAM;KACP,CAAC,CAAC;AACL,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,aAAa,CAAC,CAAU;IACtC,MAAM,MAAM,GAAsC,EAAE,CAAC;IACrD,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC5D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;YACxB,IAAI,OAAO,MAAM,KAAK,QAAQ;gBAAE,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QACvD,CAAC;aAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,CAAU;IACxC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACvC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;IACpC,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,WAAW,CAAC,CAAU;IAC7B,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAC5C,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC5C,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,OAAO,IAAI,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,CAAU,EACV,UAAiC;IAEjC,MAAM,QAAQ,GAAG,CAAC,UAAU,CAAC,WAAW,IAAI,kBAAkB,CAAC,CAAC,WAAW,EAAE,CAAC;IAC9E,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,IAAI,IAAI,CAAC;IAC7C,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC9B,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACrD,MAAM,UAAU,GACd,MAAM,KAAK,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,IAAI,aAAa,KAAK,GAAG,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,UAAU,CAAC,kBAAkB,KAAK,IAAI,CAAC;IACvD,0EAA0E;IAC1E,8DAA8D;IAC9D,MAAM,UAAU,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,YAAY,CAAC,CAAC;IAE3E,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC,QAAQ;YAAE,OAAO,SAAS,CAAC;QAChC,MAAM,IAAI,cAAc,CAAC,GAAG,EAAE;YAC5B,KAAK,EAAE,qBAAqB,CAAC,UAAU;YACvC,OAAO,EAAE,KAAK,QAAQ,2BAA2B;YACjD,MAAM,EAAE;gBACN,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,0BAA0B,EAAE,IAAI,EAAE,UAAU,EAAE;aACtF;SACF,CAAC,CAAC;IACL,CAAC;IAED,IACE,MAAM,KAAK,QAAQ;QACnB,CAAC,UAAU;QACX,CAAC,CAAC,QAAQ,KAAK,YAAY,IAAI,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,EAC3D,CAAC;QACD,MAAM,IAAI,cAAc,CAAC,GAAG,EAAE;YAC5B,KAAK,EAAE,qBAAqB,CAAC,oBAAoB;YACjD,OAAO,EAAE,cAAc,QAAQ,8BAA8B,MAAM,IAAI,MAAM,EAAE;SAChF,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC;QACH,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,kBAAkB;gBACrB,kEAAkE;gBAClE,sDAAsD;gBACtD,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;YACxC,KAAK,mCAAmC;gBACtC,IAAI,UAAU,EAAE,CAAC;oBACf,OAAO,MAAM,CAAC,WAAW,CAAC,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;gBACrE,CAAC;gBACD,OAAO,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9C,KAAK,qBAAqB;gBACxB,OAAO,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;YAC9C,KAAK,YAAY;gBACf,OAAO,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YAC5B;gBACE,IAAI,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;oBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;gBACtE,OAAO,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,MAAM,IAAI,cAAc,CAAC,GAAG,EAAE;YAC5B,KAAK,EAAE,qBAAqB,CAAC,UAAU;YACvC,OAAO,EAAE,aAAa,QAAQ,eAAe;YAC7C,MAAM,EAAE;gBACN;oBACE,QAAQ,EAAE,MAAM;oBAChB,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB;oBAChE,IAAI,EAAE,WAAW;iBAClB;aACF;SACF,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AASD,MAAM,KAAK,GAAoC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEjE,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,CAAU,EACV,SAAiC;IAEjC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC;IAC3D,MAAM,YAAY,GAAG,MAAM;QACzB,CAAC,CAAE,CAAC,MAAM,SAAS,CAAC,MAAmB,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,QAAQ,CAAC,CAA6B;QAC9F,CAAC,CAAC,KAAK,CAAC;IACV,MAAM,WAAW,GAAG,KAAK;QACvB,CAAC,CAAE,CAAC,MAAM,SAAS,CAAC,KAAkB,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAA6B;QAC/F,CAAC,CAAC,KAAK,CAAC;IACV,MAAM,aAAa,GAAG,OAAO;QAC3B,CAAC,CAAE,CAAC,MAAM,SAAS,CAAC,OAAoB,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAA6B;QACrG,CAAC,CAAC,KAAK,CAAC;IACV,IAAI,UAAU,GAAY,SAAS,CAAC;IACpC,IAAI,IAAI,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3C,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,EAAE,CAAC;YACjD,UAAU,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAChG,CAAC"}
|
package/dist/zod-openapi.d.ts
CHANGED
|
@@ -8,6 +8,27 @@
|
|
|
8
8
|
* `z` from here (or call `extendZodWithOpenApi` themselves on the same zod
|
|
9
9
|
* instance) instead of importing zod directly.
|
|
10
10
|
*/
|
|
11
|
-
import { z } from "zod";
|
|
11
|
+
import { z, type ZodType } from "zod";
|
|
12
|
+
import { type ZodOpenAPIMetadata } from "@asteasolutions/zod-to-openapi";
|
|
12
13
|
export { z };
|
|
13
14
|
export type { ZodType, ZodObject } from "zod";
|
|
15
|
+
export type OpenApiSchemaMetadata = Partial<ZodOpenAPIMetadata>;
|
|
16
|
+
/**
|
|
17
|
+
* `schema.openapi(...)` for schemas built BEFORE this package was evaluated.
|
|
18
|
+
*
|
|
19
|
+
* zod v4 copies `ZodType.prototype` methods onto each schema instance when it
|
|
20
|
+
* is constructed, so a schema exported by another package (e.g.
|
|
21
|
+
* `@schemavaults/auth-common`) only has its own `.openapi` when that package
|
|
22
|
+
* happened to be evaluated after this one — which depends on the import order
|
|
23
|
+
* of whichever bundle loads first and throws `... .openapi is not a function`
|
|
24
|
+
* at module load otherwise. Invoking the prototype method explicitly sidesteps
|
|
25
|
+
* that: it returns a fresh copy of the schema carrying the metadata, exactly
|
|
26
|
+
* like a direct call would. Use it for every schema you did not build with the
|
|
27
|
+
* `z` exported from here.
|
|
28
|
+
*
|
|
29
|
+
* ```ts
|
|
30
|
+
* export const App = withOpenApi(schemaVaultsAppDefinitionSchema, "App", { description: "..." });
|
|
31
|
+
* const params = z.object({ app_id: withOpenApi(appIdSchema, { example: "my-app" }) });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function withOpenApi<T extends ZodType>(schema: T, refIdOrMetadata: string | OpenApiSchemaMetadata, metadata?: OpenApiSchemaMetadata): T;
|
package/dist/zod-openapi.js
CHANGED
|
@@ -9,7 +9,31 @@
|
|
|
9
9
|
* instance) instead of importing zod directly.
|
|
10
10
|
*/
|
|
11
11
|
import { z } from "zod";
|
|
12
|
-
import { extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";
|
|
12
|
+
import { extendZodWithOpenApi, } from "@asteasolutions/zod-to-openapi";
|
|
13
13
|
extendZodWithOpenApi(z);
|
|
14
14
|
export { z };
|
|
15
|
+
/**
|
|
16
|
+
* `schema.openapi(...)` for schemas built BEFORE this package was evaluated.
|
|
17
|
+
*
|
|
18
|
+
* zod v4 copies `ZodType.prototype` methods onto each schema instance when it
|
|
19
|
+
* is constructed, so a schema exported by another package (e.g.
|
|
20
|
+
* `@schemavaults/auth-common`) only has its own `.openapi` when that package
|
|
21
|
+
* happened to be evaluated after this one — which depends on the import order
|
|
22
|
+
* of whichever bundle loads first and throws `... .openapi is not a function`
|
|
23
|
+
* at module load otherwise. Invoking the prototype method explicitly sidesteps
|
|
24
|
+
* that: it returns a fresh copy of the schema carrying the metadata, exactly
|
|
25
|
+
* like a direct call would. Use it for every schema you did not build with the
|
|
26
|
+
* `z` exported from here.
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* export const App = withOpenApi(schemaVaultsAppDefinitionSchema, "App", { description: "..." });
|
|
30
|
+
* const params = z.object({ app_id: withOpenApi(appIdSchema, { example: "my-app" }) });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export function withOpenApi(schema, refIdOrMetadata, metadata) {
|
|
34
|
+
const openapi = z.ZodType.prototype.openapi;
|
|
35
|
+
return typeof refIdOrMetadata === "string"
|
|
36
|
+
? openapi.call(schema, refIdOrMetadata, metadata)
|
|
37
|
+
: openapi.call(schema, refIdOrMetadata);
|
|
38
|
+
}
|
|
15
39
|
//# sourceMappingURL=zod-openapi.js.map
|
package/dist/zod-openapi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod-openapi.js","sourceRoot":"","sources":["../src/zod-openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"zod-openapi.js","sourceRoot":"","sources":["../src/zod-openapi.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,CAAC,EAAgB,MAAM,KAAK,CAAC;AACtC,OAAO,EACL,oBAAoB,GAErB,MAAM,gCAAgC,CAAC;AAExC,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAExB,OAAO,EAAE,CAAC,EAAE,CAAC;AAOb;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,WAAW,CACzB,MAAS,EACT,eAA+C,EAC/C,QAAgC;IAEhC,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,OAAgE,CAAC;IACrG,OAAO,OAAO,eAAe,KAAK,QAAQ;QACxC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,CAAC;QACjD,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;AAC5C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schemavaults/openapi-operations",
|
|
3
3
|
"description": "Define OpenAPI-representable HTTP operations (zod schemas + auth schemes + handlers) and serve them as Hono apps on Vercel functions / Next.js route handlers",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.1",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"private": false,
|
|
7
7
|
"repository": {
|