api.jsonがswagger-cli validateでエラーにならないように生成ロジックを修正
This commit is contained in:
parent
e0de86359c
commit
1e36284a27
|
@ -16,12 +16,9 @@ export const meta = {
|
||||||
requireCredential: false,
|
requireCredential: false,
|
||||||
|
|
||||||
res: {
|
res: {
|
||||||
oneOf: [{
|
type: 'object',
|
||||||
type: 'object',
|
optional: false, nullable: true,
|
||||||
ref: 'FederationInstance',
|
ref: 'FederationInstance',
|
||||||
}, {
|
|
||||||
type: 'null',
|
|
||||||
}],
|
|
||||||
},
|
},
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
|
|
@ -31,14 +31,6 @@ export function genOpenapiSpec(config: Config) {
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
schemas: schemas,
|
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 requestType = endpoint.meta.requireFile ? 'multipart/form-data' : 'application/json';
|
||||||
const schema = { ...endpoint.params };
|
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) {
|
if (endpoint.meta.requireFile) {
|
||||||
schema.properties = {
|
schema.properties = {
|
||||||
...schema.properties,
|
...schema.properties,
|
||||||
|
@ -79,6 +86,11 @@ export function genOpenapiSpec(config: Config) {
|
||||||
schema.required = [...schema.required ?? [], 'file'];
|
schema.required = [...schema.required ?? [], 'file'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (schema.required && schema.required.length <= 0) {
|
||||||
|
// 空配列は許可されない
|
||||||
|
schema.required = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const info = {
|
const info = {
|
||||||
operationId: endpoint.name,
|
operationId: endpoint.name,
|
||||||
summary: endpoint.name,
|
summary: endpoint.name,
|
||||||
|
@ -90,11 +102,6 @@ export function genOpenapiSpec(config: Config) {
|
||||||
...(endpoint.meta.tags ? {
|
...(endpoint.meta.tags ? {
|
||||||
tags: [endpoint.meta.tags[0]],
|
tags: [endpoint.meta.tags[0]],
|
||||||
} : {}),
|
} : {}),
|
||||||
...(endpoint.meta.requireCredential ? {
|
|
||||||
security: [{
|
|
||||||
ApiKeyAuth: [],
|
|
||||||
}],
|
|
||||||
} : {}),
|
|
||||||
requestBody: {
|
requestBody: {
|
||||||
required: true,
|
required: true,
|
||||||
content: {
|
content: {
|
||||||
|
@ -118,6 +125,11 @@ export function genOpenapiSpec(config: Config) {
|
||||||
description: 'OK (without any results)',
|
description: 'OK (without any results)',
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
...(endpoint.meta.res?.optional === true || endpoint.meta.res?.nullable === true ? {
|
||||||
|
'204': {
|
||||||
|
description: 'OK (without any results)',
|
||||||
|
},
|
||||||
|
} : {}),
|
||||||
'400': {
|
'400': {
|
||||||
description: 'Client error',
|
description: 'Client error',
|
||||||
content: {
|
content: {
|
||||||
|
|
|
@ -10,7 +10,11 @@ export function convertSchemaToOpenApiSchema(schema: Schema) {
|
||||||
const res: any = schema;
|
const res: any = schema;
|
||||||
|
|
||||||
if (schema.type === 'object' && schema.properties) {
|
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)) {
|
for (const k of Object.keys(schema.properties)) {
|
||||||
res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k]);
|
res.properties[k] = convertSchemaToOpenApiSchema(schema.properties[k]);
|
||||||
|
@ -32,8 +36,15 @@ export function convertSchemaToOpenApiSchema(schema: Schema) {
|
||||||
} else {
|
} else {
|
||||||
res.$ref = $ref;
|
res.$ref = $ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// $refを抽出したので不要.
|
||||||
|
res.ref = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// requiredを抽出したので不要.
|
||||||
|
// object以外の型も親階層のobjectによって列挙されているはずなので構わず消す
|
||||||
|
res.optional = undefined;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue