UNPKG

swagger-typed-express-docs

Version:

Simple express runtime parser and documentation swagger generator with 100% support of Typescript static types

373 lines (372 loc) 17.2 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTSchemaValidator = exports.convertSchemaToYupValidationObject = exports.normalizeYupError = void 0; var yup = __importStar(require("yup")); var utils_1 = require("./utils"); var tSchemaDiscriminator_1 = require("./tSchemaDiscriminator"); var normalizeYupError = function (obj) { var _a, _b, _c, _d, _e; if (!obj) return undefined; var yErrObj = JSON.parse(JSON.stringify(obj)); var errorsList = ((_b = (_a = yErrObj.inner) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0 ? (_c = yErrObj.inner) === null || _c === void 0 ? void 0 : _c.map(function (i) { return ({ path: i === null || i === void 0 ? void 0 : i.path, errors: i === null || i === void 0 ? void 0 : i.errors }); }) : (_d = yErrObj.errors) === null || _d === void 0 ? void 0 : _d.map(function (i) { return ({ path: '', errors: i }); }); var niceYErrObj = ((_e = errorsList === null || errorsList === void 0 ? void 0 : errorsList.length) !== null && _e !== void 0 ? _e : 0) > 0 ? errorsList : [{ errors: [yErrObj], path: '' }]; return niceYErrObj; }; exports.normalizeYupError = normalizeYupError; var convertSchemaToYupValidationObject = function (schema, extra) { var _a; var transformTypeMode = (_a = extra === null || extra === void 0 ? void 0 : extra.transformTypeMode) !== null && _a !== void 0 ? _a : 'decode'; var yupValidator = yup; if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'array') { yupValidator = yupValidator.array().of((0, exports.convertSchemaToYupValidationObject)(schema.items, extra)); } else if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'object') { yupValidator = yupValidator .object((0, utils_1.mapEntries)(function (_a) { var _b = __read(_a, 2), k = _b[0], v = _b[1]; var yupValidator = (0, exports.convertSchemaToYupValidationObject)(v, extra); if (v.required && yupValidator.required) { yupValidator = yupValidator.required(); } return [k, yupValidator]; }, schema.properties)) .default(undefined) .test({ name: 'non-nullable-object', message: function (d) { return [ "".concat(d.path, " must be a non-nullable, "), "but the final value was: `".concat(JSON.stringify(d.value), "`."), ].join(''); }, test: function (value) { var isDefaultValueApplied = value === undefined; if (isDefaultValueApplied && schema.required) { return false; } return true; }, }); } else if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'boolean') { yupValidator = yup.mixed().test({ name: 'strict-custom-boolean', message: function (d) { return [ "".concat(d.path, " must be a `boolean` type, "), "but the final value was: `".concat(JSON.stringify(d.value), "`."), ].join(''); }, test: function (value) { if (schema.required === false && (value === null || value === undefined)) return true; if (typeof value === 'boolean') return true; return false; }, }); } else if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'number') { yupValidator = yup .mixed() .test({ name: 'strict-custom-number', message: function (d) { return [ "".concat(d.path, " must be a `number` type, "), "but the final value was: `".concat(JSON.stringify(d.value), "`."), ].join(''); }, test: function (value) { if (schema.required === false && (value === null || value === undefined)) return true; if (typeof value === 'number' && !isNaN(value)) return true; return false; }, }); } else if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'string') { yupValidator = yup.mixed().test({ name: 'strict-custom-string', message: function (d) { return [ "".concat(d.path, " must be a `string` type, "), "but the final value was: `".concat(JSON.stringify(d.value), "`."), ].join(''); }, test: function (value) { if (schema.required === false && (value === null || value === undefined)) return true; if (typeof value === 'string') return true; return false; }, }); } else if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'transformType') { yupValidator = yup.mixed(); yupValidator = yupValidator .transform(function (value) { if (schema.required === false && (value === null || value === undefined)) { return value; } try { if (transformTypeMode === 'decode' || transformTypeMode === 'keep-decoded') { var transformedItem = (0, exports.convertSchemaToYupValidationObject)(schema.encodedTSchema, __assign({}, extra)).validateSync(value, { abortEarly: false }); if (transformTypeMode === 'keep-decoded') return transformedItem; var newValue = schema.syncDecoder(transformedItem); (0, exports.convertSchemaToYupValidationObject)(schema.decodedTSchema, __assign(__assign({}, extra), { transformTypeMode: 'keep-encoded' })).validateSync(newValue, { abortEarly: false }); return newValue; } else if (transformTypeMode === 'encode' || transformTypeMode === 'keep-encoded') { var transformedItem = (0, exports.convertSchemaToYupValidationObject)(schema.decodedTSchema, __assign({}, extra)).validateSync(value, { abortEarly: false }); if (transformTypeMode === 'keep-encoded') return transformedItem; var newValue = schema.syncEncoder(transformedItem); (0, exports.convertSchemaToYupValidationObject)(schema.encodedTSchema, __assign(__assign({}, extra), { transformTypeMode: 'keep-decoded' })).validateSync(newValue, { abortEarly: false }); return newValue; } else { throw new Error('invalid transformTypeMode'); } } catch (err) { return err; } }) .test({ name: "custom-transform-type", test: function (value) { var _a; if (value instanceof Error) return this.createError({ path: this.path, message: (_a = value === null || value === void 0 ? void 0 : value.message) !== null && _a !== void 0 ? _a : '' }); return true; }, }); } else if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'any') { yupValidator = yupValidator.mixed(); } else if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'hashMap') { yupValidator = yup; var objValueValidator_1 = (0, exports.convertSchemaToYupValidationObject)(schema.property, extra); if (schema.property.required && yupValidator.required) { yupValidator = yupValidator.required(); } yupValidator = yupValidator.lazy(function (v) { if (schema.required === false && (v === null || v === undefined)) { return yup.object({}).nullable(); } if (v === null || v === undefined) { return yup.object({}).required(); } return yup.object((0, utils_1.mapEntries)(function (_a) { var _b = __read(_a, 1), k = _b[0]; return [k, objValueValidator_1]; }, v)); }); } else if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'enum') { yupValidator = yupValidator.mixed().test({ name: 'strict-custom-enum', message: function (d) { return [ "".concat(d.path, " must be one of ["), schema.options.join(' | '), "] type, but the final value was: `".concat(JSON.stringify(d.value), "`."), ].join(''); }, test: function (value) { if (schema.required === false && (value === null || value === undefined)) return true; if (schema.options.includes(value)) return true; return false; }, }); } else if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'oneOf') { var extraNoAsyncValidation_1 = __assign({}, extra); var validators_1 = schema.options.map(function (o) { return (0, exports.convertSchemaToYupValidationObject)(o, extraNoAsyncValidation_1); }); yupValidator = yupValidator .mixed() .transform(function (value, ogValue, context) { if (schema.required === false && (value === null || value === undefined)) { return value; } var maybeMatchedItem = (function () { var _a; var enumDiscriminatorKey = (0, tSchemaDiscriminator_1.getOneOfEnumDiscriminator)(schema); if (enumDiscriminatorKey) { if (value && typeof value === 'object' && enumDiscriminatorKey in value) { var discriminatorValue_1 = value[enumDiscriminatorKey]; var matchingSchemaIndex = schema.options.findIndex(function (option) { var _a; return option.type === 'object' && ((_a = option.properties[enumDiscriminatorKey]) === null || _a === void 0 ? void 0 : _a.type) === 'enum' && option.properties[enumDiscriminatorKey].options.includes(discriminatorValue_1); }); var matchingValidator_1 = (_a = validators_1[matchingSchemaIndex]) !== null && _a !== void 0 ? _a : validators_1[0]; return (0, utils_1.validateUntilFirstSuccess)([ function () { return matchingValidator_1.validateSync(value, { abortEarly: false }); }, ]); } } return (0, utils_1.validateUntilFirstSuccess)(schema.options.map(function (_o, index) { return function () { return validators_1[index].validateSync(value, { abortEarly: false, }); }; })); })(); if (maybeMatchedItem.status === 'rejected') { try { var allOptionSchemaErrors = maybeMatchedItem.reasons .map(function (reason) { return (0, exports.normalizeYupError)(reason); }) .filter(utils_1.notNullable); var errMsg = { message: 'data does not match any of allowed schemas', currentValue: value, allOptionSchemaErrors: allOptionSchemaErrors, }; var err = new Error('invalid one of'); err._data = errMsg; return err; } catch (err) { return err; } } return maybeMatchedItem.data; }) .test({ name: 'one-of-schema', test: function (transformedValue, conf) { var _a, _b; if (transformedValue instanceof Error) { return this.createError({ path: this.path, message: (_b = (_a = transformedValue._data) !== null && _a !== void 0 ? _a : transformedValue.message) !== null && _b !== void 0 ? _b : '', }); } return true; }, }); } else if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'lazy') { yupValidator = yupValidator.lazy(function () { return (0, exports.convertSchemaToYupValidationObject)(schema.getSchema(), extra); }); } else { throw new Error("unsupported type ".concat(schema === null || schema === void 0 ? void 0 : schema.type)); } if (schema.required === false && yupValidator.nullable) { yupValidator = yupValidator.nullable(); } if (schema.validator) { yupValidator = yupValidator.test({ name: 'custom-validation', test: function (value) { var _a, _b; if (schema.required === false && (value === null || value === undefined)) return true; try { if (value instanceof Error) return false; (_a = schema.validator) === null || _a === void 0 ? void 0 : _a.call(schema, value); } catch (err) { return this.createError({ path: this.path, message: (_b = err === null || err === void 0 ? void 0 : err.message) !== null && _b !== void 0 ? _b : '' }); } return true; }, }); } return yupValidator; }; exports.convertSchemaToYupValidationObject = convertSchemaToYupValidationObject; var getTSchemaValidator = function (tSchema, extra) { var convertor = (0, exports.convertSchemaToYupValidationObject)(tSchema, extra); var validate = function (value, _a) { var _b = _a === void 0 ? {} : _a, _c = _b.stripUnknown, stripUnknown = _c === void 0 ? true : _c, _d = _b.abortEarly, abortEarly = _d === void 0 ? false : _d; var transformedValue = convertor.validateSync(value, { abortEarly: abortEarly, stripUnknown: stripUnknown }); return transformedValue; }; var isValid = function (value) { try { validate(value); return true; } catch (err) { return false; } }; var validateSync = validate; var isValidSync = isValid; return { validate: validate, validateSync: validateSync, isValid: isValid, isValidSync: isValidSync }; }; exports.getTSchemaValidator = getTSchemaValidator;