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化を使用してコード構造を最適化します.次のように
    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;
    };