Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | 1x 1x 1x 36x 1x 9x 1x 51x 17x 15x 3x 4x 3x 1x 7x 1x 28x 1x 88x 88x 88x 2x 2x 2x 88x 88x 79x 52x 1x 51x 27x 5x 5x 22x 20x 26x 10x 26x 9x 8x 10x 9x 6x 4x 3x 2x 2x 1x 1x 1x | import { combineValidationObjects } from './validate.js'
import {
Validation, isArray, isEnum, isObj,
isString, isMap, isNumber, isTypeDefValidation, ValueTypes, isMeta, isAnd
} from './validationTypes.js'
const containsOptional = (input: Validation) =>
(Array.isArray(input) && input.some(y => y === '?')) ||
input === '?'
const allOptional = (input: Validation) =>
Object.values(input).every(containsOptional)
const simpleTypes = (input: string) => {
switch (input) {
case 'string':
return 'string'
case 'number':
return 'number'
case 'integer':
return 'number'
case 'boolean':
return 'boolean'
case 'any':
return 'any'
case 'null':
return 'null'
case '?':
return 'undefined'
default: throw new Error(`Unhandled ${input}`)
}
}
export const validationToType = (input:ValueTypes): string => validationToTypeInternal(input, {})
const validationToTypeInternal = (input: ValueTypes, typesIn: {[key:string]:Validation}): string => {
let customTypes = typesIn
let type:ValueTypes = input
if (isTypeDefValidation(input)) {
customTypes = input.$types
type = { ...input }
delete type.$types
}
const toType = (input:ValueTypes) => validationToTypeInternal(input, customTypes)
if (Array.isArray(type)) { return type.map(toType).join(' | ') }
if (typeof type === 'string') {
if (customTypes[type]) {
return toType(customTypes[type])
}
return simpleTypes(type)
}
if (isArray(type)) {
const typeRet = toType(type.$array)
return (Array.isArray(type.$array) && type.$array.length > 1) || typeRet.indexOf('|') > -1
? `(${typeRet})[]` : `${typeRet}[]`
}
if (isEnum(type)) { return type.$enum.map(x => `"${x}"`).join(' | ') }
if (isObj(type)) {
const optionalPostfix = (value: Validation) => containsOptional(value) ? '?' : ''
const obj = Object.entries(type)
.map(([key, value]) => `${key.startsWith('\\$') ? key.slice(1) : key}${optionalPostfix(value)}: ${toType(value)}`)
.join('; ')
if (allOptional(type)) { return `{ ${obj} } | undefined` }
return `{ ${obj} }`
}
if (isString(type)) { return toType('string') }
if (isMap(type)) { return `{ [key: string] : ${toType(type.$map)}}` }
if (isMeta(type)) { return toType(type.$type) }
if (isNumber(type)) { return toType('number') }
if (isAnd(type)) {
const combined = combineValidationObjects(type, customTypes, (x) => x)
if (combined.result === 'error') {
throw new Error('Schema error, $and types must be objects: ' + JSON.stringify(combined.error, null, 2))
}
return toType(combined.pass)
}
throw new Error(`UNSUPPORTED ${JSON.stringify(type, undefined, 2)}`)
}
|