api.jsonがswagger-cli validateでエラーにならないように生成ロジックを修正
This commit is contained in:
		
							parent
							
								
									e0de86359c
								
							
						
					
					
						commit
						1e36284a27
					
				|  | @ -16,12 +16,9 @@ export const meta = { | |||
| 	requireCredential: false, | ||||
| 
 | ||||
| 	res: { | ||||
| 		oneOf: [{ | ||||
| 			type: 'object', | ||||
| 			ref: 'FederationInstance', | ||||
| 		}, { | ||||
| 			type: 'null', | ||||
| 		}], | ||||
| 		type: 'object', | ||||
| 		optional: false, nullable: true, | ||||
| 		ref: 'FederationInstance', | ||||
| 	}, | ||||
| } as const; | ||||
| 
 | ||||
|  |  | |||
|  | @ -31,14 +31,6 @@ export function genOpenapiSpec(config: Config) { | |||
| 
 | ||||
| 		components: { | ||||
| 			schemas: schemas, | ||||
| 
 | ||||
| 			securitySchemes: { | ||||
| 				ApiKeyAuth: { | ||||
| 					type: 'apiKey', | ||||
| 					in: 'body', | ||||
| 					name: 'i', | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	}; | ||||
| 
 | ||||
|  | @ -67,6 +59,21 @@ export function genOpenapiSpec(config: Config) { | |||
| 		const requestType = endpoint.meta.requireFile ? 'multipart/form-data' : 'application/json'; | ||||
| 		const schema = { ...endpoint.params }; | ||||
| 
 | ||||
| 		if (endpoint.meta.requireCredential) { | ||||
| 			// https://swagger.io/docs/specification/authentication/api-keys/
 | ||||
| 			// ↑曰く、「can be "header", "query" or "cookie"」とのこと。
 | ||||
| 			// Misskeyはbodyに埋め込む形にしているので、各エンドポイントのパラメータに直接APIキー用のフィールドを追加する必要がある
 | ||||
| 			schema.properties = { | ||||
| 				'i': { | ||||
| 					type: 'string', | ||||
| 					nullable: false, | ||||
| 					description: 'API Key', | ||||
| 				}, | ||||
| 				...schema.properties, | ||||
| 			}; | ||||
| 			schema.required = ['i', ...schema.required ?? []]; | ||||
| 		} | ||||
| 
 | ||||
| 		if (endpoint.meta.requireFile) { | ||||
| 			schema.properties = { | ||||
| 				...schema.properties, | ||||
|  | @ -79,6 +86,11 @@ export function genOpenapiSpec(config: Config) { | |||
| 			schema.required = [...schema.required ?? [], 'file']; | ||||
| 		} | ||||
| 
 | ||||
| 		if (schema.required && schema.required.length <= 0) { | ||||
| 			// 空配列は許可されない
 | ||||
| 			schema.required = undefined; | ||||
| 		} | ||||
| 
 | ||||
| 		const info = { | ||||
| 			operationId: endpoint.name, | ||||
| 			summary: endpoint.name, | ||||
|  | @ -90,11 +102,6 @@ export function genOpenapiSpec(config: Config) { | |||
| 			...(endpoint.meta.tags ? { | ||||
| 				tags: [endpoint.meta.tags[0]], | ||||
| 			} : {}), | ||||
| 			...(endpoint.meta.requireCredential ? { | ||||
| 				security: [{ | ||||
| 					ApiKeyAuth: [], | ||||
| 				}], | ||||
| 			} : {}), | ||||
| 			requestBody: { | ||||
| 				required: true, | ||||
| 				content: { | ||||
|  | @ -118,6 +125,11 @@ export function genOpenapiSpec(config: Config) { | |||
| 						description: 'OK (without any results)', | ||||
| 					}, | ||||
| 				}), | ||||
| 				...(endpoint.meta.res?.optional === true || endpoint.meta.res?.nullable === true ? { | ||||
| 					'204': { | ||||
| 						description: 'OK (without any results)', | ||||
| 					}, | ||||
| 				} : {}), | ||||
| 				'400': { | ||||
| 					description: 'Client error', | ||||
| 					content: { | ||||
|  |  | |||
|  | @ -10,7 +10,11 @@ export function convertSchemaToOpenApiSchema(schema: Schema) { | |||
| 	const res: any = schema; | ||||
| 
 | ||||
| 	if (schema.type === 'object' && schema.properties) { | ||||
| 		res.required = Object.entries(schema.properties).filter(([k, v]) => !v.optional).map(([k]) => k); | ||||
| 		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]); | ||||
|  | @ -32,8 +36,15 @@ export function convertSchemaToOpenApiSchema(schema: Schema) { | |||
| 		} else { | ||||
| 			res.$ref = $ref; | ||||
| 		} | ||||
| 
 | ||||
| 		// $refを抽出したので不要.
 | ||||
| 		res.ref = undefined; | ||||
| 	} | ||||
| 
 | ||||
| 	// requiredを抽出したので不要.
 | ||||
| 	// object以外の型も親階層のobjectによって列挙されているはずなので構わず消す
 | ||||
| 	res.optional = undefined; | ||||
| 
 | ||||
| 	return res; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue