UNPKG

sveltekit-superforms

Version:

Making SvelteKit forms a pleasure to use!

80 lines (79 loc) 3.31 kB
import { assertSchema } from '../utils.js'; import { merge } from 'ts-deepmerge'; const conversionFormatTypes = ['unix-time', 'bigint', 'any', 'symbol', 'set', 'int64']; /** * Normalizes the different kind of schema variations (anyOf, union, const null, etc) * to figure out the field type, optional, nullable, etc. */ export function schemaInfo(schema, isOptional, path) { assertSchema(schema, path); const types = schemaTypes(schema, path); const array = schema.items && types.includes('array') ? (Array.isArray(schema.items) ? schema.items : [schema.items]).filter((s) => typeof s !== 'boolean') : undefined; const additionalProperties = schema.additionalProperties && typeof schema.additionalProperties === 'object' && types.includes('object') ? Object.fromEntries(Object.entries(schema.additionalProperties).filter(([, value]) => typeof value !== 'boolean')) : undefined; const properties = schema.properties && types.includes('object') ? Object.fromEntries(Object.entries(schema.properties).filter(([, value]) => typeof value !== 'boolean')) : undefined; const union = unionInfo(schema)?.filter((u) => u.type !== 'null' && u.const !== null); const result = { types: types.filter((s) => s !== 'null'), isOptional, isNullable: types.includes('null'), schema, union: union?.length ? union : undefined, array, properties, additionalProperties, required: schema.required }; if (!schema.allOf || !schema.allOf.length) { return result; } return { ...merge.withOptions({ allowUndefinedOverrides: false }, result, ...schema.allOf.map((s) => schemaInfo(s, false, []))), schema }; } function schemaTypes(schema, path) { assertSchema(schema, path); let types = schema.const === null ? ['null'] : []; if (schema.type) { types = Array.isArray(schema.type) ? schema.type : [schema.type]; } if (schema.anyOf) { types = schema.anyOf.flatMap((s) => schemaTypes(s, path)); } if (types.includes('array') && schema.uniqueItems) { const i = types.findIndex((t) => t != 'array'); types[i] = 'set'; } else if (schema.format && conversionFormatTypes.includes(schema.format)) { types.unshift(schema.format); // For dates and int64 (bigint), remove the integer type, as the schema format will be used // instead in the following cases if (schema.format == 'unix-time' || schema.format == 'int64') { const i = types.findIndex((t) => t == 'integer'); types.splice(i, 1); } // For bigint, remove the string type, as the schema format will be used // instead in the following cases if (schema.format == 'bigint') { const i = types.findIndex((t) => t == 'string'); types.splice(i, 1); } } if (schema.const && schema.const !== null && typeof schema.const !== 'function') { types.push(typeof schema.const); } return Array.from(new Set(types)); } function unionInfo(schema) { if (!schema.anyOf || !schema.anyOf.length) return undefined; return schema.anyOf.filter((s) => typeof s !== 'boolean'); }