sveltekit-superforms
Advanced tools
Comparing version
import type { type } from 'arktype'; | ||
import { type ValidationAdapter, type ClientValidationAdapter, type AdapterOptions, type Infer } from './adapters.js'; | ||
import type { JSONSchema7 } from 'json-schema'; | ||
import { type AdapterOptions, type ClientValidationAdapter, type Infer, type ValidationAdapter } from './adapters.js'; | ||
type Options = Parameters<type.Any['toJsonSchema']>[0]; | ||
@@ -5,0 +5,0 @@ export declare const arktypeToJSONSchema: <S extends type.Any>(schema: S, options?: Options) => JSONSchema7; |
@@ -0,3 +1,4 @@ | ||
import { defaultValues } from '../jsonSchema/schemaDefaults.js'; | ||
import { memoize } from '../memoize.js'; | ||
import { createAdapter } from './adapters.js'; | ||
import { memoize } from '../memoize.js'; | ||
async function modules() { | ||
@@ -32,2 +33,14 @@ const { type } = await import(/* webpackIgnore: true */ 'arktype'); | ||
}; | ||
/** | ||
* Creates defaults for ArkType schemas by filtering out undefined values. | ||
* | ||
* ArkType with exactOptionalPropertyTypes requires optional properties to be | ||
* omitted rather than set to undefined. | ||
* | ||
* @param jsonSchema - JSON schema to generate defaults from | ||
* @returns Default values object without undefined properties | ||
*/ | ||
function createArktypeDefaults(jsonSchema) { | ||
return Object.fromEntries(Object.entries(defaultValues(jsonSchema)).filter(([, value]) => value !== undefined)); | ||
} | ||
async function _validate(schema, data) { | ||
@@ -52,6 +65,7 @@ const { type } = await fetchModule(); | ||
function _arktype(schema, options) { | ||
const jsonSchema = options?.jsonSchema ?? arktypeToJSONSchema(schema, options?.config); | ||
return createAdapter({ | ||
superFormValidationLibrary: 'arktype', | ||
defaults: options?.defaults, | ||
jsonSchema: options?.jsonSchema ?? arktypeToJSONSchema(schema, options?.config), | ||
defaults: options?.defaults ?? createArktypeDefaults(jsonSchema), | ||
jsonSchema, | ||
validate: async (data) => _validate(schema, data) | ||
@@ -58,0 +72,0 @@ }); |
@@ -131,2 +131,3 @@ import { pathExists, setPaths, traversePath, traversePaths } from './traversal.js'; | ||
//#region Types | ||
// TODO: Memoize Types with _schema? | ||
const Types = defaultTypes(_schema); | ||
@@ -133,0 +134,0 @@ function Types_correctValue(dataValue, defValue, type) { |
@@ -0,3 +1,3 @@ | ||
import type { JSONSchema } from './index.js'; | ||
import type { SuperValidateOptions } from './superValidate.js'; | ||
import type { JSONSchema } from './index.js'; | ||
type ParsedData = { | ||
@@ -4,0 +4,0 @@ id: string | undefined; |
@@ -1,7 +0,7 @@ | ||
import { SuperFormError, SchemaError } from './errors.js'; | ||
import { parse } from 'devalue'; | ||
import { SchemaError, SuperFormError } from './errors.js'; | ||
import { defaultValues } from './jsonSchema/schemaDefaults.js'; | ||
import { schemaInfo } from './jsonSchema/schemaInfo.js'; | ||
import { defaultValues } from './jsonSchema/schemaDefaults.js'; | ||
import { splitPath } from './stringPath.js'; | ||
import { setPaths } from './traversal.js'; | ||
import { splitPath } from './stringPath.js'; | ||
import { assertSchema } from './utils.js'; | ||
@@ -21,2 +21,30 @@ /** | ||
const unionError = 'FormData parsing failed: Unions are only supported when the dataType option for superForm is set to "json".'; | ||
/** | ||
* Check if multiple types represent compatible variations of the same base type | ||
*/ | ||
function isCompatibleTypeUnion(types) { | ||
const primaryTypes = new Set(types.map((type) => { | ||
if (['number', 'integer'].includes(type)) | ||
return 'number'; | ||
if (type === 'unix-time') | ||
return 'number'; | ||
return type; | ||
})); | ||
return primaryTypes.size <= 1; | ||
} | ||
/** | ||
* Check if union schema represents compatible variations of the same base type | ||
*/ | ||
function isCompatibleUnionSchema(union) { | ||
if (!union) | ||
return true; | ||
const unionTypes = new Set(union.flatMap((u) => u.type | ||
? Array.isArray(u.type) | ||
? u.type | ||
: [u.type] | ||
: u.const !== undefined | ||
? [typeof u.const] | ||
: [])); | ||
return unionTypes.size <= 1 || (unionTypes.size === 2 && unionTypes.has('null')); | ||
} | ||
export async function parseRequest(data, schemaData, options) { | ||
@@ -147,3 +175,3 @@ let parsed; | ||
} | ||
if (info.types.length > 1) { | ||
if (info.types.length > 1 && !isCompatibleTypeUnion(info.types)) { | ||
throw new SchemaError(unionError, key); | ||
@@ -180,3 +208,3 @@ } | ||
const entries = formData.getAll(key); | ||
if (info.union && info.union.length > 1) { | ||
if (info.union && info.union.length > 1 && !isCompatibleUnionSchema(info.union)) { | ||
throw new SchemaError(unionError, key); | ||
@@ -183,0 +211,0 @@ } |
@@ -201,5 +201,8 @@ import { SchemaError } from '../errors.js'; | ||
const info = schemaInfo(schema, isOptional, path); | ||
const output = { | ||
let output = { | ||
__types: info.types | ||
}; | ||
if (info.union) { | ||
output = merge(output, ...info.union.map((u) => _defaultTypes(u, info.isOptional, path))); | ||
} | ||
//if (schema.type == 'object') console.log('--- OBJECT ---'); //debug | ||
@@ -206,0 +209,0 @@ //else console.dir({ path, info }, { depth: 10 }); //debug |
{ | ||
"name": "sveltekit-superforms", | ||
"version": "2.27.0", | ||
"version": "2.27.1", | ||
"author": "Andreas Söderlund <ciscoheat@gmail.com> (https://blog.encodeart.dev)", | ||
@@ -5,0 +5,0 @@ "description": "Making SvelteKit forms a pleasure to use!", |
Sorry, the diff of this file is too big to display
327323
0.57%6632
0.73%