sveltekit-superforms
Advanced tools
Comparing version 2.7.0 to 2.8.0
@@ -53,10 +53,11 @@ import { derived, get, readonly, writable } from 'svelte/store'; | ||
} | ||
///////////////////////////////////////////////////////////////////// | ||
/** | ||
* V1 compatibilty. resetForm = false and taintedMessage = true | ||
*/ | ||
let legacyMode = false; | ||
let LEGACY_MODE = false; | ||
try { | ||
// @ts-expect-error Vite define check | ||
if (SUPERFORMS_LEGACY) | ||
legacyMode = true; | ||
LEGACY_MODE = true; | ||
} | ||
@@ -67,2 +68,15 @@ catch { | ||
/** | ||
* Storybook compatibility mode, basically disables the navigating store. | ||
*/ | ||
let STORYBOOK_MODE = false; | ||
try { | ||
// @ts-expect-error Storybook check | ||
if (globalThis.STORIES) | ||
STORYBOOK_MODE = true; | ||
} | ||
catch { | ||
// No Storybook | ||
} | ||
///////////////////////////////////////////////////////////////////// | ||
/** | ||
* Initializes a SvelteKit form, for convenient handling of values, errors and sumbitting data. | ||
@@ -81,3 +95,3 @@ * @param {SuperValidated} form Usually data.form from PageData. | ||
{ | ||
if (options.legacy ?? legacyMode) { | ||
if (options.legacy ?? LEGACY_MODE) { | ||
if (options.resetForm === undefined) | ||
@@ -88,2 +102,6 @@ options.resetForm = false; | ||
} | ||
if (STORYBOOK_MODE) { | ||
if (options.applyAction === undefined) | ||
options.applyAction = false; | ||
} | ||
initialValidator = options.validators; | ||
@@ -1050,5 +1068,18 @@ options = { | ||
let cancelled = false; | ||
function cancel(resetTimers = true) { | ||
function clientValidationResult(validation) { | ||
const validationResult = { ...validation, posted: true }; | ||
const status = validationResult.valid | ||
? 200 | ||
: (typeof options.SPA === 'boolean' ? undefined : options.SPA?.failStatus) ?? 400; | ||
const data = { form: validationResult }; | ||
const result = validationResult.valid | ||
? { type: 'success', status, data } | ||
: { type: 'failure', status, data }; | ||
setTimeout(() => validationResponse({ result }), 0); | ||
} | ||
function cancel(opts = { | ||
resetTimers: true | ||
}) { | ||
cancelled = true; | ||
if (resetTimers && htmlForm.isSubmitting()) { | ||
if (opts.resetTimers && htmlForm.isSubmitting()) { | ||
htmlForm.completed({ cancelled }); | ||
@@ -1060,3 +1091,3 @@ } | ||
if (htmlForm.isSubmitting() && options.multipleSubmits == 'prevent') { | ||
cancel(false); | ||
cancel({ resetTimers: false }); | ||
} | ||
@@ -1074,7 +1105,5 @@ else { | ||
} | ||
if (cancelled) { | ||
if (options.flashMessage) | ||
cancelFlash(options); | ||
} | ||
else { | ||
if (cancelled && options.flashMessage) | ||
cancelFlash(options); | ||
if (!cancelled) { | ||
// Client validation | ||
@@ -1093,9 +1122,4 @@ const noValidate = !options.SPA && | ||
if (!validation.valid) { | ||
cancel(false); | ||
const result = { | ||
type: 'failure', | ||
status: (typeof options.SPA === 'boolean' ? undefined : options.SPA?.failStatus) ?? 400, | ||
data: { form: validation } | ||
}; | ||
setTimeout(() => validationResponse({ result }), 0); | ||
cancel({ resetTimers: false }); | ||
clientValidationResult(validation); | ||
} | ||
@@ -1128,16 +1152,6 @@ } | ||
if (options.SPA) { | ||
cancel(false); | ||
if (!validation) | ||
validation = await validateForm(); | ||
const validationResult = { ...validation, posted: true }; | ||
const result = { | ||
type: validationResult.valid ? 'success' : 'failure', | ||
status: validationResult.valid | ||
? 200 | ||
: typeof options.SPA == 'object' | ||
? options.SPA?.failStatus | ||
: 400 ?? 400, | ||
data: { form: validationResult } | ||
}; | ||
setTimeout(() => validationResponse({ result }), 0); | ||
cancel({ resetTimers: false }); | ||
clientValidationResult(validation); | ||
} | ||
@@ -1198,4 +1212,6 @@ else if (options.dataType === 'json') { | ||
async function validationResponse(event) { | ||
let cancelled = false; | ||
currentRequest = null; | ||
// Check if an error was thrown in hooks, in which case it has no type. | ||
const result = event.result.type | ||
let result = event.result.type | ||
? event.result | ||
@@ -1207,4 +1223,2 @@ : { | ||
}; | ||
currentRequest = null; | ||
let cancelled = false; | ||
const cancel = () => (cancelled = true); | ||
@@ -1217,11 +1231,15 @@ const data = { | ||
}; | ||
// Check for goto to a different route in the events | ||
const unsubCheckforNav = navigating.subscribe(($nav) => { | ||
if (!$nav || $nav.from?.route.id === $nav.to?.route.id) | ||
return; | ||
cancel(); | ||
}); | ||
const unsubCheckforNav = STORYBOOK_MODE | ||
? () => { } | ||
: navigating.subscribe(($nav) => { | ||
// Check for goto to a different route in the events | ||
if (!$nav || $nav.from?.route.id === $nav.to?.route.id) | ||
return; | ||
cancel(); | ||
}); | ||
for (const event of formEvents.onResult) { | ||
await event(data); | ||
} | ||
// In case it was modified in the event | ||
result = data.result; | ||
if (!cancelled) { | ||
@@ -1320,2 +1338,5 @@ if ((result.type === 'success' || result.type == 'failure') && result.data) { | ||
} | ||
else if (STORYBOOK_MODE) { | ||
htmlForm.completed({ cancelled, clearAll: true }); | ||
} | ||
else { | ||
@@ -1322,0 +1343,0 @@ const unsub = navigating.subscribe(($nav) => { |
@@ -90,3 +90,3 @@ import { pathExists, setPaths, traversePath, traversePaths } from './traversal.js'; | ||
traversePaths(New, (error) => { | ||
if (!Array.isArray(error.value)) | ||
if (!Array.isArray(error.value) && error.value !== undefined) | ||
return; | ||
@@ -93,0 +93,0 @@ setPaths(Previous, [error.path], error.value); |
import { SchemaError } from '../errors.js'; | ||
import { assertSchema } from '../utils.js'; | ||
import { merge } from 'ts-deepmerge'; | ||
import { schemaInfo } from './schemaInfo.js'; | ||
@@ -14,4 +15,4 @@ export function defaultValues(schema, isOptional = false, path = []) { | ||
return undefined; | ||
//if (schema.type == 'object') console.log('--- OBJECT ---'); //debug | ||
//else console.dir({ path, schema, isOptional }, { depth: 10 }); //debug | ||
//if (schema.type == 'object') console.log('--- OBJECT ---'); | ||
//else console.dir({ path, schema, isOptional }, { depth: 10 }); | ||
let objectDefaults = undefined; | ||
@@ -52,2 +53,3 @@ // Default takes (early) priority. | ||
}; | ||
let output = {}; | ||
// Check unions first, so default values can take precedence over nullable and optional | ||
@@ -71,2 +73,9 @@ if (!objectDefaults && info.union) { | ||
} | ||
// Objects must have default values to avoid setting undefined properties on nested data | ||
if (info.union.length && info.types[0] == 'object') { | ||
output = | ||
info.union.length > 1 | ||
? merge.withOptions({ allowUndefinedOverrides: true }, ...info.union.map((s) => _defaultValues(s, isOptional, path))) | ||
: _defaultValues(info.union[0], isOptional, path); | ||
} | ||
} | ||
@@ -83,3 +92,2 @@ } | ||
if (info.properties) { | ||
const output = {}; | ||
for (const [key, value] of Object.entries(info.properties)) { | ||
@@ -89,3 +97,3 @@ assertSchema(value, [...path, key]); | ||
? objectDefaults[key] | ||
: _defaultValues(value, !schema.required?.includes(key), [...path, key]); | ||
: _defaultValues(value, !info.required?.includes(key), [...path, key]); | ||
//if (def !== undefined) output[key] = def; | ||
@@ -92,0 +100,0 @@ output[key] = def; |
@@ -1,3 +0,3 @@ | ||
import { SchemaError } from '../errors.js'; | ||
import { assertSchema } from '../utils.js'; | ||
import { merge } from 'ts-deepmerge'; | ||
const conversionFormatTypes = ['unix-time', 'bigint', 'any', 'symbol', 'set']; | ||
@@ -10,4 +10,8 @@ /** | ||
assertSchema(schema, path); | ||
if (!path) | ||
throw new SchemaError('Why?', path); | ||
if (schema.allOf && schema.allOf.length) { | ||
return { | ||
...merge.withOptions({ allowUndefinedOverrides: false }, ...schema.allOf.map((s) => schemaInfo(s, false, []))), | ||
schema | ||
}; | ||
} | ||
const types = schemaTypes(schema, path); | ||
@@ -14,0 +18,0 @@ const array = schema.items && types.includes('array') |
{ | ||
"name": "sveltekit-superforms", | ||
"version": "2.7.0", | ||
"version": "2.8.0", | ||
"author": "Andreas Söderlund <ciscoheat@gmail.com> (https://blog.encodeart.dev)", | ||
@@ -166,3 +166,3 @@ "description": "Making SvelteKit forms a pleasure to use!", | ||
"uuid": "^9.0.1", | ||
"vite": "^5.1.4", | ||
"vite": "^5.1.5", | ||
"vitest": "^1.3.1" | ||
@@ -169,0 +169,0 @@ }, |
259946
5535