@znight/openapi 0.0.0-stage → 0.1.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.
Files changed (54) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +572 -2
  3. package/dist/build-BTUC96mY.d.mts +174 -0
  4. package/dist/build-DXunOzlI.mjs +733 -0
  5. package/dist/build-DXunOzlI.mjs.map +1 -0
  6. package/dist/compiler.d.mts +16 -0
  7. package/dist/compiler.mjs +2639 -0
  8. package/dist/compiler.mjs.map +1 -0
  9. package/dist/emit-child.d.mts +1 -0
  10. package/dist/emit-child.mjs +124 -0
  11. package/dist/emit-child.mjs.map +1 -0
  12. package/dist/emit.d.mts +2 -0
  13. package/dist/emit.mjs +252 -0
  14. package/dist/emit.mjs.map +1 -0
  15. package/dist/index-CqQ6IRnN.d.mts +60 -0
  16. package/dist/index.d.mts +260 -0
  17. package/dist/index.mjs +777 -0
  18. package/dist/index.mjs.map +1 -0
  19. package/dist/openapi-CQk5dHqc.mjs +39 -0
  20. package/dist/openapi-CQk5dHqc.mjs.map +1 -0
  21. package/dist/shared-BZxtyaB0.mjs +147 -0
  22. package/dist/shared-BZxtyaB0.mjs.map +1 -0
  23. package/dist/testing.d.mts +39 -0
  24. package/dist/testing.mjs +155 -0
  25. package/dist/testing.mjs.map +1 -0
  26. package/dist/types-VzBexMKj.d.mts +213 -0
  27. package/dist/vite.d.mts +24 -0
  28. package/dist/vite.mjs +64 -0
  29. package/dist/vite.mjs.map +1 -0
  30. package/package.json +115 -4
  31. package/src/build.ts +898 -0
  32. package/src/compiler/analyze.ts +81 -0
  33. package/src/compiler/document.ts +612 -0
  34. package/src/compiler/generate.ts +79 -0
  35. package/src/compiler/index.ts +47 -0
  36. package/src/compiler/model.ts +141 -0
  37. package/src/compiler/operations.ts +1475 -0
  38. package/src/compiler/schemas.ts +706 -0
  39. package/src/compiler/validate.ts +102 -0
  40. package/src/compiler/values.ts +81 -0
  41. package/src/converters.ts +137 -0
  42. package/src/decorators.ts +187 -0
  43. package/src/emit/child.ts +144 -0
  44. package/src/emit/index.ts +377 -0
  45. package/src/emit/protocol.ts +35 -0
  46. package/src/index.ts +94 -0
  47. package/src/metadata.ts +112 -0
  48. package/src/openapi.ts +55 -0
  49. package/src/plugin.ts +810 -0
  50. package/src/shared.ts +154 -0
  51. package/src/testing.ts +224 -0
  52. package/src/types.ts +240 -0
  53. package/src/ui.ts +215 -0
  54. package/src/vite.ts +126 -0
