Skip to content

Commit 5041414

Browse files
committed
Class-validator adapter!
1 parent 7b5d3c5 commit 5041414

File tree

7 files changed

+128
-19
lines changed

7 files changed

+128
-19
lines changed

src/lib/adapters/adapters.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export type InferIn<T extends Schema> = NonNullable<InferInSchema<T>>;
2020

2121
export type ValidationLibrary =
2222
| 'arktype'
23-
| 'classValidator'
23+
| 'classvalidator'
2424
| 'custom'
2525
| 'joi'
2626
| 'superform'

src/lib/adapters/class-validator.ts renamed to src/lib/adapters/classvalidator.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,24 @@ import {
66
type InferIn,
77
type ValidationResult,
88
type ClientValidationAdapter,
9-
type RequiredDefaultsOptions,
9+
type RequiredDefaultsOptions
1010
} from './adapters.js';
1111
import { memoize } from '$lib/memoize.js';
12+
import type { Schema } from '@typeschema/class-validator';
1213

13-
import {
14-
validate as classValidatorValidate,
15-
type Schema
16-
} from '@typeschema/class-validator';
14+
async function modules() {
15+
const { validate } = await import(/* webpackIgnore: true */ '@typeschema/class-validator');
16+
return { validate };
17+
}
18+
19+
const fetchModule = /* @__PURE__ */ memoize(modules);
1720

