|
| 1 | +# 1.0.0-rc.1 |
| 2 | + |
| 3 | +After plenty of work, the first release candidate for **Superforms 1.0** is ready! |
| 4 | + |
| 5 | +First a feature list, so you'll see what's new, then a comprehensive migration guide. |
| 6 | + |
| 7 | +## New and updated features |
| 8 | + |
| 9 | +### Automatic form id |
| 10 | + |
| 11 | +Setting a form `id` for multiple forms is not required anymore when using `use:enhance`, unless the forms are using the same schema. |
| 12 | + |
| 13 | +```diff |
| 14 | +const loginForm = await superValidate(loginSchema, { |
| 15 | +- id: 'loginForm' |
| 16 | +}); |
| 17 | + |
| 18 | +const registerForm = await superValidate(registerSchema, { |
| 19 | +- id: 'registerForm' |
| 20 | +}); |
| 21 | +``` |
| 22 | + |
| 23 | +Without `use:enhance`, an id can be specified in the options or in a hidden form field called `__superform_id`. |
| 24 | + |
| 25 | +For extra safety, a warning will be emitted if identical id's are detected. |
| 26 | + |
| 27 | +### defaultValues |
| 28 | + |
| 29 | +This method will provide you with the default values for a schema. |
| 30 | + |
| 31 | +```ts |
| 32 | +import { defaultValues } from 'sveltekit-superforms/server' |
| 33 | + |
| 34 | +const schema = z.object({ ... }) |
| 35 | +const defaults = defaultValues(schema) |
| 36 | +``` |
| 37 | + |
| 38 | +This was previously an undocumented function called `defaultData`. If you've used it, rename it to `defaultValues`. |
| 39 | + |
| 40 | +### superValidateSync |
| 41 | + |
| 42 | +When using `superValidate` on the client, you previously had to use a `+page.ts` file to call `superValidate`, since it is asynchronous. But now you can import `superValidateSync` and use it in components directly. Can be very convenient in SPA:s. |
| 43 | + |
| 44 | +```svelte |
| 45 | +<script lang="ts"> |
| 46 | + import { schema } from '$lib/schemas'; |
| 47 | + import { superValidateSync, superForm } from 'sveltekit-superforms/client'; |
| 48 | +
|
| 49 | + const validation = superValidateSync(schema); |
| 50 | + const form = superForm(validation); |
| 51 | +</script> |
| 52 | +``` |
| 53 | + |
| 54 | +### String path accessors |
| 55 | + |
| 56 | +When you wanted to set errors, use proxies and nested data in components, the array syntax was a bit clunky. It has now been replaced with a typesafe string path, so you can write it just as you would access an object property: |
| 57 | + |
| 58 | +```diff |
| 59 | +import { setError } from 'sveltekit-superforms/server' |
| 60 | + |
| 61 | +const i = 1; |
| 62 | + |
| 63 | +- setError(form, ['tags', i, 'name'], 'Incorrect name'); |
| 64 | ++ setError(form, `tags[${i}].name`, 'Incorrect name'); |
| 65 | +``` |
| 66 | + |
| 67 | +```diff |
| 68 | +import { intProxy } from 'sveltekit-superforms/client' |
| 69 | + |
| 70 | +const { form } = superForm(data.form); |
| 71 | +- const idProxy = intProxy(form, ['user', 'profile', 'id']); |
| 72 | ++ const idProxy = intProxy(form, 'user.profile.id'); |
| 73 | +``` |
| 74 | + |
| 75 | +# Migration guide |
| 76 | + |
| 77 | +Lists the breaking changes that you need to address to upgrade from v0.8. |
| 78 | + |
| 79 | +The guide is written with the affected methods in the headlines, so you can scan through them and apply the changes if you're using them in your code. |
| 80 | + |
| 81 | +## setError |
| 82 | + |
| 83 | +The `setError` function doesn't handle form-level errors anymore, because it conflicts with client-side validation. Use refine/superRefine on the schema, or the `message` helper instead. |
| 84 | + |
| 85 | +```ts |
| 86 | +const schema = z |
| 87 | + .object({ |
| 88 | + password: z.string().min(8), |
| 89 | + confirmPassword: z.string() |
| 90 | + }) |
| 91 | + .refine((data) => password == confirmPassword, `Passwords doesn't match.`); |
| 92 | +``` |
| 93 | + |
| 94 | +The above will be available on the client as `$errors._errors` as before, and will be removed (or added) upon client-side validation. |
| 95 | + |
| 96 | +```ts |
| 97 | +const form = await superValidate(request, schema); |
| 98 | + |
| 99 | +if (!form.valid) return fail(400, { form }); |
| 100 | + |
| 101 | +if (form.data.password != form.data.confirmPassword) |
| 102 | + return message(form, `Passwords doesn't match`, { status: 400 }); |
| 103 | +``` |
| 104 | + |
| 105 | +Unlike form-level messages, `message` will persist until the next form submission. |
| 106 | + |
| 107 | +## validate, setError, proxy methods (ending with `Proxy`) |
| 108 | + |
| 109 | +`FieldPath` is gone - the above methods are now using a string accessor like `tags[2].id` instead of an array like `['tags', 2, 'id']`. |
| 110 | + |
| 111 | +```diff |
| 112 | +- setError(form, ['tags', i, 'name'], 'Incorrect name'); |
| 113 | ++ setError(form, `tags[${i}].name`, 'Incorrect name'); |
| 114 | +``` |
| 115 | + |
| 116 | +This also applies to generic components, so you should change the type of the field prop, as described on the componentization page: |
| 117 | + |
| 118 | +```svelte |
| 119 | +<script lang="ts"> |
| 120 | + import type { z, AnyZodObject } from 'zod'; |
| 121 | + import type { UnwrapEffects } from 'sveltekit-superforms'; |
| 122 | + import type { SuperForm, StringPath } from 'sveltekit-superforms/client'; |
| 123 | + import { formFieldProxy } from 'sveltekit-superforms/client'; |
| 124 | +
|
| 125 | + type T = $$Generic<AnyZodObject>; |
| 126 | +
|
| 127 | + export let form: SuperForm<UnwrapEffects<T>, unknown>; |
| 128 | + export let field: string & StringPath<z.infer<UnwrapEffects<T>>>; |
| 129 | +
|
| 130 | + const { path, value, errors, constraints } = formFieldProxy(form, field); |
| 131 | +</script> |
| 132 | +``` |
| 133 | + |
| 134 | +## allErrors, firstError |
| 135 | + |
| 136 | +The signature for `allErrors` and `firstError` has changed, to make it easier to group related messages: |
| 137 | + |
| 138 | +```diff |
| 139 | +- { path: string[]; message: string[] } |
| 140 | ++ { path: string; messages: string[] } |
| 141 | +``` |
| 142 | + |
| 143 | +The path follows the same format as the string accessor path above. |
| 144 | + |
| 145 | +```svelte |
| 146 | +{#if $allErrors.length} |
| 147 | + <ul> |
| 148 | + {#each $allErrors as error} |
| 149 | + <li> |
| 150 | + <b>{error.path}:</b> |
| 151 | + {error.messages} |
| 152 | + </li> |
| 153 | + {/each} |
| 154 | + </ul> |
| 155 | +{/if} |
| 156 | +``` |
| 157 | + |
| 158 | +## defaultData |
| 159 | + |
| 160 | +The `defaultData` function is now called `defaultValues`. |
| 161 | + |
| 162 | +```diff |
| 163 | +- import { defaultData } from 'sveltekit-superforms/server` |
| 164 | ++ import { defaultValues } from 'sveltekit-superforms/server` |
| 165 | +``` |
| 166 | + |
| 167 | +## meta |
| 168 | + |
| 169 | +The virtually unused `meta` store has been removed. Use the Zod schema directly instead for reflection. |
| 170 | + |
| 171 | +## Client options |
| 172 | + |
| 173 | +The following `superForm` options have changed: |
| 174 | + |
| 175 | +### resetForm |
| 176 | + |
| 177 | +Resetting the form now works without `use:enhance`! Just set the option to `true` and it will work. |
| 178 | + |
| 179 | +If you have used the function version of `resetForm`, `() => boolean`, it is now synchronous. |
| 180 | + |
| 181 | +### errorSelector |
| 182 | + |
| 183 | +The default `errorSelector` is now `[data-invalid],[aria-invalid="true"]`, so if you want to be more accessibility-friendly: |
| 184 | + |
| 185 | +```diff |
| 186 | +<input |
| 187 | + name="name" |
| 188 | + bind:value={$form.name} |
| 189 | +- data-invalid={$errors.name} |
| 190 | ++ aria-invalid={$errors.name ? 'true' : undefined} |
| 191 | +/> |
| 192 | +``` |
| 193 | + |
| 194 | +## Server options |
| 195 | + |
| 196 | +The following `superValidate` options have changed: |
| 197 | + |
| 198 | +### noErrors |
| 199 | + |
| 200 | +`noErrors` is removed from the options. Use `errors` instead to determine if errors should be added or not to the validation. |
| 201 | + |
| 202 | +```ts |
| 203 | +// Add errors to an empty form |
| 204 | +const form = await superValidate(schema, { errors: true }); |
| 205 | +``` |
| 206 | + |
| 207 | +The [changelog](https://github.com/ciscoheat/sveltekit-superforms/blob/main/CHANGELOG.md) has a full list of changes that aren't breaking. So please try this release candidate, and let me know in a [Github issue](https://github.com/ciscoheat/sveltekit-superforms/issues) or on [Discord](https://discord.gg/AptebvVuhB) if you find some problem. Thank you for helping out towards 1.0! |
0 commit comments