mirror of
https://github.com/pocket-id/pocket-id.git
synced 2026-03-31 19:56:35 +00:00
refactor: upgrade to Zod v4 (#623)
This commit is contained in:
@@ -8,16 +8,18 @@
|
||||
import { LucideMinus, LucidePlus } from '@lucide/svelte';
|
||||
import type { Snippet } from 'svelte';
|
||||
import type { HTMLAttributes } from 'svelte/elements';
|
||||
import { z } from 'zod/v4';
|
||||
|
||||
let {
|
||||
client,
|
||||
federatedIdentities = $bindable([]),
|
||||
error = $bindable(null),
|
||||
errors,
|
||||
...restProps
|
||||
}: HTMLAttributes<HTMLDivElement> & {
|
||||
client?: OidcClient;
|
||||
federatedIdentities: OidcClientFederatedIdentity[];
|
||||
error?: string | null;
|
||||
errors?: z.core.$ZodIssue[];
|
||||
|
||||
children?: Snippet;
|
||||
} = $props();
|
||||
|
||||
@@ -47,6 +49,13 @@
|
||||
[field]: value
|
||||
};
|
||||
}
|
||||
|
||||
function getFieldError(index: number, field: keyof OidcClientFederatedIdentity): string | null {
|
||||
console.log(federatedIdentities)
|
||||
if (!errors) return null;
|
||||
const path = [index, field];
|
||||
return errors?.filter((e) => e.path[0] == path[0] && e.path[1] == path[1])[0]?.message;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div {...restProps}>
|
||||
@@ -76,8 +85,11 @@
|
||||
placeholder="https://example.com/"
|
||||
value={identity.issuer}
|
||||
oninput={(e) => updateFederatedIdentity(i, 'issuer', e.currentTarget.value)}
|
||||
required
|
||||
aria-invalid={!!getFieldError(i, 'issuer')}
|
||||
/>
|
||||
{#if getFieldError(i, 'issuer')}
|
||||
<p class="text-destructive mt-1 text-xs">{getFieldError(i, 'issuer')}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -87,7 +99,11 @@
|
||||
placeholder="Defaults to the client ID: {client?.id}"
|
||||
value={identity.subject || ''}
|
||||
oninput={(e) => updateFederatedIdentity(i, 'subject', e.currentTarget.value)}
|
||||
aria-invalid={!!getFieldError(i, 'subject')}
|
||||
/>
|
||||
{#if getFieldError(i, 'subject')}
|
||||
<p class="text-destructive mt-1 text-xs">{getFieldError(i, 'subject')}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -97,7 +113,11 @@
|
||||
placeholder="Defaults to the Pocket ID URL"
|
||||
value={identity.audience || ''}
|
||||
oninput={(e) => updateFederatedIdentity(i, 'audience', e.currentTarget.value)}
|
||||
aria-invalid={!!getFieldError(i, 'audience')}
|
||||
/>
|
||||
{#if getFieldError(i, 'audience')}
|
||||
<p class="text-destructive mt-1 text-xs">{getFieldError(i, 'audience')}</p>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -107,7 +127,11 @@
|
||||
placeholder="Defaults to {identity.issuer || '<issuer>'}/.well-known/jwks.json"
|
||||
value={identity.jwks || ''}
|
||||
oninput={(e) => updateFederatedIdentity(i, 'jwks', e.currentTarget.value)}
|
||||
aria-invalid={!!getFieldError(i, 'jwks')}
|
||||
/>
|
||||
{#if getFieldError(i, 'jwks')}
|
||||
<p class="text-destructive mt-1 text-xs">{getFieldError(i, 'jwks')}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -115,10 +139,6 @@
|
||||
</div>
|
||||
</FormInput>
|
||||
|
||||
{#if error}
|
||||
<p class="text-destructive mt-1 text-xs">{error}</p>
|
||||
{/if}
|
||||
|
||||
<Button class="mt-3" variant="secondary" size="sm" onclick={addFederatedIdentity} type="button">
|
||||
<LucidePlus class="mr-1 size-4" />
|
||||
{federatedIdentities.length === 0
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
import { cn } from '$lib/utils/style';
|
||||
import { LucideChevronDown } from '@lucide/svelte';
|
||||
import { slide } from 'svelte/transition';
|
||||
import { z } from 'zod';
|
||||
import { z } from 'zod/v4';
|
||||
import FederatedIdentitiesInput from './federated-identities-input.svelte';
|
||||
import OidcCallbackUrlInput from './oidc-callback-url-input.svelte';
|
||||
|
||||
@@ -50,17 +50,17 @@
|
||||
credentials: z.object({
|
||||
federatedIdentities: z.array(
|
||||
z.object({
|
||||
issuer: z.string().url(),
|
||||
issuer: z.url(),
|
||||
subject: z.string().optional(),
|
||||
audience: z.string().optional(),
|
||||
jwks: z.string().url().optional().or(z.literal(''))
|
||||
jwks: z.url().optional().or(z.literal(''))
|
||||
})
|
||||
)
|
||||
})
|
||||
});
|
||||
|
||||
type FormSchema = typeof formSchema;
|
||||
const { inputs, ...form } = createForm<FormSchema>(formSchema, client);
|
||||
const { inputs, errors, ...form } = createForm<FormSchema>(formSchema, client);
|
||||
|
||||
async function onSubmit() {
|
||||
const data = form.validate();
|
||||
@@ -91,6 +91,15 @@
|
||||
logo = null;
|
||||
logoDataURL = null;
|
||||
}
|
||||
|
||||
function getFederatedIdentityErrors(errors: z.ZodError<any> | undefined) {
|
||||
return errors?.issues
|
||||
.filter((e) => e.path[0] == 'credentials' && e.path[1] == 'federatedIdentities')
|
||||
.map((e) => {
|
||||
e.path.splice(0, 2);
|
||||
return e;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<form onsubmit={preventDefault(onSubmit)}>
|
||||
@@ -159,7 +168,7 @@
|
||||
<FederatedIdentitiesInput
|
||||
client={existingClient}
|
||||
bind:federatedIdentities={$inputs.credentials.value.federatedIdentities}
|
||||
bind:error={$inputs.credentials.error}
|
||||
errors={getFederatedIdentityErrors($errors)}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
Reference in New Issue
Block a user