barkey/packages/backend/src/server/api/openapi/schemas.ts
zyoshoka d792f4f348
fix(backend): 虚無ノートを投稿できる問題の修正と api.json の OpenAPI Specification 3.1.0 への対応 ()
* fix(backend): `text: null`だけのノートは投稿できないように

* add test

* Update CHANGELOG.md

* chore: bump OpenAPI Specification from 3.0.0 to 3.1.0

* chore: テストがすでにコメントで記述されていたのでそっちを使うことにする

* fix test

* fix(backend): prohibit posting whitespace-only notes

* Update CHANGELOG.md

* fix(backend): `renoteId`または`fileIds`(`mediaIds`)または`poll`が`null`でない場合に、`text  が空白文字のみで構成されたリクエストになることを許可して、結果は`text: null`を返すように

* test(backend): 引用renoteで空白文字のみで構成されたtextにするとレスポンスが`text: null`になることをチェックするテストを追加

* fix(frontend): `text`が`null`であって`renoteId`と`replyId`が`null`でないようなノートは引用リノートとして表示するように

* fix(misskey-js): OpenAPI 3.1に対応

* fix(misskey-js): 型生成をOpenAPI Specification 3.1.0に対応

* fix(ci): `validate-api.json`をOpenAPI Specification 3.1.0に対応

* fix(ci): スキーマ書き換えの際のミスを修正

* Revert "fix(frontend): `text`が`null`であって`renoteId`と`replyId`が`null`でないようなノートは引用リノートとして表示するように"

This reverts commit a9ca55343df6ea1679599acbc4801f78aa3a242b.

* fix(misskey-js): `build-misskey-js-with-types`時は`api.json`のGETをスキップするように

* Revert "fix(misskey-js): `build-misskey-js-with-types`時は`api.json`のGETをスキップするように"

This reverts commit 865458989f9ddacc38d1bb3743a41ea828dbf324.

* fix(misskey-js): `openapi-parser`で`validate`のかわりに`parse`を用いるように

* Update CHANGELOG.md
2024-01-13 16:54:25 +09:00

88 lines
2.3 KiB
TypeScript

/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import type { Schema } from '@/misc/json-schema.js';
import { refs } from '@/misc/json-schema.js';
export function convertSchemaToOpenApiSchema(schema: Schema, type: 'param' | 'res') {
// optional, nullable, refはスキーマ定義に含まれないので分離しておく
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { optional, nullable, ref, ...res }: any = schema;
if (schema.type === 'object' && schema.properties) {
if (type === 'res') {
const required = Object.entries(schema.properties).filter(([k, v]) => !v.optional).map(([k]) => k);
if (required.length > 0) {
// 空配列は許可されない
res.required = required;
}
}
for (const k of Object.keys(schema.properties)) {
res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k], type);
}
}
if (schema.type === 'array' && schema.items) {
res.items = convertSchemaToOpenApiSchema(schema.items, type);
}
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 (type === 'res' && schema.ref) {
const $ref = `#/components/schemas/${schema.ref}`;
if (schema.nullable || schema.optional) {
res.allOf = [{ $ref }];
} else {
res.$ref = $ref;
}
}
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;
}
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.',
},
},
required: ['code', 'id', 'message'],
},
},
required: ['error'],
},
...Object.fromEntries(
Object.entries(refs).map(([key, schema]) => [key, convertSchemaToOpenApiSchema(schema, 'res')]),
),
};