From ea758c3c1957f50972e1b804bc279a8adbbffbda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Costa?= Date: Sat, 16 Mar 2024 00:26:58 -0700 Subject: [PATCH 1/3] feat: add support to fastest-validator Summary: Test Plan: --- .gitattributes | 6 ++ README.md | 10 +++ packages/all/package.json | 3 + .../src/__tests__/fastest-validator.test.ts | 70 ++++++++++++++++++ packages/fastest-validator/README.md | 44 +++++++++++ packages/fastest-validator/package.json | 74 +++++++++++++++++++ .../src/__tests__/example.ts | 13 ++++ .../src/__tests__/fastest-validator.test.ts | 66 +++++++++++++++++ .../src/__tests__/tsconfig.json | 5 ++ packages/fastest-validator/src/index.ts | 37 ++++++++++ packages/fastest-validator/src/resolver.ts | 8 ++ packages/fastest-validator/src/validation.ts | 33 +++++++++ packages/fastest-validator/tsconfig.json | 5 ++ packages/main/package.json | 7 ++ .../src/__tests__/fastest-validator.test.ts | 70 ++++++++++++++++++ packages/main/src/adapters.ts | 2 + packages/main/src/selector.ts | 39 +++++++++- packages/main/src/serialization.ts | 1 + packages/main/src/validation.ts | 6 ++ pnpm-lock.yaml | 30 ++++++++ turbo/generators/config.ts | 8 ++ 21 files changed, 535 insertions(+), 2 deletions(-) create mode 100644 packages/all/src/__tests__/fastest-validator.test.ts create mode 100644 packages/fastest-validator/README.md create mode 100644 packages/fastest-validator/package.json create mode 100644 packages/fastest-validator/src/__tests__/example.ts create mode 100644 packages/fastest-validator/src/__tests__/fastest-validator.test.ts create mode 100644 packages/fastest-validator/src/__tests__/tsconfig.json create mode 100644 packages/fastest-validator/src/index.ts create mode 100644 packages/fastest-validator/src/resolver.ts create mode 100644 packages/fastest-validator/src/validation.ts create mode 100644 packages/fastest-validator/tsconfig.json create mode 100644 packages/main/src/__tests__/fastest-validator.test.ts diff --git a/.gitattributes b/.gitattributes index bdd7d48c..7415f784 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,6 +7,7 @@ packages/all/src/__tests__/arktype.test.ts linguist-generated packages/all/src/__tests__/class-validator.test.ts linguist-generated packages/all/src/__tests__/deepkit.test.ts linguist-generated packages/all/src/__tests__/effect.test.ts linguist-generated +packages/all/src/__tests__/fastest-validator.test.ts linguist-generated packages/all/src/__tests__/function.test.ts linguist-generated packages/all/src/__tests__/io-ts.test.ts linguist-generated packages/all/src/__tests__/joi.test.ts linguist-generated @@ -40,6 +41,10 @@ packages/effect/README.md linguist-generated packages/effect/src/__tests__/tsconfig.json linguist-generated packages/effect/src/index.ts linguist-generated packages/effect/tsconfig.json linguist-generated +packages/fastest-validator/README.md linguist-generated +packages/fastest-validator/src/__tests__/tsconfig.json linguist-generated +packages/fastest-validator/src/index.ts linguist-generated +packages/fastest-validator/tsconfig.json linguist-generated packages/function/README.md linguist-generated packages/function/src/__tests__/tsconfig.json linguist-generated packages/function/src/index.ts linguist-generated @@ -61,6 +66,7 @@ packages/main/src/__tests__/arktype.test.ts linguist-generated packages/main/src/__tests__/class-validator.test.ts linguist-generated packages/main/src/__tests__/deepkit.test.ts linguist-generated packages/main/src/__tests__/effect.test.ts linguist-generated +packages/main/src/__tests__/fastest-validator.test.ts linguist-generated packages/main/src/__tests__/function.test.ts linguist-generated packages/main/src/__tests__/io-ts.test.ts linguist-generated packages/main/src/__tests__/joi.test.ts linguist-generated diff --git a/README.md b/README.md index da674b26..bcd59982 100644 --- a/README.md +++ b/README.md @@ -224,6 +224,16 @@ We value flexibility, which is why there are multiple ways of using TypeSchema: @typeschema/runtypes npm downloads + + fastest-validator + GitHub stars + 🧐 + 🧐 + ✅ + 🧐 + @typeschema/fastest-validator + npm downloads + suretype GitHub stars diff --git a/packages/all/package.json b/packages/all/package.json index 58e305b1..65ce4d83 100644 --- a/packages/all/package.json +++ b/packages/all/package.json @@ -17,6 +17,7 @@ "class-validator", "deepkit", "effect", + "fastest-validator", "function", "io-ts", "joi", @@ -78,6 +79,7 @@ "@typeschema/class-validator": "workspace:*", "@typeschema/deepkit": "workspace:*", "@typeschema/effect": "workspace:*", + "@typeschema/fastest-validator": "workspace:*", "@typeschema/function": "workspace:*", "@typeschema/io-ts": "workspace:*", "@typeschema/joi": "workspace:*", @@ -99,6 +101,7 @@ "@deepkit/type-compiler": "^1.0.1-alpha.142", "@effect/schema": "^0.63.2", "effect": "^2.4.1", + "fastest-validator": "^1.17.0", "typia": "^5.5.3", "fp-ts": "^2.16.2", "io-ts": "^2.2.21", diff --git a/packages/all/src/__tests__/fastest-validator.test.ts b/packages/all/src/__tests__/fastest-validator.test.ts new file mode 100644 index 00000000..ac04ea20 --- /dev/null +++ b/packages/all/src/__tests__/fastest-validator.test.ts @@ -0,0 +1,70 @@ +/** + * This file is generated. Do not modify it manually! + */ + +import type {Infer, InferIn} from '..'; + +import {initTRPC} from '@trpc/server'; +import {expectTypeOf} from 'expect-type'; +import {describe, expect, test} from 'vitest'; + +import {assert, validate, wrap} from '..'; + +describe('fastest-validator', () => { + const schema = { + age: 'number', + createdAt: 'string', + email: 'string', + id: 'string', + name: 'string', + updatedAt: 'string', + }; + + const data = { + age: 123, + createdAt: '2021-01-01T00:00:00.000Z', + email: 'john.doe@test.com', + id: 'c4a760a8-dbcf-4e14-9f39-645a8e933d74', + name: 'John Doe', + updatedAt: '2021-01-01T00:00:00.000Z', + }; + const badData = { + age: '123', + createdAt: '2021-01-01T00:00:00.000Z', + email: 'john.doe@test.com', + id: 'c4a760a8-dbcf-4e14-9f39-645a8e933d74', + name: 'John Doe', + updatedAt: '2021-01-01T00:00:00.000Z', + }; + + test('infer', () => { + expectTypeOf>().toEqualTypeOf(); + expectTypeOf>().toEqualTypeOf(); + }); + + test('validate', async () => { + expect(await validate(schema, data)).toStrictEqual({data, success: true}); + expect(await validate(schema, badData)).toStrictEqual({ + issues: [{message: "The 'age' field must be a number.", path: ['age']}], + success: false, + }); + }); + + test('assert', async () => { + expect(await assert(schema, data)).toStrictEqual(data); + await expect(assert(schema, badData)).rejects.toThrow(); + }); + + test('wrap', async () => { + const tRPC = initTRPC.create(); + const router = tRPC.router({ + hello: tRPC.procedure.input(wrap(schema)).query(({input}) => { + expectTypeOf().toEqualTypeOf(); + return input; + }), + }); + const createCaller = tRPC.createCallerFactory(router); + const caller = createCaller({}); + expect(await caller.hello(data)).toStrictEqual(data); + }); +}); diff --git a/packages/fastest-validator/README.md b/packages/fastest-validator/README.md new file mode 100644 index 00000000..3439b0f4 --- /dev/null +++ b/packages/fastest-validator/README.md @@ -0,0 +1,44 @@ + + +TypeSchema +

