fix(misskey-js): OpenAPI 3.1に対応
This commit is contained in:
		@@ -36,7 +36,7 @@ export const paramDef = {
 | 
			
		||||
		untilId: { type: 'string', format: 'misskey:id' },
 | 
			
		||||
		folderId: { type: 'string', format: 'misskey:id', nullable: true, default: null },
 | 
			
		||||
		type: { type: 'string', nullable: true, pattern: /^[a-zA-Z\/\-*]+$/.toString().slice(1, -1) },
 | 
			
		||||
		sort: { type: 'string', nullable: true, enum: ['+createdAt', '-createdAt', '+name', '-name', '+size', '-size'] },
 | 
			
		||||
		sort: { type: 'string', nullable: true, enum: ['+createdAt', '-createdAt', '+name', '-name', '+size', '-size', null] },
 | 
			
		||||
	},
 | 
			
		||||
	required: [],
 | 
			
		||||
} as const;
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,7 @@ export const paramDef = {
 | 
			
		||||
				'-firstRetrievedAt',
 | 
			
		||||
				'+latestRequestReceivedAt',
 | 
			
		||||
				'-latestRequestReceivedAt',
 | 
			
		||||
				null,
 | 
			
		||||
			],
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
 
 | 
			
		||||
@@ -103,13 +103,13 @@ export const meta = {
 | 
			
		||||
							items: {
 | 
			
		||||
								type: 'string',
 | 
			
		||||
								enum: [
 | 
			
		||||
									"ble",
 | 
			
		||||
									"cable",
 | 
			
		||||
									"hybrid",
 | 
			
		||||
									"internal",
 | 
			
		||||
									"nfc",
 | 
			
		||||
									"smart-card",
 | 
			
		||||
									"usb",
 | 
			
		||||
									'ble',
 | 
			
		||||
									'cable',
 | 
			
		||||
									'hybrid',
 | 
			
		||||
									'internal',
 | 
			
		||||
									'nfc',
 | 
			
		||||
									'smart-card',
 | 
			
		||||
									'usb',
 | 
			
		||||
								],
 | 
			
		||||
							},
 | 
			
		||||
						},
 | 
			
		||||
@@ -123,8 +123,8 @@ export const meta = {
 | 
			
		||||
					authenticatorAttachment: {
 | 
			
		||||
						type: 'string',
 | 
			
		||||
						enum: [
 | 
			
		||||
							"cross-platform",
 | 
			
		||||
							"platform",
 | 
			
		||||
							'cross-platform',
 | 
			
		||||
							'platform',
 | 
			
		||||
						],
 | 
			
		||||
					},
 | 
			
		||||
					requireResidentKey: {
 | 
			
		||||
@@ -133,9 +133,9 @@ export const meta = {
 | 
			
		||||
					userVerification: {
 | 
			
		||||
						type: 'string',
 | 
			
		||||
						enum: [
 | 
			
		||||
							"discouraged",
 | 
			
		||||
							"preferred",
 | 
			
		||||
							"required",
 | 
			
		||||
							'discouraged',
 | 
			
		||||
							'preferred',
 | 
			
		||||
							'required',
 | 
			
		||||
						],
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
@@ -144,10 +144,11 @@ export const meta = {
 | 
			
		||||
				type: 'string',
 | 
			
		||||
				nullable: true,
 | 
			
		||||
				enum: [
 | 
			
		||||
					"direct",
 | 
			
		||||
					"enterprise",
 | 
			
		||||
					"indirect",
 | 
			
		||||
					"none",
 | 
			
		||||
					'direct',
 | 
			
		||||
					'enterprise',
 | 
			
		||||
					'indirect',
 | 
			
		||||
					'none',
 | 
			
		||||
					null,
 | 
			
		||||
				],
 | 
			
		||||
			},
 | 
			
		||||
			extensions: {
 | 
			
		||||
 
 | 
			
		||||
@@ -191,10 +191,9 @@ export const paramDef = {
 | 
			
		||||
	then: {
 | 
			
		||||
		properties: {
 | 
			
		||||
			text: {
 | 
			
		||||
				type: 'string',
 | 
			
		||||
				type: ['string', 'null'],
 | 
			
		||||
				minLength: 1,
 | 
			
		||||
				maxLength: MAX_NOTE_TEXT_LENGTH,
 | 
			
		||||
				nullable: false,
 | 
			
		||||
				pattern: '[^\\s]+',
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
 
 | 
			
		||||
@@ -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,12 @@ export function genOpenapiSpec(config: Config) {
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
		spec.paths['/' + endpoint.name] = {
 | 
			
		||||
			...(endpoint.meta.allowGet ? { get: info } : {}),
 | 
			
		||||
			...(endpoint.meta.allowGet ? {
 | 
			
		||||
				get: {
 | 
			
		||||
					...info,
 | 
			
		||||
					operationId: 'get/' + endpoint.name,
 | 
			
		||||
				},
 | 
			
		||||
			} : {}),
 | 
			
		||||
			post: info,
 | 
			
		||||
		};
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -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')]),
 | 
			
		||||
	),
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user