validateSchema: function()

in src/framework/MUtil.tsx [490:549]


  validateSchema: function (s: MFieldSchema, parentPath?: string): MValidationFail[] {
    let result: MValidationFail[] = [];
    const error = (msg: string) => result.push({ message: msg, path: MUtil.jsonPath(parentPath, s.name) });
    const checkDup = (a: any[], msgIfFail: string) => {
      if (_.uniq(a).length !== a.length) {
        error(msgIfFail);
      }
    };
    const checkVL = (fs: MEnumField[]) => {
      checkDup(fs.map(f => f.value), s.name + "值有重复");
      checkDup(fs.map(f => f.label).filter(l => l), s.name + "文案有重复");
    }
    const stringOnlyEnum = (candidate: string | MEnumField[] | undefined) => {
      const ns = MUtil.standardFields(candidate).find(f => !_.isString(f.value))
      if (ns) {
        error("暂不支持的选项数据类型:" + JSON.stringify(ns) + ": " + (typeof ns))
      }
    }

    if (s.type === "decoration") {
      return [];
    } else if (s.type === "enum") {
      checkVL(MUtil.standardFields(s.enumFields))
    } else if (s.type === "set") {
      checkVL(MUtil.standardFields(s.setFields))
    } else if (s.type === "matrix") {
      stringOnlyEnum(s.matrix.x);
      stringOnlyEnum(s.matrix.y);
    } else if (s.type === "object") {
      if (!s.objectFields) {
        error("object类型未定义成员");
      } else {
        checkDup(s.objectFields.filter(f => f.type !== 'decoration').map(f => f.name), "字段名有重复");
        for (let f of s.objectFields) {
          result = _.concat(result, MUtil.validateSchema(f, MUtil.jsonPath(parentPath, s.name)));
        }

        if (s.uispec?.type === "segmentForm") {
          if (!s.uispec.segments) {
            error("分段未定义");
          } else {
            checkDup(s.uispec.segments.map(f => f.label), "分段文案有重复");
            const fieldsInSegments = _.flatten(s.uispec.segments.map(f => f.fields));
            checkDup(fieldsInSegments, "分段字段有重复");
            const fields = s.objectFields.map(f => f.name);
            checkDup(fields, "字段名有重复");
            const notInSegment = _.difference(fields, fieldsInSegments);
            if (notInSegment.length > 0) {
              error("字段" + notInSegment.join(",") + "未体现在分段中");
            }
            const fieldNotExist = _.difference(fieldsInSegments, fields);
            if (fieldNotExist.length > 0) {
              error("分段字段名无效:" + notInSegment.join(","));
            }
          }
        }
      }
    }
    return result;
  },