1821
async function validate<T extends Schema>(
1922
schema: T,
2023
data: unknown
2124
): Promise<ValidationResult<Infer<T>>> {
22-
const result = await classValidatorValidate<T>(schema, data);
25+
const { validate } = await fetchModule();
26+
const result = await validate<T>(schema, data);
2327
if (result.success) {
2428
return {
2529
data: result.data as Infer<T>,
@@ -35,26 +39,26 @@ async function validate<T extends Schema>(
3539
};
3640
}
3741

38-
function _classValidator<T extends Schema>(
42+
function _classvalidator<T extends Schema>(
3943
schema: T,
4044
options: RequiredDefaultsOptions<Infer<T>>
4145
): ValidationAdapter<Infer<T>, InferIn<T>> {
4246
return createAdapter({
43-
superFormValidationLibrary: 'classValidator',
47+
superFormValidationLibrary: 'classvalidator',
4448
validate: async (data: unknown) => validate(schema, data),
4549
jsonSchema: createJsonSchema(options),
4650
defaults: options.defaults
4751
});
4852
}
4953

50-
function _classValidatorClient<T extends Schema>(
54+
function _classvalidatorClient<T extends Schema>(
5155
schema: T
5256
): ClientValidationAdapter<Infer<T>, InferIn<T>> {
5357
return {
54-
superFormValidationLibrary: 'classValidator',
58+
superFormValidationLibrary: 'classvalidator',
5559
validate: async (data) => validate(schema, data)
5660
};
5761
}
5862

59-
export const classValidator = /* @__PURE__ */ memoize(_classValidator);
60-
export const classValidatorClient = /* @__PURE__ */ memoize(_classValidatorClient);
63+
export const classvalidator = /* @__PURE__ */ memoize(_classvalidator);
64+
export const classvalidatorClient = /* @__PURE__ */ memoize(_classvalidatorClient);

src/lib/adapters/typeSchema.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { Type } from 'arktype';
33
import type { AnySchema } from 'joi';
44
import type {
55
Infer as ClassValidatorInfer,
6-
InferIn as ClassValidatorInferIn,
6+
InferIn as ClassValidatorInferIn,
77
Schema as ClassValidatorSchema
88
} from '@typeschema/class-validator';
99

@@ -80,7 +80,9 @@ interface ArkTypeResolver extends Resolver {
8080

8181
interface ClassValidatorResolver extends Resolver {
8282
base: ClassValidatorSchema;
83-
input: this['schema'] extends ClassValidatorSchema ? ClassValidatorInferIn<this['schema']> : never;
83+
input: this['schema'] extends ClassValidatorSchema
84+
? ClassValidatorInferIn<this['schema']>
85+
: never;
8486
output: this['schema'] extends ClassValidatorSchema ? ClassValidatorInfer<this['schema']> : never;
8587
}
8688

@@ -191,7 +193,7 @@ interface RuntypesResolver extends Resolver {
191193

192194
type Registry = {
193195
arktype: ArkTypeResolver;
194-
classValidator: ClassValidatorResolver;
196+
classvalidator: ClassValidatorResolver;
195197
custom: CustomResolver;
196198
joi: JoiResolver;
197199
typebox: TypeBoxResolver;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { classvalidator } from '$lib/adapters/classvalidator.js';
2+
import { message, superValidate } from '$lib/server/index.js';
3+
import { schema } from './schema.js';
4+
import { fail } from '@sveltejs/kit';
5+
6+
const defaults = new schema();
7+
8+
export const load = async () => {
9+
const form = await superValidate(classvalidator(schema, { defaults }));
10+
return { form };
11+
};
12+
13+
export const actions = {
14+
default: async ({ request }) => {
15+
const formData = await request.formData();
16+
console.log(formData);
17+
18+
const form = await superValidate(formData, classvalidator(schema, { defaults }));
19+
console.log(form);
20+
21+
if (!form.valid) return fail(400, { form });
22+
23+
return message(form, 'Posted OK!');
24+
}
25+
};
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<script lang="ts">
2+
import { classvalidatorClient } from '$lib/adapters/classvalidator.js';
3+
import { superForm } from '$lib/client/index.js';
4+
import SuperDebug from '$lib/client/SuperDebug.svelte';
5+
import { schema } from './schema.js';
6+
7+
export let data;
8+
9+
const { form, errors, tainted, message, enhance } = superForm(data.form, {
10+
taintedMessage: false,
11+
validators: classvalidatorClient(schema)
12+
//dataType: 'json',
13+
});
14+
</script>
15+
16+
<SuperDebug data={{ $form, $errors, $tainted }} />
17+
18+
{#if $message}<h4>{$message}</h4>{/if}
19+
20+
<form method="POST" use:enhance>
21+
<label>
22+
Name: <input
23+
name="name"
24+
bind:value={$form.name}
25+
aria-invalid={$errors.name ? 'true' : undefined}
26+
/>
27+
{#if $errors.name}<span class="invalid">{$errors.name}</span>{/if}
28+
</label>
29+
<label>
30+
Email: <input
31+
name="email"
32+
bind:value={$form.email}
33+
aria-invalid={$errors.email ? 'true' : undefined}
34+
/>
35+
{#if $errors.email}<span class="invalid">{$errors.email}</span>{/if}
36+
</label>
37+
<div>
38+
<button>Submit</button>
39+
</div>
40+
</form>
41+
42+
<style lang="scss">
43+
form {
44+
margin: 2rem 0;
45+
46+
input {
47+
background-color: #dedede;
48+
}
49+
50+
.invalid {
51+
color: crimson;
52+
}
53+
}
54+
</style>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { IsEmail, IsString, MinLength } from 'class-validator';
2+
3+
class ClassValidatorSchema {
4+
@IsString()
5+
@MinLength(2)
6+
name: string = '';
7+
8+
@IsString()
9+
@IsEmail()
10+
email: string = '';
11+
}
12+
13+
export const schema = ClassValidatorSchema;

src/tests/superValidate.test.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,19 @@ import { z, type ZodErrorMap } from 'zod';
2323
import { valibot } from '$lib/adapters/valibot.js';
2424
import * as v from 'valibot';
2525

26-
import { classValidator } from '$lib/adapters/class-validator.js';
27-
import { ArrayMinSize, IsOptional, IsString, IsEmail, IsArray, MinLength, IsInt, Min, IsDate, Matches } from 'class-validator';
26+
import { classvalidator } from '$lib/adapters/classvalidator.js';
27+
import {
28+
ArrayMinSize,
29+
IsOptional,
30+
IsString,
31+
IsEmail,
32+
IsArray,
33+
MinLength,
34+
IsInt,
35+
Min,
36+
IsDate,
37+
Matches
38+
} from 'class-validator';
2839

2940
//import { ajv } from '$lib/adapters/ajv.js';
3041
//import type { JSONSchema } from '$lib/jsonSchema/index.js';
@@ -500,7 +511,7 @@ describe('class-validator', () => {
500511
extra: string | null = null;
501512
}
502513

503-
const adapter = classValidator(ClassValidatorSchema, { defaults });
514+
const adapter = classvalidator(ClassValidatorSchema, { defaults });
504515
schemaTest(adapter, ['email', 'date', 'nospace', 'tags'], 'simple');
505516
});
506517

0 commit comments

Comments
 (0)