-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
swagger-cli validateがvalidとなるapi.jsonを作れるようにする #12403
Changes from 5 commits
1e36284
443d4f5
c3773a3
61180ad
5cce089
02d4a7b
2fd0530
b043aaa
819f2a2
a9cb82e
f9bf848
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { loadConfig } from './built/config.js' | ||
import { genOpenapiSpec } from './built/server/api/openapi/gen-spec.js' | ||
import { writeFileSync } from "node:fs"; | ||
|
||
const config = loadConfig(); | ||
const spec = genOpenapiSpec(config); | ||
|
||
writeFileSync('./built/api.json', JSON.stringify(spec), 'utf-8'); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ | |
*/ | ||
|
||
import type { Config } from '@/config.js'; | ||
import endpoints from '../endpoints.js'; | ||
import endpoints, { IEndpoint } from '../endpoints.js'; | ||
import { errors as basicErrors } from './errors.js'; | ||
import { schemas, convertSchemaToOpenApiSchema } from './schemas.js'; | ||
|
||
|
@@ -31,18 +31,12 @@ export function genOpenapiSpec(config: Config) { | |
|
||
components: { | ||
schemas: schemas, | ||
|
||
securitySchemes: { | ||
ApiKeyAuth: { | ||
type: 'apiKey', | ||
in: 'body', | ||
name: 'i', | ||
}, | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. inには"header"、"query"、"cookie"のみ設定できるとのことでした… |
||
}, | ||
}; | ||
|
||
for (const endpoint of endpoints.filter(ep => !ep.meta.secure)) { | ||
// 書き換えたりするのでディープコピーしておく。そのまま編集するとメモリ上の値が汚れて次回以降の出力に影響する | ||
const copiedEndpoints = JSON.parse(JSON.stringify(endpoints)) as IEndpoint[]; | ||
for (const endpoint of copiedEndpoints.filter(ep => !ep.meta.secure)) { | ||
const errors = {} as any; | ||
|
||
if (endpoint.meta.errors) { | ||
|
@@ -67,6 +61,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キー用のフィールドを追加する必要がある | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
表向きはそうですが実際はヘッダーに取ってもよいので "securitySchemas": {
"ApiKeyAuth": { "type": "apiKey", "in": "header", "name": "Authorization" }
} にしてしまった方が取り回しの点でも優れて良さそう There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. bodyに https://swagger.io/docs/specification/authentication/api-keys/ |
||
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 +88,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 +104,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 +127,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: { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type: 'null'
は定義されない書式らしいです…代わりに、res直下のoptionalまたはnullableをtrueにすると、レスポンスのHTTPステータス一覧に204が生えるようにしています。