Skip to content

Commit bcce03d

Browse files
committed
Added arrayProxy.
1 parent 66f6934 commit bcce03d

File tree

3 files changed

+41
-20
lines changed

3 files changed

+41
-20
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12-
- Added `FormPathArrays` type, enumerating all arrays in an object as string accessors.
12+
- Added `arrayProxy`, for proxying arrays and their errors in the form data.
13+
- Added `FormPathArrays` type, enumerating all arrays in an object as string accessors. Used to access `arrayProxy` in a type-safe manner.
1314

1415
## [1.9.0] - 2023-10-31
1516

src/lib/client/proxies.ts

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import {
1313
type FormPathLeaves,
1414
type FormPathType
1515
} from '../stringPath.js';
16-
import type { ZodValidation } from '../index.js';
16+
import type { FormPathArrays, ZodValidation } from '../index.js';
1717

1818
type DefaultOptions = {
1919
trueStringValue: string;
@@ -233,12 +233,33 @@ function _stringProxy<
233233
};
234234
}
235235

236+
export function arrayProxy<
237+
T extends ZodValidation<AnyZodObject>,
238+
Path extends FormPathArrays<z.infer<UnwrapEffects<T>>>
239+
>(
240+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
241+
superForm: SuperForm<T, any>,
242+
path: Path
243+
): {
244+
path: Path;
245+
value: Writable<FormPathType<z.infer<UnwrapEffects<T>>, Path>>;
246+
errors: Writable<string[] | undefined>;
247+
} {
248+
return {
249+
path,
250+
value: fieldProxy(superForm.form, path),
251+
errors: fieldProxy(
252+
superForm.errors,
253+
`${path}._errors` as any
254+
) as Writable<string[] | undefined>
255+
};
256+
}
236257
export function formFieldProxy<
237258
T extends ZodValidation<AnyZodObject>,
238259
Path extends FormPathLeaves<z.infer<UnwrapEffects<T>>>
239260
>(
240261
// eslint-disable-next-line @typescript-eslint/no-explicit-any
241-
form: SuperForm<T, any>,
262+
superForm: SuperForm<T, any>,
242263
path: Path
243264
): {
244265
path: Path;
@@ -253,19 +274,19 @@ export function formFieldProxy<
253274
.filter((p) => isNaN(parseInt(String(p))))
254275
.join('.');
255276

256-
const taintedProxy = derived<typeof form.tainted, boolean | undefined>(
257-
form.tainted,
258-
($tainted) => {
259-
if (!$tainted) return $tainted;
260-
const taintedPath = traversePath($tainted, path2);
261-
return taintedPath ? taintedPath.value : undefined;
262-
}
263-
);
277+
const taintedProxy = derived<
278+
typeof superForm.tainted,
279+
boolean | undefined
280+
>(superForm.tainted, ($tainted) => {
281+
if (!$tainted) return $tainted;
282+
const taintedPath = traversePath($tainted, path2);
283+
return taintedPath ? taintedPath.value : undefined;
284+
});
264285

265286
const tainted = {
266287
subscribe: taintedProxy.subscribe,
267288
update(upd: Updater<boolean | undefined>) {
268-
form.tainted.update(($tainted) => {
289+
superForm.tainted.update(($tainted) => {
269290
if (!$tainted) $tainted = {};
270291
const output = traversePath($tainted, path2, (path) => {
271292
if (!path.value) path.parent[path.key] = {};
@@ -276,7 +297,7 @@ export function formFieldProxy<
276297
});
277298
},
278299
set(value: boolean | undefined) {
279-
form.tainted.update(($tainted) => {
300+
superForm.tainted.update(($tainted) => {
280301
if (!$tainted) $tainted = {};
281302
const output = traversePath($tainted, path2, (path) => {
282303
if (!path.value) path.parent[path.key] = {};
@@ -290,12 +311,12 @@ export function formFieldProxy<
290311

291312
return {
292313
path,
293-
value: fieldProxy(form.form, path),
294-
errors: fieldProxy(form.errors, path) as unknown as Writable<
314+
value: fieldProxy(superForm.form, path),
315+
errors: fieldProxy(superForm.errors, path) as unknown as Writable<
295316
string[] | undefined
296317
>,
297318
constraints: fieldProxy(
298-
form.constraints,
319+
superForm.constraints,
299320
constraintsPath as never
300321
) as Writable<InputConstraint | undefined>,
301322
tainted

src/routes/tests/array-component/AutoComplete.svelte

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,15 @@
66
<script lang="ts" generics="T extends AnyZodObject">
77
import type { z } from 'zod';
88
import type { ZodValidation, FormPathArrays } from '$lib';
9-
import type { Writable } from 'svelte/store';
10-
import { fieldProxy, type SuperForm } from '$lib/client';
9+
import type { SuperForm } from '$lib/client';
10+
import { arrayProxy } from '$lib/client/proxies';
1111
1212
export let form: SuperForm<ZodValidation<T>, unknown>;
1313
export let field: FormPathArrays<z.infer<T>>;
1414
export let options: { value: string; label: string }[];
1515
export let label = '';
1616
17-
const value = fieldProxy(form.form, field) as Writable<unknown[]>;
18-
const errors = fieldProxy(form.errors, `${field}._errors` as any);
17+
const { value, errors } = arrayProxy(form, field);
1918
</script>
2019

2120
{#if label}<label for={field}>{label}</label>{/if}

0 commit comments

Comments
 (0)