From fbfae9f83d67ddb78fe194d96d69600812d596f9 Mon Sep 17 00:00:00 2001 From: yukineko <27853966+hideki0403@users.noreply.github.com> Date: Thu, 1 Feb 2024 22:56:01 +0900 Subject: [PATCH 1/5] =?UTF-8?q?refactor:=20=E8=87=AA=E5=B7=B1=E5=8F=82?= =?UTF-8?q?=E7=85=A7=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=97=E3=81=A6=E3=81=84?= =?UTF-8?q?=E3=82=8B=E7=AE=87=E6=89=80=E3=81=AB`selfRef`=E3=82=92=E6=8C=81?= =?UTF-8?q?=E3=81=9F=E3=81=9B=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/misc/json-schema.ts | 1 + packages/backend/src/models/json-schema/page.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/backend/src/misc/json-schema.ts b/packages/backend/src/misc/json-schema.ts index 0dd8f15d9a8b..dc290036818c 100644 --- a/packages/backend/src/misc/json-schema.ts +++ b/packages/backend/src/misc/json-schema.ts @@ -119,6 +119,7 @@ export interface Schema extends OfSchema { readonly example?: any; readonly format?: string; readonly ref?: keyof typeof refs; + readonly selfRef?: boolean; readonly enum?: ReadonlyArray; readonly default?: (this['type'] extends TypeStringef ? StringDefToType : any) | null; readonly maxLength?: number; diff --git a/packages/backend/src/models/json-schema/page.ts b/packages/backend/src/models/json-schema/page.ts index 402db76e5207..e4d844645e11 100644 --- a/packages/backend/src/models/json-schema/page.ts +++ b/packages/backend/src/models/json-schema/page.ts @@ -53,6 +53,7 @@ const sectionBlockSchema = { type: 'object', optional: false, nullable: false, ref: 'PageBlock', + selfRef: true, }, }, }, From b0cce8cc957a0e61f8bc02a6dce1d0abb97f5ede Mon Sep 17 00:00:00 2001 From: yukineko <27853966+hideki0403@users.noreply.github.com> Date: Thu, 1 Feb 2024 22:57:26 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=E3=82=B9=E3=82=AD=E3=83=BC?= =?UTF-8?q?=E3=83=9E=E7=94=9F=E6=88=90=E6=99=82=E3=81=AB=E8=87=AA=E5=B7=B1?= =?UTF-8?q?=E5=8F=82=E7=85=A7=E3=82=92=E5=90=AB=E3=82=80=E3=81=8B=E3=81=A9?= =?UTF-8?q?=E3=81=86=E3=81=8B=E3=82=92=E6=8C=87=E5=AE=9A=E3=81=A7=E3=81=8D?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/generate_api_json.js | 2 +- .../src/server/api/openapi/gen-spec.ts | 10 +-- .../backend/src/server/api/openapi/schemas.ts | 66 ++++++++++--------- 3 files changed, 40 insertions(+), 38 deletions(-) diff --git a/packages/backend/generate_api_json.js b/packages/backend/generate_api_json.js index 5819c60a5ff4..4079b3bb0aac 100644 --- a/packages/backend/generate_api_json.js +++ b/packages/backend/generate_api_json.js @@ -3,6 +3,6 @@ import { genOpenapiSpec } from './built/server/api/openapi/gen-spec.js' import { writeFileSync } from "node:fs"; const config = loadConfig(); -const spec = genOpenapiSpec(config); +const spec = genOpenapiSpec(config, true); writeFileSync('./built/api.json', JSON.stringify(spec), 'utf-8'); \ No newline at end of file diff --git a/packages/backend/src/server/api/openapi/gen-spec.ts b/packages/backend/src/server/api/openapi/gen-spec.ts index 971a6116bfdd..5dbd4a01e1a9 100644 --- a/packages/backend/src/server/api/openapi/gen-spec.ts +++ b/packages/backend/src/server/api/openapi/gen-spec.ts @@ -6,9 +6,9 @@ import type { Config } from '@/config.js'; import endpoints, { IEndpoint } from '../endpoints.js'; import { errors as basicErrors } from './errors.js'; -import { schemas, convertSchemaToOpenApiSchema } from './schemas.js'; +import { getSchemas, convertSchemaToOpenApiSchema } from './schemas.js'; -export function genOpenapiSpec(config: Config) { +export function genOpenapiSpec(config: Config, includeSelfRef = false) { const spec = { openapi: '3.1.0', @@ -30,7 +30,7 @@ export function genOpenapiSpec(config: Config) { paths: {} as any, components: { - schemas: schemas, + schemas: getSchemas(includeSelfRef), securitySchemes: { bearerAuth: { @@ -56,7 +56,7 @@ export function genOpenapiSpec(config: Config) { } } - const resSchema = endpoint.meta.res ? convertSchemaToOpenApiSchema(endpoint.meta.res, 'res') : {}; + const resSchema = endpoint.meta.res ? convertSchemaToOpenApiSchema(endpoint.meta.res, 'res', includeSelfRef) : {}; 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 = { ...convertSchemaToOpenApiSchema(endpoint.params, 'param') }; + const schema = { ...convertSchemaToOpenApiSchema(endpoint.params, 'param', false) }; if (endpoint.meta.requireFile) { schema.properties = { diff --git a/packages/backend/src/server/api/openapi/schemas.ts b/packages/backend/src/server/api/openapi/schemas.ts index a862a7b74252..1e8b7ad506df 100644 --- a/packages/backend/src/server/api/openapi/schemas.ts +++ b/packages/backend/src/server/api/openapi/schemas.ts @@ -6,7 +6,7 @@ import type { Schema } from '@/misc/json-schema.js'; import { refs } from '@/misc/json-schema.js'; -export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 'res') { +export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 'res', includeSelfRef: boolean): any { // optional, nullable, refはスキーマ定義に含まれないので分離しておく // eslint-disable-next-line @typescript-eslint/no-unused-vars const { optional, nullable, ref, ...res }: any = schema; @@ -21,20 +21,20 @@ export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 're } for (const k of Object.keys(schema.properties)) { - res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k], type); + res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k], type, includeSelfRef); } } if (schema.type === 'array' && schema.items) { - res.items = convertSchemaToOpenApiSchema(schema.items, type); + res.items = convertSchemaToOpenApiSchema(schema.items, type, includeSelfRef); } 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 (o in schema) res[o] = schema[o]!.map(schema => convertSchemaToOpenApiSchema(schema, type, includeSelfRef)); } - if (type === 'res' && schema.ref) { + if (type === 'res' && schema.ref && (!schema.selfRef || includeSelfRef)) { const $ref = `#/components/schemas/${schema.ref}`; if (schema.nullable || schema.optional) { res.allOf = [{ $ref }]; @@ -54,35 +54,37 @@ export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 're return res; } -export const schemas = { - Error: { - type: 'object', - properties: { - error: { - type: 'object', - description: 'An error object.', - properties: { - code: { - type: 'string', - description: 'An error code. Unique within the endpoint.', - }, - message: { - type: 'string', - description: 'An error message.', - }, - id: { - type: 'string', - format: 'uuid', - description: 'An error ID. This ID is static.', +export function getSchemas(includeSelfRef: boolean) { + return { + Error: { + type: 'object', + properties: { + error: { + type: 'object', + description: 'An error object.', + properties: { + code: { + type: 'string', + description: 'An error code. Unique within the endpoint.', + }, + message: { + type: 'string', + description: 'An error message.', + }, + id: { + type: 'string', + format: 'uuid', + description: 'An error ID. This ID is static.', + }, }, + required: ['code', 'id', 'message'], }, - required: ['code', 'id', 'message'], }, + required: ['error'], }, - required: ['error'], - }, - ...Object.fromEntries( - Object.entries(refs).map(([key, schema]) => [key, convertSchemaToOpenApiSchema(schema, 'res')]), - ), -}; + ...Object.fromEntries( + Object.entries(refs).map(([key, schema]) => [key, convertSchemaToOpenApiSchema(schema, 'res', includeSelfRef)]), + ), + }; +} From bd431d279f9ae6a1b61e8c2e39b666ac5830ca87 Mon Sep 17 00:00:00 2001 From: yukineko <27853966+hideki0403@users.noreply.github.com> Date: Thu, 1 Feb 2024 23:29:14 +0900 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20api.json=E3=81=ABselfRef=E3=81=8C?= =?UTF-8?q?=E5=90=AB=E3=81=BE=E3=82=8C=E3=81=A6=E3=81=84=E3=82=8B=E3=81=AE?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/server/api/openapi/schemas.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/backend/src/server/api/openapi/schemas.ts b/packages/backend/src/server/api/openapi/schemas.ts index 1e8b7ad506df..198b24e57a43 100644 --- a/packages/backend/src/server/api/openapi/schemas.ts +++ b/packages/backend/src/server/api/openapi/schemas.ts @@ -3,6 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ +import { de } from 'date-fns/locale'; import type { Schema } from '@/misc/json-schema.js'; import { refs } from '@/misc/json-schema.js'; @@ -43,6 +44,10 @@ export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 're } } + if (schema.selfRef) { + delete res.selfRef; + } + if (schema.nullable) { if (Array.isArray(schema.type) && !schema.type.includes('null')) { res.type.push('null'); From e00bf4dec004baaea605441c83a9c85e5f93d320 Mon Sep 17 00:00:00 2001 From: yukineko <27853966+hideki0403@users.noreply.github.com> Date: Fri, 2 Feb 2024 00:00:09 +0900 Subject: [PATCH 4/5] =?UTF-8?q?refactor:=20=E4=BB=96=E3=81=AE=E7=AE=87?= =?UTF-8?q?=E6=89=80=E3=81=A8=E5=90=8C=E6=A7=98=E3=81=ABselfRef=E3=81=AE?= =?UTF-8?q?=E9=99=A4=E5=8E=BB=E3=82=92=E8=A1=8C=E3=81=86=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/server/api/openapi/schemas.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/backend/src/server/api/openapi/schemas.ts b/packages/backend/src/server/api/openapi/schemas.ts index 198b24e57a43..2534a40eb1ac 100644 --- a/packages/backend/src/server/api/openapi/schemas.ts +++ b/packages/backend/src/server/api/openapi/schemas.ts @@ -10,7 +10,7 @@ import { refs } from '@/misc/json-schema.js'; export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 'res', includeSelfRef: boolean): any { // optional, nullable, refはスキーマ定義に含まれないので分離しておく // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { optional, nullable, ref, ...res }: any = schema; + const { optional, nullable, ref, selfRef, ...res }: any = schema; if (schema.type === 'object' && schema.properties) { if (type === 'res') { @@ -44,10 +44,6 @@ export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 're } } - if (schema.selfRef) { - delete res.selfRef; - } - if (schema.nullable) { if (Array.isArray(schema.type) && !schema.type.includes('null')) { res.type.push('null'); From 06bebd772df1fb0bd495296917912fdecb63d71f Mon Sep 17 00:00:00 2001 From: yukineko <27853966+hideki0403@users.noreply.github.com> Date: Fri, 2 Feb 2024 00:13:14 +0900 Subject: [PATCH 5/5] =?UTF-8?q?remove:=20=E4=B8=8D=E8=A6=81=E3=81=AAimport?= =?UTF-8?q?=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/backend/src/server/api/openapi/schemas.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/backend/src/server/api/openapi/schemas.ts b/packages/backend/src/server/api/openapi/schemas.ts index 2534a40eb1ac..61ce913b7404 100644 --- a/packages/backend/src/server/api/openapi/schemas.ts +++ b/packages/backend/src/server/api/openapi/schemas.ts @@ -3,7 +3,6 @@ * SPDX-License-Identifier: AGPL-3.0-only */ -import { de } from 'date-fns/locale'; import type { Schema } from '@/misc/json-schema.js'; import { refs } from '@/misc/json-schema.js';