@clov-std/elysia-openapi 1.1.0 → 1.2.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 +4 -0
- package/dist/index.js +44 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -40,6 +40,10 @@ The reference is at `http://localhost:3000/openapi`, the JSON at `http://localho
|
|
|
40
40
|
|
|
41
41
|
Each operation gets an `operationId` derived from the method and path (`get` + `/users/:id` gives `getUsersById`), unique across the document.
|
|
42
42
|
|
|
43
|
+
### Validation errors
|
|
44
|
+
|
|
45
|
+
Every operation that validates params, query, headers, cookies or a body documents Elysia's `422`, a `validation` problem document (`application/problem+json`) added to `components.schemas`. A route that declares its own `422` keeps it.
|
|
46
|
+
|
|
43
47
|
### Response headers
|
|
44
48
|
|
|
45
49
|
```ts
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { Elysia } from "elysia";
|
|
|
4
4
|
|
|
5
5
|
// src/document.ts
|
|
6
6
|
import { StatusMapBack } from "elysia";
|
|
7
|
+
import { isProduction } from "elysia/error";
|
|
7
8
|
import { isRecordNumber } from "elysia/utils";
|
|
8
9
|
import { IsOptional, IsUnion as IsUnion2 } from "typebox";
|
|
9
10
|
|
|
@@ -284,6 +285,46 @@ var mergeRequestBody = (generated, override) => {
|
|
|
284
285
|
}
|
|
285
286
|
return { ...generated, ...override, content };
|
|
286
287
|
};
|
|
288
|
+
var VALIDATION_PROBLEM = "validation";
|
|
289
|
+
var validationProblemSchema = () => ({
|
|
290
|
+
type: "object",
|
|
291
|
+
description: "The request failed validation.",
|
|
292
|
+
required: isProduction() ? ["type", "title", "status"] : ["type", "title", "status", "detail"],
|
|
293
|
+
properties: {
|
|
294
|
+
type: { type: "string", const: VALIDATION_PROBLEM },
|
|
295
|
+
code: { type: "string", const: VALIDATION_PROBLEM },
|
|
296
|
+
title: { type: "string", example: "Validation Error" },
|
|
297
|
+
status: { type: "integer", const: 422 },
|
|
298
|
+
on: {
|
|
299
|
+
type: "string",
|
|
300
|
+
enum: ["params", "query", "headers", "cookie", "body"],
|
|
301
|
+
description: "The part of the request that failed."
|
|
302
|
+
},
|
|
303
|
+
property: { type: "string", description: "Path of the first invalid property." },
|
|
304
|
+
...isProduction() ? {} : {
|
|
305
|
+
detail: {
|
|
306
|
+
type: "string",
|
|
307
|
+
description: "The first validation error, in words."
|
|
308
|
+
},
|
|
309
|
+
found: { description: "The value received." },
|
|
310
|
+
expected: { description: "A value of the expected shape." },
|
|
311
|
+
errors: {
|
|
312
|
+
type: "array",
|
|
313
|
+
description: "Every validation error.",
|
|
314
|
+
items: { type: "object" }
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
var validationResponse = {
|
|
320
|
+
description: "Unprocessable Content",
|
|
321
|
+
content: {
|
|
322
|
+
"application/problem+json": {
|
|
323
|
+
schema: { $ref: `#/components/schemas/${VALIDATION_PROBLEM}` }
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
var validationComponent = (operations) => operations.some((operation) => operation.responses?.["422"] === validationResponse) ? { [VALIDATION_PROBLEM]: validationProblemSchema() } : {};
|
|
287
328
|
var toOperation = (route, models, method) => {
|
|
288
329
|
const { hooks } = route;
|
|
289
330
|
const parameters = new Map;
|
|
@@ -306,6 +347,8 @@ var toOperation = (route, models, method) => {
|
|
|
306
347
|
const allParameters = mergeParameters([...parameters.values()], parameterOverrides);
|
|
307
348
|
const requestBody = mergeRequestBody(toRequestBody(hooks, models, method), requestBodyOverride);
|
|
308
349
|
const responses = mergeResponses(toResponses(route, models), responseOverrides);
|
|
350
|
+
if ((parameters.size > 0 || requestBody) && !responses["422"])
|
|
351
|
+
responses["422"] = validationResponse;
|
|
309
352
|
return {
|
|
310
353
|
...allParameters.length > 0 && { parameters: allParameters },
|
|
311
354
|
...requestBody && { requestBody },
|
|
@@ -474,6 +517,7 @@ var buildDocument = (app, base = {}) => {
|
|
|
474
517
|
...base.components,
|
|
475
518
|
schemas: {
|
|
476
519
|
...base.components?.schemas,
|
|
520
|
+
...validationComponent([...generated.keys()]),
|
|
477
521
|
...Object.fromEntries(Object.entries(models).map(([name, model]) => [
|
|
478
522
|
name,
|
|
479
523
|
toSchema(model)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clov-std/elysia-openapi",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "OpenAPI 3.2 document and Scalar reference for Elysia, generated from your route schemas.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"elysia",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"test": "bun test --pass-with-no-tests --coverage"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@types/bun": "^1.4.
|
|
40
|
-
"oxfmt": "0.
|
|
41
|
-
"oxlint": "1.
|
|
42
|
-
"oxlint-tsgolint": "7.0.
|
|
39
|
+
"@types/bun": "^1.4.4",
|
|
40
|
+
"oxfmt": "0.75.0",
|
|
41
|
+
"oxlint": "1.90.0",
|
|
42
|
+
"oxlint-tsgolint": "7.0.2005",
|
|
43
43
|
"typescript": "^7.0.2"
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|