koa-swagger-decoratorソースコードの簡単な説明(下書き)
3041 ワード
コアファイルwrapper.ts はdecorator関数の実行後に得られたデータに基づいてrouterの自動化構築を行い、middlewares関数の結果に基づいてrouter構築時に対応するミドルウェアを追加するために使用される. swaggerObjectに基づくswagger文書 の構築
swaggerObject.ts swaggerドキュメントは、json記述を使用することができ、swaggerObjectは、swaggerObjectのインスタンスを露出し、decoratorが使用するために対応するswaggerフィールドを追加する方法を提供し、dataフィールドがswaggerオブジェクト全体を表し、swagger jsonドキュメントを構築するために露出する
decorators.tsは,@request,@summaryなどの使用するdecoratorを定義する.swaggerドキュメントの構築では、summaryとdescriptionのフォーマットが同じなど、フィールドに対して似たような構造があるため、decorator関数をより簡潔にするためにcurry化を使用してコード構造を最適化します.次のように
これらのdecoratorでは、swaggerObjectに対して関連フィールドの内容を追加することと、router構築に対して関連フィールドの内容を追加すること、例えば@requestにpathを追加すること、methodの2つのフィールドをバインドする方法においてwapper.jsではこれらの情報に基づいてrouterを構築できます
validate/index.ts validate/check.tsこの2つのファイルはdecorator定義のパラメータを検証するために使用されます.肝心な難点はswaggerにおけるarrayとobjectネスト構造の検証を再帰的に実現することである.参照コードは、cObjectでcheckチェックネストデータを呼び出します.
swaggerObject.ts swaggerドキュメントは、json記述を使用することができ、swaggerObjectは、swaggerObjectのインスタンスを露出し、decoratorが使用するために対応するswaggerフィールドを追加する方法を提供し、dataフィールドがswaggerオブジェクト全体を表し、swagger jsonドキュメントを構築するために露出する
decorators.tsは,@request,@summaryなどの使用するdecoratorを定義する.swaggerドキュメントの構築では、summaryとdescriptionのフォーマットが同じなど、フィールドに対して似たような構造があるため、decorator関数をより簡潔にするためにcurry化を使用してコード構造を最適化します.次のように
const _desc = (type: string, text: string | any[]) => (target: any, name: string, descriptor: PropertyDescriptor) => {
descriptor.value[type] = text;
swaggerObject.add(target, name, { [type]: text });
return descriptor;
};
const desc = _.curry(_desc);
const description = desc('description');
const summary = desc('summary');
const tags = desc('tags');
これらのdecoratorでは、swaggerObjectに対して関連フィールドの内容を追加することと、router構築に対して関連フィールドの内容を追加すること、例えば@requestにpathを追加すること、methodの2つのフィールドをバインドする方法においてwapper.jsではこれらの情報に基づいてrouterを構築できます
validate/index.ts validate/check.tsこの2つのファイルはdecorator定義のパラメータを検証するために使用されます.肝心な難点はswaggerにおけるarrayとobjectネスト構造の検証を再帰的に実現することである.参照コードは、cObjectでcheckチェックネストデータを呼び出します.
const check = (input: any, expect: Expect) => {
const cond = _.cond([
[_.equals('string'), () => cString(input, expect)],
[_.equals('boolean'), () => cBool(input, expect)],
[_.equals('number'), () => cNum(input, expect)],
[_.equals('object'), () => cObject(input, expect)],
[_.equals('array'), () => cArray(input, expect)],
[_.T, () => ({ is: true, val: input })] // ,
]);
return cond(expect.type);
};
// /**
// * Object ,
// {
// aaaa: 'hh',
// bbbb: 'qq',
// }
// { // expect:
// type: 'object',
// properties: {
// aaaa: { type: 'string', example: 'http://www.baidu.com', required: true },
// bbbb: { type: 'string', example: 'Bob' }
// c: { type: 'object', properties: {ii: {type: 'string'}, jj: {type: 'number'}} }
// }
// }
// */
const cObject = (input: any, expect: Expect = {}) => {
if (!cRequired(input, expect).is) return { is: false };
const res = { is: true, val: input };
if (!is.object(input)) return { is: false };
if (!expect.properties) return res;
for (const key of Object.keys(expect.properties)) {
// ignore empty key if not required
if (!expect.properties[key].required && input[key] === undefined) {
continue; // eslint-disable-line
}
const { is, val } = check(input[key], expect.properties[key]);
if (!is) {
console.log('error object properties:', key); // TODO need to update error debug info
res.is = false;
break;
}
input[key] = is ? val : input[key];
}
return res;
};