@typeschema/fastest-validator

+

+ License + Bundle size + npm downloads + GitHub stars +

+

+ Reusable adapter for fastest-validator schemas +
+ https://typeschema.com ✨ +

+ +```ts +import {initTRPC} from '@trpc/server'; + +import {wrap} from '@typeschema/fastest-validator'; + +const schema = {name: 'string'}; + +const t = initTRPC.create(); +const appRouter = t.router({ + hello: t.procedure + .input(wrap(schema)) + .query(({input}) => `Hello, ${(input as any).name}!`), + // ^? unknown +}); + +``` + +Use it directly or through [`@typeschema/main`](https://github.com/decs/typeschema/tree/main/packages/main) + +## Dependencies +- [`fastest-validator`](https://www.npmjs.com/package/fastest-validator): (`^1.17.0`) + +## API + +### Validation +- `wrap(schema)`: Returns the wrapped schema with access to its operations +- `validate(schema, data)`: Returns the validated data or a list of validation issues +- `assert(schema, data)`: Returns the validated data or throws an `AggregateError` diff --git a/packages/fastest-validator/package.json b/packages/fastest-validator/package.json new file mode 100644 index 00000000..4035f209 --- /dev/null +++ b/packages/fastest-validator/package.json @@ -0,0 +1,74 @@ +{ + "//": "This file is partially generated. Only some fields can be modified manually!", + "name": "@typeschema/fastest-validator", + "//version": "This field is manually maintained.", + "version": "0.0.0", + "//description": "This field is manually maintained.", + "description": "Reusable adapter for fastest-validator schemas", + "keywords": [ + "typescript", + "type", + "schema", + "adapter", + "validation", + "inference", + "assert" + ], + "homepage": "https://typeschema.com", + "license": "MIT", + "author": { + "name": "André Costa", + "email": "andrefonsecacosta@gmail.com" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, + "files": [ + "/dist" + ], + "main": "dist/index.js", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.mts", + "default": "./dist/index.mjs" + }, + "require": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + } + }, + "sideEffects": false, + "repository": { + "type": "git", + "url": "https://github.com/decs/typeschema.git" + }, + "scripts": { + "build": "tsup --config ../../tsup.config.ts", + "lint": "eslint src --fix", + "lint:package": "publint && attw --pack", + "test": "vitest --config ../../vitest.config.ts", + "upgrade:deps": "ncu -u --dep=dev,peer --reject ow" + }, + "dependencies": { + "@typeschema/core": "workspace:*" + }, + "//devDependencies": "This field is manually maintained.", + "devDependencies": { + "fastest-validator": "^1.17.0" + }, + "//peerDependencies": "This field is manually maintained.", + "peerDependencies": { + "fastest-validator": "^1.17.0" + }, + "//peerDependenciesMeta": "This field is manually maintained.", + "peerDependenciesMeta": { + "fastest-validator": { + "optional": true + } + } +} diff --git a/packages/fastest-validator/src/__tests__/example.ts b/packages/fastest-validator/src/__tests__/example.ts new file mode 100644 index 00000000..27f44c5a --- /dev/null +++ b/packages/fastest-validator/src/__tests__/example.ts @@ -0,0 +1,13 @@ +import {initTRPC} from '@trpc/server'; + +import {wrap} from '..'; + +const schema = {name: 'string'}; + +const t = initTRPC.create(); +const appRouter = t.router({ + hello: t.procedure + .input(wrap(schema)) + .query(({input}) => `Hello, ${(input as any).name}!`), + // ^? unknown +}); diff --git a/packages/fastest-validator/src/__tests__/fastest-validator.test.ts b/packages/fastest-validator/src/__tests__/fastest-validator.test.ts new file mode 100644 index 00000000..629d8e85 --- /dev/null +++ b/packages/fastest-validator/src/__tests__/fastest-validator.test.ts @@ -0,0 +1,66 @@ +import type {Infer, InferIn} from '..'; + +import {initTRPC} from '@trpc/server'; +import {expectTypeOf} from 'expect-type'; +import {describe, expect, test} from 'vitest'; + +import {assert, validate, wrap} from '..'; + +describe('fastest-validator', () => { + const schema = { + age: 'number', + createdAt: 'string', + email: 'string', + id: 'string', + name: 'string', + updatedAt: 'string', + }; + + const data = { + age: 123, + createdAt: '2021-01-01T00:00:00.000Z', + email: 'john.doe@test.com', + id: 'c4a760a8-dbcf-4e14-9f39-645a8e933d74', + name: 'John Doe', + updatedAt: '2021-01-01T00:00:00.000Z', + }; + const badData = { + age: '123', + createdAt: '2021-01-01T00:00:00.000Z', + email: 'john.doe@test.com', + id: 'c4a760a8-dbcf-4e14-9f39-645a8e933d74', + name: 'John Doe', + updatedAt: '2021-01-01T00:00:00.000Z', + }; + + test('infer', () => { + expectTypeOf>().toEqualTypeOf(); + expectTypeOf>().toEqualTypeOf(); + }); + + test('validate', async () => { + expect(await validate(schema, data)).toStrictEqual({data, success: true}); + expect(await validate(schema, badData)).toStrictEqual({ + issues: [{message: "The 'age' field must be a number.", path: ['age']}], + success: false, + }); + }); + + test('assert', async () => { + expect(await assert(schema, data)).toStrictEqual(data); + await expect(assert(schema, badData)).rejects.toThrow(); + }); + + test('wrap', async () => { + const tRPC = initTRPC.create(); + const router = tRPC.router({ + hello: tRPC.procedure.input(wrap(schema)).query(({input}) => { + expectTypeOf().toEqualTypeOf(); + return input; + }), + }); + const createCaller = tRPC.createCallerFactory(router); + const caller = createCaller({}); + expect(await caller.hello(data)).toStrictEqual(data); + }); +}); diff --git a/packages/fastest-validator/src/__tests__/tsconfig.json b/packages/fastest-validator/src/__tests__/tsconfig.json new file mode 100644 index 00000000..6a86fc8c --- /dev/null +++ b/packages/fastest-validator/src/__tests__/tsconfig.json @@ -0,0 +1,5 @@ +{ + "//": "This file is generated. Do not modify it manually!", + "extends": "../../../../tsconfig.test.json", + "include": ["*.ts"] +} diff --git a/packages/fastest-validator/src/index.ts b/packages/fastest-validator/src/index.ts new file mode 100644 index 00000000..c5a15869 --- /dev/null +++ b/packages/fastest-validator/src/index.ts @@ -0,0 +1,37 @@ +/** + * This file is generated. Do not modify it manually! + */ + +import type { + InputFrom, + OutputFrom, + SchemaFrom, + UnknownIfNever, +} from '@typeschema/core'; + +import { + createAssert, + createValidate, + createWrap, +} from '@typeschema/core'; + +import {AdapterResolver} from './resolver'; +import {validationAdapter} from './validation'; + +export type Schema = SchemaFrom; +export type Infer = UnknownIfNever< + OutputFrom +>; +export type InferIn = UnknownIfNever< + InputFrom +>; + +export const validate = createValidate(validationAdapter); +export const assert = createAssert(validate); +export const wrap = createWrap(assert, validate); + + +export { + AdapterResolver, + validationAdapter, +}; diff --git a/packages/fastest-validator/src/resolver.ts b/packages/fastest-validator/src/resolver.ts new file mode 100644 index 00000000..76a3994f --- /dev/null +++ b/packages/fastest-validator/src/resolver.ts @@ -0,0 +1,8 @@ +import type {IfDefined, Resolver} from '@typeschema/core'; +import type {ValidationSchema} from 'fastest-validator'; + +export interface AdapterResolver extends Resolver { + base: IfDefined; + input: this['schema'] extends this['base'] ? unknown : never; + output: this['schema'] extends this['base'] ? unknown : never; +} diff --git a/packages/fastest-validator/src/validation.ts b/packages/fastest-validator/src/validation.ts new file mode 100644 index 00000000..1736d9d5 --- /dev/null +++ b/packages/fastest-validator/src/validation.ts @@ -0,0 +1,33 @@ +import type {AdapterResolver} from './resolver'; +import type {ValidationAdapter} from '@typeschema/core'; + +import {memoize} from '@typeschema/core'; + +const importValidationModule = memoize(async () => { + const {default: FastestValidator} = await import('fastest-validator'); + return new FastestValidator(); +}); + +export const validationAdapter: ValidationAdapter< + AdapterResolver +> = async schema => { + const fastestValidator = await importValidationModule(); + const validateSchema = fastestValidator.compile(schema); + return async data => { + const result = await validateSchema(data); + if (result === true) { + return { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + data: data as any, + success: true, + }; + } + return { + issues: result.map(({message, field}) => ({ + message: message ?? '', + path: [field], + })), + success: false, + }; + }; +}; diff --git a/packages/fastest-validator/tsconfig.json b/packages/fastest-validator/tsconfig.json new file mode 100644 index 00000000..caf27170 --- /dev/null +++ b/packages/fastest-validator/tsconfig.json @@ -0,0 +1,5 @@ +{ + "//": "This file is generated. Do not modify it manually!", + "extends": "../../tsconfig.json", + "include": ["src"] +} diff --git a/packages/main/package.json b/packages/main/package.json index ed6269a5..a0092fd9 100644 --- a/packages/main/package.json +++ b/packages/main/package.json @@ -17,6 +17,7 @@ "class-validator", "deepkit", "effect", + "fastest-validator", "function", "io-ts", "joi", @@ -85,6 +86,8 @@ "@typeschema/effect": "workspace:*", "@effect/schema": "^0.63.2", "effect": "^2.4.1", + "@typeschema/fastest-validator": "workspace:*", + "fastest-validator": "^1.17.0", "@typeschema/function": "workspace:*", "typia": "^5.5.3", "@typeschema/io-ts": "workspace:*", @@ -124,6 +127,7 @@ "@typeschema/class-validator": "workspace:*", "@typeschema/deepkit": "workspace:*", "@typeschema/effect": "workspace:*", + "@typeschema/fastest-validator": "workspace:*", "@typeschema/function": "workspace:*", "@typeschema/io-ts": "workspace:*", "@typeschema/joi": "workspace:*", @@ -151,6 +155,9 @@ "@typeschema/effect": { "optional": true }, + "@typeschema/fastest-validator": { + "optional": true + }, "@typeschema/function": { "optional": true }, diff --git a/packages/main/src/__tests__/fastest-validator.test.ts b/packages/main/src/__tests__/fastest-validator.test.ts new file mode 100644 index 00000000..ac04ea20 --- /dev/null +++ b/packages/main/src/__tests__/fastest-validator.test.ts @@ -0,0 +1,70 @@ +/** + * This file is generated. Do not modify it manually! + */ + +import type {Infer, InferIn} from '..'; + +import {initTRPC} from '@trpc/server'; +import {expectTypeOf} from 'expect-type'; +import {describe, expect, test} from 'vitest'; + +import {assert, validate, wrap} from '..'; + +describe('fastest-validator', () => { + const schema = { + age: 'number', + createdAt: 'string', + email: 'string', + id: 'string', + name: 'string', + updatedAt: 'string', + }; + + const data = { + age: 123, + createdAt: '2021-01-01T00:00:00.000Z', + email: 'john.doe@test.com', + id: 'c4a760a8-dbcf-4e14-9f39-645a8e933d74', + name: 'John Doe', + updatedAt: '2021-01-01T00:00:00.000Z', + }; + const badData = { + age: '123', + createdAt: '2021-01-01T00:00:00.000Z', + email: 'john.doe@test.com', + id: 'c4a760a8-dbcf-4e14-9f39-645a8e933d74', + name: 'John Doe', + updatedAt: '2021-01-01T00:00:00.000Z', + }; + + test('infer', () => { + expectTypeOf>().toEqualTypeOf(); + expectTypeOf>().toEqualTypeOf(); + }); + + test('validate', async () => { + expect(await validate(schema, data)).toStrictEqual({data, success: true}); + expect(await validate(schema, badData)).toStrictEqual({ + issues: [{message: "The 'age' field must be a number.", path: ['age']}], + success: false, + }); + }); + + test('assert', async () => { + expect(await assert(schema, data)).toStrictEqual(data); + await expect(assert(schema, badData)).rejects.toThrow(); + }); + + test('wrap', async () => { + const tRPC = initTRPC.create(); + const router = tRPC.router({ + hello: tRPC.procedure.input(wrap(schema)).query(({input}) => { + expectTypeOf().toEqualTypeOf(); + return input; + }), + }); + const createCaller = tRPC.createCallerFactory(router); + const caller = createCaller({}); + expect(await caller.hello(data)).toStrictEqual(data); + }); +}); diff --git a/packages/main/src/adapters.ts b/packages/main/src/adapters.ts index 48bc28db..972067bb 100644 --- a/packages/main/src/adapters.ts +++ b/packages/main/src/adapters.ts @@ -6,6 +6,7 @@ import type {AdapterResolver as ArktypeResolver} from '@typeschema/arktype'; import type {AdapterResolver as ClassValidatorResolver} from '@typeschema/class-validator'; import type {AdapterResolver as DeepkitResolver} from '@typeschema/deepkit'; import type {AdapterResolver as EffectResolver} from '@typeschema/effect'; +import type {AdapterResolver as FastestValidatorResolver} from '@typeschema/fastest-validator'; import type {AdapterResolver as FunctionResolver} from '@typeschema/function'; import type {AdapterResolver as IoTsResolver} from '@typeschema/io-ts'; import type {AdapterResolver as JoiResolver} from '@typeschema/joi'; @@ -25,6 +26,7 @@ export type AdapterResolvers = { classValidator: ClassValidatorResolver; deepkit: DeepkitResolver; effect: EffectResolver; + fastestValidator: FastestValidatorResolver; function: FunctionResolver; ioTs: IoTsResolver; joi: JoiResolver; diff --git a/packages/main/src/selector.ts b/packages/main/src/selector.ts index 683e4a13..4e6a4b2d 100644 --- a/packages/main/src/selector.ts +++ b/packages/main/src/selector.ts @@ -41,6 +41,38 @@ function isClassValidatorSchema( ); } +type IsJSONSchema = TSchema extends {type: unknown} + ? true + : TSchema extends {const: unknown} + ? true + : TSchema extends {enum: unknown} + ? true + : TSchema extends {anyOf: unknown} + ? true + : TSchema extends {oneOf: unknown} + ? true + : TSchema extends {allOf: unknown} + ? true + : TSchema extends {not: unknown} + ? true + : TSchema extends {if: unknown} + ? true + : false; +function isJSONSchema( + schema: SchemaFrom, +): schema is SchemaFrom { + return ( + typeof schema === 'object' && + ('type' in schema || + 'const' in schema || + 'enum' in schema || + 'anyOf' in schema || + 'oneOf' in schema || + 'allOf' in schema || + 'not' in schema || + 'if' in schema) + ); +} function notJSON( schema: TSchema, ): Exclude> { @@ -82,7 +114,9 @@ export type Select = ? 'ow' : TSchema extends {toTerminals: unknown} ? 'valita' - : 'json'; + : IsJSONSchema extends true + ? 'json' + : 'fastestValidator'; export const select: < TMap extends { @@ -117,6 +151,7 @@ export const select: < if ('kind' in schema) return is.deepkit(notJSON(schema)); if ('addValidator' in schema) return is.ow(notJSON(schema)); if ('toTerminals' in schema) return is.valita(notJSON(schema)); - return is.json(schema); + if (isJSONSchema(schema)) return is.json(schema); + return is.fastestValidator(schema); } }; diff --git a/packages/main/src/serialization.ts b/packages/main/src/serialization.ts index 4ad52e0b..5aec484c 100644 --- a/packages/main/src/serialization.ts +++ b/packages/main/src/serialization.ts @@ -57,6 +57,7 @@ export const serializationAdapter: SerializationAdapter = selec classValidator: unsupportedAdapter('@typeschema/class-validator'), deepkit: unsupportedAdapter('@typeschema/deepkit'), effect: async schema => (await importEffectSerializationAdapter())(schema), + fastestValidator: unsupportedAdapter('@typeschema/fastest-validator'), function: unsupportedAdapter('@typeschema/function'), ioTs: unsupportedAdapter('@typeschema/io-ts'), joi: async schema => (await importJoiSerializationAdapter())(schema), diff --git a/packages/main/src/validation.ts b/packages/main/src/validation.ts index c524cdc9..9ce525ab 100644 --- a/packages/main/src/validation.ts +++ b/packages/main/src/validation.ts @@ -32,6 +32,11 @@ const importEffectValidationAdapter = memoize(async () => { return validationAdapter; }); +const importFastestValidatorValidationAdapter = memoize(async () => { + const {validationAdapter} = await import('@typeschema/fastest-validator'); + return validationAdapter; +}); + const importFunctionValidationAdapter = memoize(async () => { const {validationAdapter} = await import('@typeschema/function'); return validationAdapter; @@ -102,6 +107,7 @@ export const validationAdapter: ValidationAdapter = select({ classValidator: async schema => (await importClassValidatorValidationAdapter())(schema), deepkit: async schema => (await importDeepkitValidationAdapter())(schema), effect: async schema => (await importEffectValidationAdapter())(schema), + fastestValidator: async schema => (await importFastestValidatorValidationAdapter())(schema), function: async schema => (await importFunctionValidationAdapter())(schema), ioTs: async schema => (await importIoTsValidationAdapter())(schema), joi: async schema => (await importJoiValidationAdapter())(schema), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 278f6684..f4dfd5b7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -242,6 +242,9 @@ importers: '@typeschema/effect': specifier: workspace:* version: link:../effect + '@typeschema/fastest-validator': + specifier: workspace:* + version: link:../fastest-validator '@typeschema/function': specifier: workspace:* version: link:../function @@ -318,6 +321,9 @@ importers: effect: specifier: ^2.4.1 version: 2.4.1 + fastest-validator: + specifier: ^1.17.0 + version: 1.17.0 fp-ts: specifier: ^2.16.2 version: 2.16.2 @@ -416,6 +422,16 @@ importers: specifier: ^2.4.1 version: 2.4.1 + packages/fastest-validator: + dependencies: + '@typeschema/core': + specifier: workspace:* + version: link:../core + devDependencies: + fastest-validator: + specifier: ^1.17.0 + version: 1.17.0 + packages/function: dependencies: '@typeschema/core': @@ -507,6 +523,9 @@ importers: '@typeschema/effect': specifier: workspace:* version: link:../effect + '@typeschema/fastest-validator': + specifier: workspace:* + version: link:../fastest-validator '@typeschema/function': specifier: workspace:* version: link:../function @@ -558,6 +577,9 @@ importers: effect: specifier: ^2.4.1 version: 2.4.1 + fastest-validator: + specifier: ^1.17.0 + version: 1.17.0 fp-ts: specifier: ^2.16.2 version: 2.16.2 @@ -6677,6 +6699,10 @@ packages: engines: {node: '>= 4.9.1'} dev: true + /fastest-validator@1.17.0: + resolution: {integrity: sha512-37U/JDP72QSFqcvNnO81f0Aeu9og+5I3mc55b2v2RbV0S2I7KvQEdBtrFeIvaYVgam1bDUgy9F9AK9HolByogA==} + dev: true + /fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} dependencies: @@ -12343,6 +12369,7 @@ packages: '@typeschema/core': link:packages/core '@typeschema/deepkit': link:packages/deepkit '@typeschema/effect': link:packages/effect + '@typeschema/fastest-validator': link:packages/fastest-validator '@typeschema/function': link:packages/function '@typeschema/io-ts': link:packages/io-ts '@typeschema/joi': link:packages/joi @@ -12368,6 +12395,7 @@ packages: '@typeschema/class-validator': workspace:* '@typeschema/deepkit': workspace:* '@typeschema/effect': workspace:* + '@typeschema/fastest-validator': workspace:* '@typeschema/function': workspace:* '@typeschema/io-ts': workspace:* '@typeschema/joi': workspace:* @@ -12390,6 +12418,8 @@ packages: optional: true '@typeschema/effect': optional: true + '@typeschema/fastest-validator': + optional: true '@typeschema/function': optional: true '@typeschema/io-ts': diff --git a/turbo/generators/config.ts b/turbo/generators/config.ts index f8ade5ee..abdada09 100644 --- a/turbo/generators/config.ts +++ b/turbo/generators/config.ts @@ -296,6 +296,14 @@ export default function generator(plop: PlopTypes.NodePlopAPI): void { name: 'runtypes', url: 'https://github.com/pelotom/runtypes', }, + { + adapter: adapters.find( + adapter => adapter.name === 'fastest-validator', + ), + github: 'icebob/fastest-validator', + name: 'fastest-validator', + url: 'https://github.com/icebob/fastest-validator', + }, { adapter: adapters.find(adapter => adapter.name === 'suretype'), github: 'grantila/suretype', From a7c09b6b899e50e9d69ee1b26f90a057bd1eaaa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Costa?= Date: Sat, 16 Mar 2024 00:27:37 -0700 Subject: [PATCH 2/3] Create ten-dogs-drop.md --- .changeset/ten-dogs-drop.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/ten-dogs-drop.md diff --git a/.changeset/ten-dogs-drop.md b/.changeset/ten-dogs-drop.md new file mode 100644 index 00000000..0615bed8 --- /dev/null +++ b/.changeset/ten-dogs-drop.md @@ -0,0 +1,7 @@ +--- +"@typeschema/all": patch +"@typeschema/fastest-validator": patch +"@typeschema/main": patch +--- + +feat: add support to fastest-validator From 9a098cf5296254985f4ad7957ee3822eb18ca88b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Costa?= Date: Sat, 16 Mar 2024 00:28:20 -0700 Subject: [PATCH 3/3] Update ten-dogs-drop.md --- .changeset/ten-dogs-drop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/ten-dogs-drop.md b/.changeset/ten-dogs-drop.md index 0615bed8..d0f123c4 100644 --- a/.changeset/ten-dogs-drop.md +++ b/.changeset/ten-dogs-drop.md @@ -1,6 +1,6 @@ --- "@typeschema/all": patch -"@typeschema/fastest-validator": patch +"@typeschema/fastest-validator": minor "@typeschema/main": patch ---