@@ -0,0 +1,260 @@
1
+ import { A as SecuritySchemeObject, C as PathItemObject, D as ResponseObject, E as RequestBodyObjectOf, M as ServerVariableObject, N as SpecificationExtensions, O as ResponseObjectOf, P as TagObject, S as ParameterObjectOf, T as RequestBodyObject, _ as OpenApiObject, a as ExternalDocumentationObject, b as ParameterLocation, c as InfoObject, d as LicenseObject, f as MediaTypeObject, g as OpenApiMethod, h as OAuthFlowsObject, i as ExampleObject, j as ServerObject, k as SecurityRequirementObject, l as JsonSchema, m as OAuthFlowObject, n as ContactObject, o as HeaderObject, p as MediaTypeObjectOf, r as EncodingObjectOf, s as HeaderObjectOf, t as ComponentsObject, u as JsonValue, v as OperationObject, w as ReferenceObject, x as ParameterObject, y as OperationObjectOf } from "./types-VzBexMKj.mjs";
2
+ import { _ as SchemaConverterContext, a as buildOpenApiDocument, c as OpenApiMetadata, d as OperationTemplate, f as ParametersPlaceholder, g as SchemaConverter, h as BUILT_IN_CONVERTERS, i as OpenApiWarning, l as OpenApiOperationDefinition, m as SchemaTemplate, n as OpenApiBuildResult, o as OPENAPI_METADATA_VERSION, p as SchemaPlaceholder, r as OpenApiOperationView, s as OpenApiDocumentTemplate, t as BuildOpenApiOptions, u as OpenApiSchemaSlot, v as standardJsonSchemaConverter, y as valibotConverter } from "./build-BTUC96mY.mjs";
3
+ import { ClassMarker, MethodMarker, Plugin, PluginContext, PluginOptions, PluginRootsContext, ProviderKey, TypedToken } from "@znight/core";
4
+ import { GuardRef, PluginHttpRoutes, PluginHttpRoutesContext, PluginRoute, RouteDecorator, RouteMetaEntry, StandardSchemaV1 } from "@znight/http";
5
+ /** A security scheme declared with {@link securityScheme}. */
6
+ interface SecurityScheme {
7
+ /** Key of the scheme in `components.securitySchemes`. */
8
+ readonly name: string;
9
+ readonly definition: SecuritySchemeObject;
10
+ }
11
+ /** One scheme, several schemes that all apply (AND), or a scheme with scopes. */
12
+ type SecurityRequirementInput = SecurityScheme | readonly SecurityScheme[] | {
13
+ readonly scheme: SecurityScheme;
14
+ readonly scopes: readonly string[];
15
+ };
16
+ /** Security of the routes carrying a route decorator (§5.5 of RFC 0002). */
17
+ interface SecurityDecision {
18
+ /** A route decorator (`createRouteDecorator`) found in the route's effective metadata. */
19
+ readonly when: RouteDecorator<any>;
20
+ /** Requirements of the matching routes; `[]` means public. */
21
+ readonly security: readonly SecurityRequirementInput[];
22
+ /** `'value'`: the decorator value (a static string array) becomes the scopes of every requirement. */
23
+ readonly scopes?: "value";
24
+ }
25
+ /** Style of the default operation ids. */
26
+ type OperationIdStyle = "controller.handler" | "handler" | "Controller_handler";
27
+ /** Options of {@link OpenApiDocument}. */
28
+ interface OpenApiDocumentOptions {
29
+ /** Title, version, description... (defaults: the JSDoc of the class, then `package.json`). */
30
+ readonly info?: Partial<InfoObject>;
31
+ readonly servers?: readonly ServerObject[];
32
+ /** Declared tags first, in this order; used tags are added, sorted. */
33
+ readonly tags?: readonly TagObject[];
34
+ readonly externalDocs?: ExternalDocumentationObject;
35
+ /** Default requirements of every operation: entries are alternatives (OR). Default: none. */
36
+ readonly security?: readonly SecurityRequirementInput[];
37
+ /** Security derived from route decorators; the first matching entry wins. */
38
+ readonly decisions?: readonly SecurityDecision[];
39
+ /** Ids of operations without `@ApiOperation({ operationId })`. Default `'controller.handler'`. */
40
+ readonly operationIds?: OperationIdStyle;
41
+ /** Standard error responses (400, 413, 415, declared 4XX/5XX). Default `true`. */
42
+ readonly errors?: boolean | {
43
+ readonly schema: StandardSchemaV1;
44
+ readonly contentType?: string;
45
+ };
46
+ /** ZNIGHT031 and ZNIGHT032 become errors. Default `false`. */
47
+ readonly strict?: boolean;
48
+ /** Read the JSDoc of controllers, handlers and types. Default `true`. */
49
+ readonly jsdoc?: boolean;
50
+ /** `x-*` fields of the root object. */
51
+ readonly extensions?: Readonly<Record<`x-${string}`, JsonValue>>;
52
+ }
53
+ /**
54
+ * Options of the document (one per application, optional). The class is never instantiated nor
55
+ * registered as a provider; its JSDoc gives the title (first line) and the description (the rest).
56
+ *
57
+ * ```ts
58
+ * /** Bookshelf API *\/
59
+ * @OpenApiDocument({ servers: [{ url: '/api' }], security: [ApiKey], decisions: [{ when: Public, security: [] }] })
60
+ * export class BookshelfApi {}
61
+ * ```
62
+ */
63
+ export declare function OpenApiDocument(_options?: OpenApiDocumentOptions): ClassMarker;
64
+ /**
65
+ * Declares a security scheme, read statically by the compiler. At runtime it returns a frozen
66
+ * `{ name, definition }`.
67
+ *
68
+ * ```ts
69
+ * export const ApiKey = securityScheme('apiKey', { type: 'apiKey', in: 'header', name: 'x-api-key' })
70
+ * ```
71
+ */
72
+ export declare function securityScheme(name: string, definition: SecuritySchemeObject): SecurityScheme;
73
+ /** Options of {@link ApiOperation}. */
74
+ interface ApiOperationOptions {
75
+ readonly summary?: string;
76
+ readonly description?: string;
77
+ readonly operationId?: string;
78
+ readonly deprecated?: boolean;
79
+ readonly externalDocs?: ExternalDocumentationObject;
80
+ readonly extensions?: Readonly<Record<`x-${string}`, JsonValue>>;
81
+ }
82
+ /** Overrides the JSDoc and the defaults of an operation. */
83
+ export declare function ApiOperation(_options: ApiOperationOptions): MethodMarker;
84
+ /** Tags of the operations (class and method tags are merged, class tags first). */
85
+ export declare function ApiTags(..._names: [string, ...string[]]): ClassMarker & MethodMarker;
86
+ /** A response status: a code, `'2XX'`-like ranges, or `'default'`. */
87
+ type ApiResponseStatus = number | `${1 | 2 | 3 | 4 | 5}XX` | "default";
88
+ /** Options of {@link ApiResponse}. */
89
+ interface ApiResponseOptions {
90
+ readonly description?: string;
91
+ /** Body schema (a Standard Schema, documented with its output JSON Schema). */
92
+ readonly schema?: StandardSchemaV1;
93
+ /** Media type(s) of the body. Default `application/json` (when the body has a schema). */
94
+ readonly contentType?: string | readonly string[];
95
+ readonly headers?: Readonly<Record<string, Partial<HeaderObject>>>;
96
+ readonly example?: JsonValue;
97
+ }
98
+ /**
99
+ * Declares or overrides a response (repeatable). The body type comes from `T`
100
+ * (`@ApiResponse<Book>(200)`) or from a Standard Schema in `schema`.
101
+ */
102
+ export declare function ApiResponse<_T = never>(_status: ApiResponseStatus, _options?: ApiResponseOptions): MethodMarker;
103
+ /** Options of {@link ApiBody}. */
104
+ interface ApiBodyOptions {
105
+ readonly description?: string;
106
+ readonly required?: boolean;
107
+ readonly contentType?: string | readonly string[];
108
+ readonly schema?: StandardSchemaV1;
109
+ }
110
+ /** The body of a route that reads it itself (`ctx.parseBody()`, `ctx.bodyStream()`). */
111
+ export declare function ApiBody<_T = never>(_options?: ApiBodyOptions): MethodMarker;
112
+ /** Options of {@link ApiQuery} and {@link ApiHeader}. */
113
+ interface ApiParameterOptions {
114
+ readonly description?: string;
115
+ readonly required?: boolean;
116
+ readonly deprecated?: boolean;
117
+ readonly example?: JsonValue;
118
+ }
119
+ /** A query parameter read outside the signature (`ctx.query`); its type is `T` (default `string`). */
120
+ export declare function ApiQuery<_T = string>(_name: string, _options?: ApiParameterOptions): MethodMarker;
121
+ /** A header read by a guard or an interceptor (`x-tenant`); its type is `T` (default `string`). */
122
+ export declare function ApiHeader<_T = string>(_name: string, _options?: ApiParameterOptions): ClassMarker & MethodMarker;
123
+ /**
124
+ * Security of the operations: the route's wins over the class's. Several arguments are
125
+ * alternatives (OR); no argument means public (`security: []`).
126
+ */
127
+ export declare function ApiSecurity(..._requirements: SecurityRequirementInput[]): ClassMarker & MethodMarker;
128
+ /** The controller or route is not documented. */
129
+ export declare function ApiExclude(): ClassMarker & MethodMarker;
130
+ /**
131
+ * The document of the application, provided by `OpenApiPlugin` (a singleton external declared in
132
+ * the manifest of `@znight/openapi`).
133
+ *
134
+ * ```ts
135
+ * @Injectable()
136
+ * export class GatewayRegistration implements OnReady {
137
+ * constructor(private readonly openapi: OpenApi, private readonly gateway: GatewayClient) {}
138
+ * async onReady(): Promise<void> {
139
+ * await this.gateway.publish(await this.openapi.json())
140
+ * }
141
+ * }
142
+ * ```
143
+ */
144
+ export declare abstract class OpenApi {
145
+ /** The frozen document (built on the first call in `'first-request'` mode, or when the plugin is disabled). */
146
+ abstract document(): Promise<OpenApiObject>;
147
+ /** The served JSON text (2 spaces, final newline). */
148
+ abstract json(): Promise<string>;
149
+ /** The YAML text (optional peer `yaml`). */
150
+ abstract yaml(): Promise<string>;
151
+ /** Static view of the operations, without any schema conversion. */
152
+ abstract readonly operations: readonly OpenApiOperationView[];
153
+ }
154
+ /** Tokens of the externals provided by `OpenApiPlugin` (declared in the package manifest). */
155
+ export declare const OpenApiTokens: {
156
+ /** The {@link OpenApi} singleton. */
157
+ readonly OpenApi: TypedToken<OpenApi>;
158
+ };
159
+ /** The supported UIs. */
160
+ type UiKind = "scalar" | "swagger";
161
+ /** An asset of a UI package. */
162
+ interface UiAsset {
163
+ /** Path in the package. */
164
+ readonly file: string;
165
+ /** SRI of the pinned CDN copy. */
166
+ readonly integrity: string;
167
+ readonly kind: "script" | "style";
168
+ }
169
+ /** A UI package pinned by this release (bumped by Renovate; checked by a network test). */
170
+ interface UiPackage {
171
+ readonly name: string;
172
+ readonly version: string;
173
+ readonly assets: readonly UiAsset[];
174
+ }
175
+ /** jsDelivr. */
176
+ export declare const CDN_ORIGIN = "https://cdn.jsdelivr.net";
177
+ /** Pinned versions and SRI hashes of the UI assets. */
178
+ export declare const UI_PACKAGES: Readonly<Record<UiKind, UiPackage>>;
179
+ /** The UI option: a kind, or a kind with its JSON-serialisable configuration. */
180
+ type OpenApiUiOption = UiKind | false | {
181
+ readonly scalar: Readonly<Record<string, JsonValue>>;
182
+ } | {
183
+ readonly swagger: Readonly<Record<string, JsonValue>>;
184
+ };
185
+ /** Options of {@link OpenApiPlugin.configure}. */
186
+ interface OpenApiPluginOptions {
187
+ /** `false` serves nothing and builds nothing (the `OpenApi` external still works). Default `true`. */
188
+ readonly enabled?: boolean;
189
+ /** Path of the JSON document, relative to the HTTP prefix. Default `'/openapi.json'`. */
190
+ readonly path?: string;
191
+ /** A path (`'/openapi.yaml'`) also serves YAML (`application/yaml`, optional peer `yaml`). Default `false`. */
192
+ readonly yaml?: string | false;
193
+ /** `'scalar'` (default), `'swagger'`, `false`, or `{ scalar: config }` / `{ swagger: config }`. */
194
+ readonly ui?: OpenApiUiOption;
195
+ /** Path of the UI page. Local assets are under `${uiPath}/_assets/`. Default `'/docs'`. */
196
+ readonly uiPath?: string;
197
+ /**
198
+ * `'local'` serves the UI package from `node_modules`, `'cdn'` the jsDelivr copy pinned by this
199
+ * release (with SRI), `'auto'` (default) local when the package is installed.
200
+ */
201
+ readonly assets?: "auto" | "local" | "cdn";
202
+ /** `'build'` (default) assembles the document from the metadata; `{ file }` serves a prebuilt `openapi.json`. */
203
+ readonly document?: "build" | {
204
+ readonly file: string | URL;
205
+ };
206
+ /** `'boot'` (default): built in `onBootstrap` (a failure fails the boot); `'first-request'`: built lazily. */
207
+ readonly build?: "boot" | "first-request";
208
+ /** Merged over the static `info`. */
209
+ readonly info?: Partial<InfoObject>;
210
+ /** Replaces the declared `servers`. */
211
+ readonly servers?: readonly ServerObject[];
212
+ readonly filter?: (operation: OpenApiOperationView) => boolean;
213
+ readonly transform?: (document: OpenApiObject) => OpenApiObject;
214
+ /** Extra converters, tried before the built-in ones. */
215
+ readonly converters?: readonly SchemaConverter[];
216
+ /** `'warn'`: a schema that cannot be converted becomes `{}` (ZNIGHT037 warning). Default `'error'`. */
217
+ readonly unrepresentable?: "error" | "warn";
218
+ /** Route metadata of the docs routes (`[Public.meta()]`): seen by guards and by the route decision check. */
219
+ readonly meta?: readonly RouteMetaEntry[];
220
+ /** Extra guards of the docs routes (classes or instances), after the global guards. */
221
+ readonly guards?: readonly GuardRef[];
222
+ /** `cache-control` of the document (revalidated with the ETag). Default `'no-cache'`. */
223
+ readonly cacheControl?: string;
224
+ }
225
+ /** A precomputed response body. */
226
+ interface Body {
227
+ readonly bytes: Uint8Array;
228
+ readonly etag: string;
229
+ readonly contentType: string;
230
+ }
231
+ /** Everything served, computed once. */
232
+ interface Served {
233
+ readonly document: OpenApiObject;
234
+ readonly json: Body;
235
+ readonly yaml: Body | undefined;
236
+ }
237
+ /** The OpenAPI plugin: `OpenApiPlugin.configure()` (name `openapi`). */
238
+ export declare class OpenApiPlugin implements Plugin, PluginHttpRoutes {
239
+ #private;
240
+ readonly name = "openapi";
241
+ private constructor();
242
+ /**
243
+ * Creates the plugin. `options` may be a function of the container, evaluated once the container
244
+ * is ready: `OpenApiPlugin.configure(c => ({ enabled: c.get(ServerConfig).docs }))`.
245
+ */
246
+ static configure(options?: PluginOptions<OpenApiPluginOptions>): OpenApiPlugin;
247
+ /** The classes of the `guards` option (instances are left out): `TestApp` creates them at boot. */
248
+ initRoots(_context?: PluginRootsContext): readonly ProviderKey[];
249
+ register(ctx: PluginContext): void;
250
+ httpRoutes(context: PluginHttpRoutesContext): readonly PluginRoute[];
251
+ onBootstrap(ctx: PluginContext): Promise<void>;
252
+ onReady(ctx: PluginContext): void;
253
+ onDispose(): void;
254
+ /** The views of the operations (no schema conversion). */
255
+ get operations(): readonly OpenApiOperationView[];
256
+ /** The served document and bodies, built once (shared promise; a failure is retried on the next call). */
257
+ served(): Promise<Served>;
258
+ }
259
+ export { type ApiBodyOptions, type ApiOperationOptions, type ApiParameterOptions, type ApiResponseOptions, type ApiResponseStatus, BUILT_IN_CONVERTERS, type BuildOpenApiOptions, type ComponentsObject, type ContactObject, type EncodingObjectOf, type ExampleObject, type ExternalDocumentationObject, type HeaderObject, type HeaderObjectOf, type InfoObject, type JsonSchema, type JsonValue, type LicenseObject, type MediaTypeObject, type MediaTypeObjectOf, type OAuthFlowObject, type OAuthFlowsObject, OPENAPI_METADATA_VERSION, type OpenApiBuildResult, type OpenApiDocumentOptions, type OpenApiDocumentTemplate, type OpenApiMetadata, type OpenApiMethod, type OpenApiObject, type OpenApiOperationDefinition, type OpenApiOperationView, type OpenApiPluginOptions, type OpenApiSchemaSlot, type OpenApiUiOption, type OpenApiWarning, type OperationIdStyle, type OperationObject, type OperationObjectOf, type OperationTemplate, type ParameterLocation, type ParameterObject, type ParameterObjectOf, type ParametersPlaceholder, type PathItemObject, type ReferenceObject, type RequestBodyObject, type RequestBodyObjectOf, type ResponseObject, type ResponseObjectOf, type SchemaConverter, type SchemaConverterContext, type SchemaPlaceholder, type SchemaTemplate, type SecurityDecision, type SecurityRequirementInput, type SecurityRequirementObject, type SecurityScheme, type SecuritySchemeObject, type ServerObject, type ServerVariableObject, type SpecificationExtensions, type TagObject, type UiAsset, type UiKind, type UiPackage, buildOpenApiDocument, standardJsonSchemaConverter, valibotConverter };
260
+ //# sourceMappingURL=index.d.mts.map