summaryrefslogtreecommitdiff
path: root/packages/backend/src/server/api/openapi
diff options
context:
space:
mode:
Diffstat (limited to 'packages/backend/src/server/api/openapi')
-rw-r--r--packages/backend/src/server/api/openapi/gen-spec.ts10
-rw-r--r--packages/backend/src/server/api/openapi/schemas.ts37
2 files changed, 30 insertions, 17 deletions
diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts
index 0e71510b48..971a6116bf 100644
--- a/packages/backend/src/server/api/openapi/gen-spec.ts
+++ b/packages/backend/src/server/api/openapi/gen-spec.ts
@@ -10,7 +10,7 @@ import { schemas, convertSchemaToOpenApiSchema } from './schemas.js';
export function genOpenapiSpec(config: Config) {
const spec = {
- openapi: '3.0.0',
+ openapi: '3.1.0',
info: {
version: config.version,
@@ -56,7 +56,7 @@ export function genOpenapiSpec(config: Config) {
}
}
- const resSchema = endpoint.meta.res ? convertSchemaToOpenApiSchema(endpoint.meta.res) : {};
+ const resSchema = endpoint.meta.res ? convertSchemaToOpenApiSchema(endpoint.meta.res, 'res') : {};
let desc = (endpoint.meta.description ? endpoint.meta.description : 'No description provided.') + '\n\n';
@@ -71,7 +71,7 @@ export function genOpenapiSpec(config: Config) {
}
const requestType = endpoint.meta.requireFile ? 'multipart/form-data' : 'application/json';
- const schema = { ...endpoint.params };
+ const schema = { ...convertSchemaToOpenApiSchema(endpoint.params, 'param') };
if (endpoint.meta.requireFile) {
schema.properties = {
@@ -210,7 +210,9 @@ export function genOpenapiSpec(config: Config) {
};
spec.paths['/' + endpoint.name] = {
- ...(endpoint.meta.allowGet ? { get: info } : {}),
+ ...(endpoint.meta.allowGet ? {
+ get: info,
+ } : {}),
post: info,
};
}
diff --git a/packages/backend/src/server/api/openapi/schemas.ts b/packages/backend/src/server/api/openapi/schemas.ts
index 2716f5f162..a862a7b742 100644
--- a/packages/backend/src/server/api/openapi/schemas.ts
+++ b/packages/backend/src/server/api/openapi/schemas.ts
@@ -6,32 +6,35 @@
import type { Schema } from '@/misc/json-schema.js';
import { refs } from '@/misc/json-schema.js';
-export function convertSchemaToOpenApiSchema(schema: Schema) {
- // optional, refはスキーマ定義に含まれないので分離しておく
+export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 'res') {
+ // optional, nullable, refはスキーマ定義に含まれないので分離しておく
// eslint-disable-next-line @typescript-eslint/no-unused-vars
- const { optional, ref, ...res }: any = schema;
+ const { optional, nullable, ref, ...res }: any = schema;
if (schema.type === 'object' && schema.properties) {
- const required = Object.entries(schema.properties).filter(([k, v]) => !v.optional).map(([k]) => k);
- if (required.length > 0) {
+ if (type === 'res') {
+ const required = Object.entries(schema.properties).filter(([k, v]) => !v.optional).map(([k]) => k);
+ if (required.length > 0) {
// 空配列は許可されない
- res.required = required;
+ res.required = required;
+ }
}
for (const k of Object.keys(schema.properties)) {
- res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k]);
+ res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k], type);
}
}
if (schema.type === 'array' && schema.items) {
- res.items = convertSchemaToOpenApiSchema(schema.items);
+ res.items = convertSchemaToOpenApiSchema(schema.items, type);
}
- if (schema.anyOf) res.anyOf = schema.anyOf.map(convertSchemaToOpenApiSchema);
- if (schema.oneOf) res.oneOf = schema.oneOf.map(convertSchemaToOpenApiSchema);
- if (schema.allOf) res.allOf = schema.allOf.map(convertSchemaToOpenApiSchema);
+ for (const o of ['anyOf', 'oneOf', 'allOf'] as const) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ if (o in schema) res[o] = schema[o]!.map(schema => convertSchemaToOpenApiSchema(schema, type));
+ }
- if (schema.ref) {
+ if (type === 'res' && schema.ref) {
const $ref = `#/components/schemas/${schema.ref}`;
if (schema.nullable || schema.optional) {
res.allOf = [{ $ref }];
@@ -40,6 +43,14 @@ export function convertSchemaToOpenApiSchema(schema: Schema) {
}
}
+ if (schema.nullable) {
+ if (Array.isArray(schema.type) && !schema.type.includes('null')) {
+ res.type.push('null');
+ } else if (typeof schema.type === 'string') {
+ res.type = [res.type, 'null'];
+ }
+ }
+
return res;
}
@@ -72,6 +83,6 @@ export const schemas = {
},
...Object.fromEntries(
- Object.entries(refs).map(([key, schema]) => [key, convertSchemaToOpenApiSchema(schema)]),
+ Object.entries(refs).map(([key, schema]) => [key, convertSchemaToOpenApiSchema(schema, 'res')]),
),
};