@rhythmjs/openapi 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +149 -0
- package/dist/body/body.d.ts +18 -0
- package/dist/body/body.js +18 -0
- package/dist/callback/callback.d.ts +6 -0
- package/dist/callback/callback.js +7 -0
- package/dist/cookie/cookie.d.ts +10 -0
- package/dist/cookie/cookie.js +14 -0
- package/dist/docs/docs.d.ts +19 -0
- package/dist/docs/docs.js +66 -0
- package/dist/document/document.d.ts +16 -0
- package/dist/document/document.js +6 -0
- package/dist/exclude/exclude.d.ts +5 -0
- package/dist/exclude/exclude.js +7 -0
- package/dist/extension/extension.d.ts +5 -0
- package/dist/extension/extension.js +8 -0
- package/dist/generate/generate.d.ts +21 -0
- package/dist/generate/generate.js +169 -0
- package/dist/header/header.d.ts +10 -0
- package/dist/header/header.js +14 -0
- package/dist/metadata/metadata.d.ts +2 -0
- package/dist/metadata/metadata.js +17 -0
- package/dist/metadata-CT05Tw6j.d.ts +62 -0
- package/dist/operation/operation.d.ts +7 -0
- package/dist/operation/operation.js +7 -0
- package/dist/param/param.d.ts +10 -0
- package/dist/param/param.js +14 -0
- package/dist/query/query.d.ts +10 -0
- package/dist/query/query.js +14 -0
- package/dist/resolver/resolver.d.ts +2 -0
- package/dist/resolver/resolver.js +37 -0
- package/dist/resolver-sb66uMQ-.d.ts +13 -0
- package/dist/response/response.d.ts +18 -0
- package/dist/response/response.js +19 -0
- package/dist/runtime-CCU9lE2d.js +137 -0
- package/dist/runtime-CtmUGPnb.d.ts +24 -0
- package/dist/security/security.d.ts +11 -0
- package/dist/security/security.js +25 -0
- package/dist/tags/tags.d.ts +5 -0
- package/dist/tags/tags.js +7 -0
- package/dist/types/types.d.ts +2 -0
- package/dist/types/types.js +1 -0
- package/dist/types-DeDU0OMv.d.ts +197 -0
- package/package.json +145 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { D as SecurityRequirementObject, E as SchemaObject, S as ReferenceObject, _ as ParameterLocation, a as ExampleObject, d as LinkObject, g as OperationObject, i as EncodingObject, t as CallbackObject, y as ParameterStyle } from "./types-DeDU0OMv.js";
|
|
2
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
|
+
import { Middleware } from "@rhythmjs/rhythm/types";
|
|
4
|
+
import { RhythmHttpContext } from "@rhythmjs/router/adapters/context";
|
|
5
|
+
//#region src/metadata/metadata.d.ts
|
|
6
|
+
declare const OPENAPI_METADATA: symbol;
|
|
7
|
+
type SchemaLike = StandardSchemaV1 | SchemaObject;
|
|
8
|
+
interface MediaTypeSpec {
|
|
9
|
+
schema?: SchemaLike;
|
|
10
|
+
example?: unknown;
|
|
11
|
+
examples?: Record<string, ExampleObject | ReferenceObject>;
|
|
12
|
+
encoding?: Record<string, EncodingObject>;
|
|
13
|
+
}
|
|
14
|
+
interface ParameterOverride {
|
|
15
|
+
description?: string;
|
|
16
|
+
required?: boolean;
|
|
17
|
+
deprecated?: boolean;
|
|
18
|
+
allowEmptyValue?: boolean;
|
|
19
|
+
style?: ParameterStyle;
|
|
20
|
+
explode?: boolean;
|
|
21
|
+
allowReserved?: boolean;
|
|
22
|
+
example?: unknown;
|
|
23
|
+
examples?: Record<string, ExampleObject | ReferenceObject>;
|
|
24
|
+
}
|
|
25
|
+
interface ParameterGroupSpec {
|
|
26
|
+
in: ParameterLocation;
|
|
27
|
+
schema: SchemaLike;
|
|
28
|
+
overrides?: Record<string, ParameterOverride>;
|
|
29
|
+
}
|
|
30
|
+
interface RequestBodySpec {
|
|
31
|
+
description?: string;
|
|
32
|
+
required?: boolean;
|
|
33
|
+
content: Record<string, MediaTypeSpec>;
|
|
34
|
+
}
|
|
35
|
+
interface HeaderSpec {
|
|
36
|
+
description?: string;
|
|
37
|
+
required?: boolean;
|
|
38
|
+
schema?: SchemaLike;
|
|
39
|
+
}
|
|
40
|
+
interface ResponseSpec {
|
|
41
|
+
description: string;
|
|
42
|
+
content?: Record<string, MediaTypeSpec>;
|
|
43
|
+
headers?: Record<string, HeaderSpec | ReferenceObject>;
|
|
44
|
+
links?: Record<string, LinkObject | ReferenceObject>;
|
|
45
|
+
}
|
|
46
|
+
type OperationFields = Pick<OperationObject, "summary" | "description" | "operationId" | "deprecated" | "externalDocs" | "servers">;
|
|
47
|
+
interface OperationFragment {
|
|
48
|
+
operation?: OperationFields;
|
|
49
|
+
tags?: readonly string[];
|
|
50
|
+
parameters?: readonly ParameterGroupSpec[];
|
|
51
|
+
requestBody?: RequestBodySpec;
|
|
52
|
+
responses?: Record<string, ResponseSpec | ReferenceObject>;
|
|
53
|
+
security?: readonly SecurityRequirementObject[] | "none";
|
|
54
|
+
callbacks?: Record<string, CallbackObject | ReferenceObject>;
|
|
55
|
+
extensions?: Record<`x-${string}`, unknown>;
|
|
56
|
+
exclude?: boolean;
|
|
57
|
+
}
|
|
58
|
+
declare function withFragment<TFn>(fn: TFn, fragment: OperationFragment): TFn;
|
|
59
|
+
declare function fragmentOf(fn: unknown): OperationFragment | undefined;
|
|
60
|
+
declare function docOnly(fragment: OperationFragment): Middleware<RhythmHttpContext>;
|
|
61
|
+
//#endregion
|
|
62
|
+
export { OperationFragment as a, RequestBodySpec as c, docOnly as d, fragmentOf as f, OperationFields as i, ResponseSpec as l, MediaTypeSpec as n, ParameterGroupSpec as o, withFragment as p, OPENAPI_METADATA as r, ParameterOverride as s, HeaderSpec as t, SchemaLike as u };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { i as OperationFields } from "../metadata-CT05Tw6j.js";
|
|
2
|
+
import { Middleware } from "@rhythmjs/rhythm/types";
|
|
3
|
+
import { RhythmHttpContext } from "@rhythmjs/router/adapters/context";
|
|
4
|
+
//#region src/operation/operation.d.ts
|
|
5
|
+
export type ApiOperationOptions = OperationFields;
|
|
6
|
+
export declare function apiOperation(options: ApiOperationOptions): Middleware<RhythmHttpContext>;
|
|
7
|
+
//#endregion
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { s as ParameterOverride } from "../metadata-CT05Tw6j.js";
|
|
2
|
+
import { n as ValidationContext, t as Validated } from "../runtime-CtmUGPnb.js";
|
|
3
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
+
import { DeriveMiddleware } from "@rhythmjs/rhythm/types";
|
|
5
|
+
//#region src/param/param.d.ts
|
|
6
|
+
export interface ApiParamOptions {
|
|
7
|
+
overrides?: Record<string, ParameterOverride>;
|
|
8
|
+
}
|
|
9
|
+
export declare function apiParam<TSchema extends StandardSchemaV1>(schema: TSchema, options?: ApiParamOptions): DeriveMiddleware<ValidationContext, Validated<"param", TSchema>>;
|
|
10
|
+
//#endregion
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { a as schemaMiddleware } from "../runtime-CCU9lE2d.js";
|
|
2
|
+
//#region src/param/param.ts
|
|
3
|
+
function apiParam(schema, options = {}) {
|
|
4
|
+
return schemaMiddleware("param", schema, { parameters: [{
|
|
5
|
+
in: "path",
|
|
6
|
+
schema,
|
|
7
|
+
...options.overrides ? { overrides: options.overrides } : {}
|
|
8
|
+
}] }, (ctx) => ({
|
|
9
|
+
ok: true,
|
|
10
|
+
value: ctx.params ?? {}
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { apiParam };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { s as ParameterOverride } from "../metadata-CT05Tw6j.js";
|
|
2
|
+
import { n as ValidationContext, t as Validated } from "../runtime-CtmUGPnb.js";
|
|
3
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
+
import { DeriveMiddleware } from "@rhythmjs/rhythm/types";
|
|
5
|
+
//#region src/query/query.d.ts
|
|
6
|
+
export interface ApiQueryOptions {
|
|
7
|
+
overrides?: Record<string, ParameterOverride>;
|
|
8
|
+
}
|
|
9
|
+
export declare function apiQuery<TSchema extends StandardSchemaV1>(schema: TSchema, options?: ApiQueryOptions): DeriveMiddleware<ValidationContext, Validated<"query", TSchema>>;
|
|
10
|
+
//#endregion
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { a as schemaMiddleware, i as collectQuery } from "../runtime-CCU9lE2d.js";
|
|
2
|
+
//#region src/query/query.ts
|
|
3
|
+
function apiQuery(schema, options = {}) {
|
|
4
|
+
return schemaMiddleware("query", schema, { parameters: [{
|
|
5
|
+
in: "query",
|
|
6
|
+
schema,
|
|
7
|
+
...options.overrides ? { overrides: options.overrides } : {}
|
|
8
|
+
}] }, (ctx) => ({
|
|
9
|
+
ok: true,
|
|
10
|
+
value: collectQuery(ctx.request.url)
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { apiQuery };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
//#region src/resolver/resolver.ts
|
|
2
|
+
function isStandardSchema(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && "~standard" in value;
|
|
4
|
+
}
|
|
5
|
+
async function convertZod(schema, io) {
|
|
6
|
+
const { z } = await import("zod");
|
|
7
|
+
return z.toJSONSchema(schema, {
|
|
8
|
+
io,
|
|
9
|
+
target: "draft-2020-12",
|
|
10
|
+
unrepresentable: "any"
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
async function convertValibot(schema, io) {
|
|
14
|
+
const { toJsonSchema } = await import("@valibot/to-json-schema");
|
|
15
|
+
return toJsonSchema(schema, {
|
|
16
|
+
errorMode: "ignore",
|
|
17
|
+
typeMode: io
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
const builtinConverters = {
|
|
21
|
+
zod: convertZod,
|
|
22
|
+
valibot: convertValibot
|
|
23
|
+
};
|
|
24
|
+
async function resolveSchema(schema, io, options = {}) {
|
|
25
|
+
if (!isStandardSchema(schema)) return schema;
|
|
26
|
+
const vendor = schema["~standard"].vendor;
|
|
27
|
+
const convert = options.converters?.[vendor] ?? builtinConverters[vendor];
|
|
28
|
+
if (!convert) throw new Error(`No JSON Schema converter for schema vendor "${vendor}". Pass one via the "converters" option.`);
|
|
29
|
+
const json = await convert(schema, io);
|
|
30
|
+
if (typeof json === "object" && json !== null && "$schema" in json) {
|
|
31
|
+
const { $schema: _dialect, ...rest } = json;
|
|
32
|
+
return rest;
|
|
33
|
+
}
|
|
34
|
+
return json;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
export { isStandardSchema, resolveSchema };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { E as SchemaObject } from "./types-DeDU0OMv.js";
|
|
2
|
+
import { u as SchemaLike } from "./metadata-CT05Tw6j.js";
|
|
3
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
+
//#region src/resolver/resolver.d.ts
|
|
5
|
+
type SchemaIO = "input" | "output";
|
|
6
|
+
type SchemaConverter = (schema: StandardSchemaV1, io: SchemaIO) => SchemaObject | Promise<SchemaObject>;
|
|
7
|
+
interface ResolverOptions {
|
|
8
|
+
converters?: Record<string, SchemaConverter>;
|
|
9
|
+
}
|
|
10
|
+
declare function isStandardSchema(value: unknown): value is StandardSchemaV1;
|
|
11
|
+
declare function resolveSchema(schema: SchemaLike, io: SchemaIO, options?: ResolverOptions): Promise<SchemaObject>;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { resolveSchema as a, isStandardSchema as i, SchemaConverter as n, SchemaIO as r, ResolverOptions as t };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { S as ReferenceObject, a as ExampleObject, d as LinkObject } from "../types-DeDU0OMv.js";
|
|
2
|
+
import { n as MediaTypeSpec, t as HeaderSpec, u as SchemaLike } from "../metadata-CT05Tw6j.js";
|
|
3
|
+
import { Middleware } from "@rhythmjs/rhythm/types";
|
|
4
|
+
import { RhythmHttpContext } from "@rhythmjs/router/adapters/context";
|
|
5
|
+
//#region src/response/response.d.ts
|
|
6
|
+
export type ResponseStatus = number | "default" | "1XX" | "2XX" | "3XX" | "4XX" | "5XX";
|
|
7
|
+
export interface ApiResponseOptions {
|
|
8
|
+
description: string;
|
|
9
|
+
schema?: SchemaLike;
|
|
10
|
+
contentType?: string;
|
|
11
|
+
example?: unknown;
|
|
12
|
+
examples?: Record<string, ExampleObject | ReferenceObject>;
|
|
13
|
+
content?: Record<string, MediaTypeSpec>;
|
|
14
|
+
headers?: Record<string, HeaderSpec | ReferenceObject>;
|
|
15
|
+
links?: Record<string, LinkObject | ReferenceObject>;
|
|
16
|
+
}
|
|
17
|
+
export declare function apiResponse(status: ResponseStatus, options: ApiResponseOptions): Middleware<RhythmHttpContext>;
|
|
18
|
+
//#endregion
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { docOnly } from "../metadata/metadata.js";
|
|
2
|
+
//#region src/response/response.ts
|
|
3
|
+
function apiResponse(status, options) {
|
|
4
|
+
const hasShorthand = options.schema !== void 0 || options.example !== void 0 || options.examples;
|
|
5
|
+
const content = options.content ?? (hasShorthand ? { [options.contentType ?? "application/json"]: {
|
|
6
|
+
...options.schema !== void 0 ? { schema: options.schema } : {},
|
|
7
|
+
...options.example !== void 0 ? { example: options.example } : {},
|
|
8
|
+
...options.examples ? { examples: options.examples } : {}
|
|
9
|
+
} } : void 0);
|
|
10
|
+
const spec = {
|
|
11
|
+
description: options.description,
|
|
12
|
+
...content ? { content } : {},
|
|
13
|
+
...options.headers ? { headers: options.headers } : {},
|
|
14
|
+
...options.links ? { links: options.links } : {}
|
|
15
|
+
};
|
|
16
|
+
return docOnly({ responses: { [String(status)]: spec } });
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { apiResponse };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { withFragment } from "./metadata/metadata.js";
|
|
2
|
+
//#region src/internal/runtime.ts
|
|
3
|
+
function serializeIssues(issues) {
|
|
4
|
+
return issues.map((issue) => {
|
|
5
|
+
const path = issue.path?.map((segment) => typeof segment === "object" && segment !== null && "key" in segment ? segment.key : segment);
|
|
6
|
+
return {
|
|
7
|
+
message: issue.message,
|
|
8
|
+
...path ? { path: path.filter((key) => typeof key !== "symbol") } : {}
|
|
9
|
+
};
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
function collectMultiValue(pairs) {
|
|
13
|
+
const out = {};
|
|
14
|
+
for (const [key, value] of pairs) {
|
|
15
|
+
const existing = out[key];
|
|
16
|
+
if (existing === void 0) out[key] = value;
|
|
17
|
+
else if (Array.isArray(existing)) existing.push(value);
|
|
18
|
+
else out[key] = [existing, value];
|
|
19
|
+
}
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
function collectQuery(url) {
|
|
23
|
+
return collectMultiValue(new URL(url).searchParams);
|
|
24
|
+
}
|
|
25
|
+
function collectHeaders(request) {
|
|
26
|
+
const out = {};
|
|
27
|
+
for (const [key, value] of request.headers) out[key] = value;
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
function collectCookies(request) {
|
|
31
|
+
const out = {};
|
|
32
|
+
const header = request.headers.get("cookie");
|
|
33
|
+
if (!header) return out;
|
|
34
|
+
for (const pair of header.split(";")) {
|
|
35
|
+
const eq = pair.indexOf("=");
|
|
36
|
+
if (eq === -1) continue;
|
|
37
|
+
const key = pair.slice(0, eq).trim();
|
|
38
|
+
if (!key) continue;
|
|
39
|
+
let value = pair.slice(eq + 1).trim();
|
|
40
|
+
if (value.startsWith("\"") && value.endsWith("\"")) value = value.slice(1, -1);
|
|
41
|
+
try {
|
|
42
|
+
out[key] = decodeURIComponent(value);
|
|
43
|
+
} catch {
|
|
44
|
+
out[key] = value;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
function parseMultipart(body, contentTypeHeader) {
|
|
50
|
+
const boundary = /boundary="?([^";]+)"?/i.exec(contentTypeHeader)?.[1];
|
|
51
|
+
if (!boundary) return void 0;
|
|
52
|
+
const pairs = [];
|
|
53
|
+
for (const part of body.split(`--${boundary}`)) {
|
|
54
|
+
const headerEnd = part.indexOf("\r\n\r\n");
|
|
55
|
+
if (headerEnd === -1) continue;
|
|
56
|
+
const headers = part.slice(0, headerEnd);
|
|
57
|
+
const name = /content-disposition:[^\r\n]*\sname="([^"]*)"/i.exec(headers)?.[1];
|
|
58
|
+
if (name === void 0) continue;
|
|
59
|
+
const value = /\sfilename="([^"]*)"/i.exec(headers)?.[1] ?? part.slice(headerEnd + 4).replace(/\r\n$/, "");
|
|
60
|
+
pairs.push([name, value]);
|
|
61
|
+
}
|
|
62
|
+
return collectMultiValue(pairs);
|
|
63
|
+
}
|
|
64
|
+
function bodyExtractor(contentType) {
|
|
65
|
+
return async (ctx) => {
|
|
66
|
+
if (contentType.includes("json")) try {
|
|
67
|
+
return {
|
|
68
|
+
ok: true,
|
|
69
|
+
value: await ctx.request.clone().json()
|
|
70
|
+
};
|
|
71
|
+
} catch {
|
|
72
|
+
return {
|
|
73
|
+
ok: false,
|
|
74
|
+
message: "Malformed JSON in request body"
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
let text;
|
|
78
|
+
try {
|
|
79
|
+
text = await ctx.request.clone().text();
|
|
80
|
+
} catch {
|
|
81
|
+
return {
|
|
82
|
+
ok: false,
|
|
83
|
+
message: "Unreadable request body"
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
if (contentType.includes("x-www-form-urlencoded")) return {
|
|
87
|
+
ok: true,
|
|
88
|
+
value: collectMultiValue(new URLSearchParams(text))
|
|
89
|
+
};
|
|
90
|
+
if (contentType.includes("form-data")) {
|
|
91
|
+
const value = parseMultipart(text, ctx.request.headers.get("content-type") ?? contentType);
|
|
92
|
+
return value ? {
|
|
93
|
+
ok: true,
|
|
94
|
+
value
|
|
95
|
+
} : {
|
|
96
|
+
ok: false,
|
|
97
|
+
message: "Malformed form data in request body"
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
ok: true,
|
|
102
|
+
value: text
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function schemaMiddleware(target, schema, fragment, extract) {
|
|
107
|
+
const middleware = async (ctx, next) => {
|
|
108
|
+
const fail = (issues) => {
|
|
109
|
+
const failure = {
|
|
110
|
+
success: false,
|
|
111
|
+
target,
|
|
112
|
+
issues
|
|
113
|
+
};
|
|
114
|
+
ctx.response.status = 400;
|
|
115
|
+
ctx.response.headers.set("content-type", "application/json");
|
|
116
|
+
ctx.response.body = JSON.stringify(failure);
|
|
117
|
+
};
|
|
118
|
+
const extracted = await extract(ctx);
|
|
119
|
+
if (!extracted.ok) {
|
|
120
|
+
fail([{ message: extracted.message }]);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const result = await schema["~standard"].validate(extracted.value);
|
|
124
|
+
if (result.issues) {
|
|
125
|
+
fail(serializeIssues(result.issues));
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
ctx.valid = {
|
|
129
|
+
...ctx.valid,
|
|
130
|
+
[target]: result.value
|
|
131
|
+
};
|
|
132
|
+
await next();
|
|
133
|
+
};
|
|
134
|
+
return withFragment(middleware, fragment);
|
|
135
|
+
}
|
|
136
|
+
//#endregion
|
|
137
|
+
export { schemaMiddleware as a, collectQuery as i, collectCookies as n, collectHeaders as r, bodyExtractor as t };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import "./metadata-CT05Tw6j.js";
|
|
2
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
|
+
import { DeriveMiddleware } from "@rhythmjs/rhythm/types";
|
|
4
|
+
import { RhythmHttpContext } from "@rhythmjs/router/adapters/context";
|
|
5
|
+
import { RhythmRouterContext } from "@rhythmjs/router";
|
|
6
|
+
//#region src/internal/runtime.d.ts
|
|
7
|
+
type ValidationTarget = "body" | "query" | "param" | "header" | "cookie";
|
|
8
|
+
type ValidationContext = RhythmHttpContext & Partial<RhythmRouterContext> & {
|
|
9
|
+
valid?: Partial<Record<ValidationTarget, unknown>>;
|
|
10
|
+
};
|
|
11
|
+
type Validated<TTarget extends ValidationTarget, TSchema extends StandardSchemaV1> = {
|
|
12
|
+
valid: { [K in TTarget]: StandardSchemaV1.InferOutput<TSchema>; };
|
|
13
|
+
};
|
|
14
|
+
interface ValidationIssue {
|
|
15
|
+
message: string;
|
|
16
|
+
path?: readonly (string | number)[];
|
|
17
|
+
}
|
|
18
|
+
interface ValidationFailure {
|
|
19
|
+
success: false;
|
|
20
|
+
target: ValidationTarget;
|
|
21
|
+
issues: readonly ValidationIssue[];
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { ValidationTarget as a, ValidationIssue as i, ValidationContext as n, ValidationFailure as r, Validated as t };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Middleware } from "@rhythmjs/rhythm/types";
|
|
2
|
+
import { RhythmHttpContext } from "@rhythmjs/router/adapters/context";
|
|
3
|
+
//#region src/security/security.d.ts
|
|
4
|
+
export declare function apiSecurity(name: string, scopes?: string[]): Middleware<RhythmHttpContext>;
|
|
5
|
+
export declare function apiBearerAuth(name?: string): Middleware<RhythmHttpContext>;
|
|
6
|
+
export declare function apiBasicAuth(name?: string): Middleware<RhythmHttpContext>;
|
|
7
|
+
export declare function apiCookieAuth(name?: string): Middleware<RhythmHttpContext>;
|
|
8
|
+
export declare function apiKeyAuth(name?: string): Middleware<RhythmHttpContext>;
|
|
9
|
+
export declare function apiOAuth2(scopes: string[], name?: string): Middleware<RhythmHttpContext>;
|
|
10
|
+
export declare function apiNoSecurity(): Middleware<RhythmHttpContext>;
|
|
11
|
+
//#endregion
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { docOnly } from "../metadata/metadata.js";
|
|
2
|
+
//#region src/security/security.ts
|
|
3
|
+
function apiSecurity(name, scopes = []) {
|
|
4
|
+
return docOnly({ security: [{ [name]: scopes }] });
|
|
5
|
+
}
|
|
6
|
+
function apiBearerAuth(name = "bearer") {
|
|
7
|
+
return apiSecurity(name);
|
|
8
|
+
}
|
|
9
|
+
function apiBasicAuth(name = "basic") {
|
|
10
|
+
return apiSecurity(name);
|
|
11
|
+
}
|
|
12
|
+
function apiCookieAuth(name = "cookie") {
|
|
13
|
+
return apiSecurity(name);
|
|
14
|
+
}
|
|
15
|
+
function apiKeyAuth(name = "api-key") {
|
|
16
|
+
return apiSecurity(name);
|
|
17
|
+
}
|
|
18
|
+
function apiOAuth2(scopes, name = "oauth2") {
|
|
19
|
+
return apiSecurity(name, scopes);
|
|
20
|
+
}
|
|
21
|
+
function apiNoSecurity() {
|
|
22
|
+
return docOnly({ security: "none" });
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { apiBasicAuth, apiBearerAuth, apiCookieAuth, apiKeyAuth, apiNoSecurity, apiOAuth2, apiSecurity };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { A as ServerVariableObject, C as RequestBodyObject, D as SecurityRequirementObject, E as SchemaObject, O as SecuritySchemeObject, S as ReferenceObject, T as ResponsesObject, _ as ParameterLocation, a as ExampleObject, b as PathItemObject, c as HeaderObject, d as LinkObject, f as MediaTypeObject, g as OperationObject, h as OpenAPIObject, i as EncodingObject, j as TagObject, k as ServerObject, l as InfoObject, m as OAuthFlowsObject, n as ComponentsObject, o as Extensible, p as OAuthFlowObject, r as ContactObject, s as ExternalDocsObject, t as CallbackObject, u as LicenseObject, v as ParameterObject, w as ResponseObject, x as PathsObject, y as ParameterStyle } from "../types-DeDU0OMv.js";
|
|
2
|
+
export { CallbackObject, ComponentsObject, ContactObject, EncodingObject, ExampleObject, Extensible, ExternalDocsObject, HeaderObject, InfoObject, LicenseObject, LinkObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, ParameterLocation, ParameterObject, ParameterStyle, PathItemObject, PathsObject, ReferenceObject, RequestBodyObject, ResponseObject, ResponsesObject, SchemaObject, SecurityRequirementObject, SecuritySchemeObject, ServerObject, ServerVariableObject, TagObject };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
//#region src/types/types.d.ts
|
|
2
|
+
interface Extensible {
|
|
3
|
+
[extension: `x-${string}`]: unknown;
|
|
4
|
+
}
|
|
5
|
+
type SchemaObject = Record<string, unknown> | boolean;
|
|
6
|
+
interface ReferenceObject {
|
|
7
|
+
$ref: string;
|
|
8
|
+
summary?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
}
|
|
11
|
+
interface ContactObject extends Extensible {
|
|
12
|
+
name?: string;
|
|
13
|
+
url?: string;
|
|
14
|
+
email?: string;
|
|
15
|
+
}
|
|
16
|
+
interface LicenseObject extends Extensible {
|
|
17
|
+
name: string;
|
|
18
|
+
identifier?: string;
|
|
19
|
+
url?: string;
|
|
20
|
+
}
|
|
21
|
+
interface InfoObject extends Extensible {
|
|
22
|
+
title: string;
|
|
23
|
+
summary?: string;
|
|
24
|
+
description?: string;
|
|
25
|
+
termsOfService?: string;
|
|
26
|
+
contact?: ContactObject;
|
|
27
|
+
license?: LicenseObject;
|
|
28
|
+
version: string;
|
|
29
|
+
}
|
|
30
|
+
interface ServerVariableObject extends Extensible {
|
|
31
|
+
enum?: string[];
|
|
32
|
+
default: string;
|
|
33
|
+
description?: string;
|
|
34
|
+
}
|
|
35
|
+
interface ServerObject extends Extensible {
|
|
36
|
+
url: string;
|
|
37
|
+
description?: string;
|
|
38
|
+
variables?: Record<string, ServerVariableObject>;
|
|
39
|
+
}
|
|
40
|
+
interface ExternalDocsObject extends Extensible {
|
|
41
|
+
description?: string;
|
|
42
|
+
url: string;
|
|
43
|
+
}
|
|
44
|
+
interface TagObject extends Extensible {
|
|
45
|
+
name: string;
|
|
46
|
+
description?: string;
|
|
47
|
+
externalDocs?: ExternalDocsObject;
|
|
48
|
+
}
|
|
49
|
+
interface ExampleObject extends Extensible {
|
|
50
|
+
summary?: string;
|
|
51
|
+
description?: string;
|
|
52
|
+
value?: unknown;
|
|
53
|
+
externalValue?: string;
|
|
54
|
+
}
|
|
55
|
+
type ParameterLocation = "query" | "header" | "path" | "cookie";
|
|
56
|
+
type ParameterStyle = "matrix" | "label" | "simple" | "form" | "spaceDelimited" | "pipeDelimited" | "deepObject";
|
|
57
|
+
interface ParameterObject extends Extensible {
|
|
58
|
+
name: string;
|
|
59
|
+
in: ParameterLocation;
|
|
60
|
+
description?: string;
|
|
61
|
+
required?: boolean;
|
|
62
|
+
deprecated?: boolean;
|
|
63
|
+
allowEmptyValue?: boolean;
|
|
64
|
+
style?: ParameterStyle;
|
|
65
|
+
explode?: boolean;
|
|
66
|
+
allowReserved?: boolean;
|
|
67
|
+
schema?: SchemaObject;
|
|
68
|
+
example?: unknown;
|
|
69
|
+
examples?: Record<string, ExampleObject | ReferenceObject>;
|
|
70
|
+
content?: Record<string, MediaTypeObject>;
|
|
71
|
+
}
|
|
72
|
+
type HeaderObject = Omit<ParameterObject, "name" | "in">;
|
|
73
|
+
interface EncodingObject extends Extensible {
|
|
74
|
+
contentType?: string;
|
|
75
|
+
headers?: Record<string, HeaderObject | ReferenceObject>;
|
|
76
|
+
style?: ParameterStyle;
|
|
77
|
+
explode?: boolean;
|
|
78
|
+
allowReserved?: boolean;
|
|
79
|
+
}
|
|
80
|
+
interface MediaTypeObject extends Extensible {
|
|
81
|
+
schema?: SchemaObject;
|
|
82
|
+
example?: unknown;
|
|
83
|
+
examples?: Record<string, ExampleObject | ReferenceObject>;
|
|
84
|
+
encoding?: Record<string, EncodingObject>;
|
|
85
|
+
}
|
|
86
|
+
interface RequestBodyObject extends Extensible {
|
|
87
|
+
description?: string;
|
|
88
|
+
content: Record<string, MediaTypeObject>;
|
|
89
|
+
required?: boolean;
|
|
90
|
+
}
|
|
91
|
+
interface LinkObject extends Extensible {
|
|
92
|
+
operationRef?: string;
|
|
93
|
+
operationId?: string;
|
|
94
|
+
parameters?: Record<string, unknown>;
|
|
95
|
+
requestBody?: unknown;
|
|
96
|
+
description?: string;
|
|
97
|
+
server?: ServerObject;
|
|
98
|
+
}
|
|
99
|
+
interface ResponseObject extends Extensible {
|
|
100
|
+
description: string;
|
|
101
|
+
headers?: Record<string, HeaderObject | ReferenceObject>;
|
|
102
|
+
content?: Record<string, MediaTypeObject>;
|
|
103
|
+
links?: Record<string, LinkObject | ReferenceObject>;
|
|
104
|
+
}
|
|
105
|
+
type ResponsesObject = Record<string, ResponseObject | ReferenceObject>;
|
|
106
|
+
type CallbackObject = Record<string, PathItemObject | ReferenceObject>;
|
|
107
|
+
type SecurityRequirementObject = Record<string, string[]>;
|
|
108
|
+
interface OAuthFlowObject extends Extensible {
|
|
109
|
+
authorizationUrl?: string;
|
|
110
|
+
tokenUrl?: string;
|
|
111
|
+
refreshUrl?: string;
|
|
112
|
+
scopes: Record<string, string>;
|
|
113
|
+
}
|
|
114
|
+
interface OAuthFlowsObject extends Extensible {
|
|
115
|
+
implicit?: OAuthFlowObject;
|
|
116
|
+
password?: OAuthFlowObject;
|
|
117
|
+
clientCredentials?: OAuthFlowObject;
|
|
118
|
+
authorizationCode?: OAuthFlowObject;
|
|
119
|
+
}
|
|
120
|
+
type SecuritySchemeObject = (Extensible & {
|
|
121
|
+
type: "apiKey";
|
|
122
|
+
description?: string;
|
|
123
|
+
name: string;
|
|
124
|
+
in: "query" | "header" | "cookie";
|
|
125
|
+
}) | (Extensible & {
|
|
126
|
+
type: "http";
|
|
127
|
+
description?: string;
|
|
128
|
+
scheme: string;
|
|
129
|
+
bearerFormat?: string;
|
|
130
|
+
}) | (Extensible & {
|
|
131
|
+
type: "mutualTLS";
|
|
132
|
+
description?: string;
|
|
133
|
+
}) | (Extensible & {
|
|
134
|
+
type: "oauth2";
|
|
135
|
+
description?: string;
|
|
136
|
+
flows: OAuthFlowsObject;
|
|
137
|
+
}) | (Extensible & {
|
|
138
|
+
type: "openIdConnect";
|
|
139
|
+
description?: string;
|
|
140
|
+
openIdConnectUrl: string;
|
|
141
|
+
});
|
|
142
|
+
interface OperationObject extends Extensible {
|
|
143
|
+
tags?: string[];
|
|
144
|
+
summary?: string;
|
|
145
|
+
description?: string;
|
|
146
|
+
externalDocs?: ExternalDocsObject;
|
|
147
|
+
operationId?: string;
|
|
148
|
+
parameters?: (ParameterObject | ReferenceObject)[];
|
|
149
|
+
requestBody?: RequestBodyObject | ReferenceObject;
|
|
150
|
+
responses?: ResponsesObject;
|
|
151
|
+
callbacks?: Record<string, CallbackObject | ReferenceObject>;
|
|
152
|
+
deprecated?: boolean;
|
|
153
|
+
security?: SecurityRequirementObject[];
|
|
154
|
+
servers?: ServerObject[];
|
|
155
|
+
}
|
|
156
|
+
interface PathItemObject extends Extensible {
|
|
157
|
+
$ref?: string;
|
|
158
|
+
summary?: string;
|
|
159
|
+
description?: string;
|
|
160
|
+
get?: OperationObject;
|
|
161
|
+
put?: OperationObject;
|
|
162
|
+
post?: OperationObject;
|
|
163
|
+
delete?: OperationObject;
|
|
164
|
+
options?: OperationObject;
|
|
165
|
+
head?: OperationObject;
|
|
166
|
+
patch?: OperationObject;
|
|
167
|
+
trace?: OperationObject;
|
|
168
|
+
servers?: ServerObject[];
|
|
169
|
+
parameters?: (ParameterObject | ReferenceObject)[];
|
|
170
|
+
}
|
|
171
|
+
type PathsObject = Record<string, PathItemObject>;
|
|
172
|
+
interface ComponentsObject extends Extensible {
|
|
173
|
+
schemas?: Record<string, SchemaObject>;
|
|
174
|
+
responses?: Record<string, ResponseObject | ReferenceObject>;
|
|
175
|
+
parameters?: Record<string, ParameterObject | ReferenceObject>;
|
|
176
|
+
examples?: Record<string, ExampleObject | ReferenceObject>;
|
|
177
|
+
requestBodies?: Record<string, RequestBodyObject | ReferenceObject>;
|
|
178
|
+
headers?: Record<string, HeaderObject | ReferenceObject>;
|
|
179
|
+
securitySchemes?: Record<string, SecuritySchemeObject | ReferenceObject>;
|
|
180
|
+
links?: Record<string, LinkObject | ReferenceObject>;
|
|
181
|
+
callbacks?: Record<string, CallbackObject | ReferenceObject>;
|
|
182
|
+
pathItems?: Record<string, PathItemObject>;
|
|
183
|
+
}
|
|
184
|
+
interface OpenAPIObject extends Extensible {
|
|
185
|
+
openapi: string;
|
|
186
|
+
info: InfoObject;
|
|
187
|
+
jsonSchemaDialect?: string;
|
|
188
|
+
servers?: ServerObject[];
|
|
189
|
+
paths?: PathsObject;
|
|
190
|
+
webhooks?: Record<string, PathItemObject>;
|
|
191
|
+
components?: ComponentsObject;
|
|
192
|
+
security?: SecurityRequirementObject[];
|
|
193
|
+
tags?: TagObject[];
|
|
194
|
+
externalDocs?: ExternalDocsObject;
|
|
195
|
+
}
|
|
196
|
+
//#endregion
|
|
197
|
+
export { ServerVariableObject as A, RequestBodyObject as C, SecurityRequirementObject as D, SchemaObject as E, SecuritySchemeObject as O, ReferenceObject as S, ResponsesObject as T, ParameterLocation as _, ExampleObject as a, PathItemObject as b, HeaderObject as c, LinkObject as d, MediaTypeObject as f, OperationObject as g, OpenAPIObject as h, EncodingObject as i, TagObject as j, ServerObject as k, InfoObject as l, OAuthFlowsObject as m, ComponentsObject as n, Extensible as o, OAuthFlowObject as p, ContactObject as r, ExternalDocsObject as s, CallbackObject as t, LicenseObject as u, ParameterObject as v, ResponseObject as w, PathsObject as x, ParameterStyle as y };
|