From 869104b15ebc667d75b3fb6173eb9780c5105dee Mon Sep 17 00:00:00 2001 From: David Roizenman Date: Mon, 18 Nov 2024 15:41:49 -0800 Subject: [PATCH] fix(arktype): support JSON schema serialization --- .changeset/friendly-dogs-pay.md | 5 +++++ README.md | 2 +- packages/arktype/README.md | 3 +++ packages/arktype/src/index.ts | 4 ++++ packages/arktype/src/serialization.ts | 9 +++++++++ packages/main/src/serialization.ts | 7 ++++++- 6 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 .changeset/friendly-dogs-pay.md create mode 100644 packages/arktype/src/serialization.ts diff --git a/.changeset/friendly-dogs-pay.md b/.changeset/friendly-dogs-pay.md new file mode 100644 index 00000000..5c4d120f --- /dev/null +++ b/.changeset/friendly-dogs-pay.md @@ -0,0 +1,5 @@ +--- +'@typeschema/arktype': minor +--- + +support JSON schema serialization diff --git a/README.md b/README.md index 53023772..60185f58 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ We value flexibility, which is why there are multiple ways of using TypeSchema: ✅ ✅ ✅ - 🧐 + ✅ @typeschema/arktype npm downloads diff --git a/packages/arktype/README.md b/packages/arktype/README.md index 6719a088..2e7474a8 100644 --- a/packages/arktype/README.md +++ b/packages/arktype/README.md @@ -47,3 +47,6 @@ Use it directly or through [`@typeschema/main`](https://github.com/decs/typesche - `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` + +### Serialization +- `toJSONSchema(schema)`: Converts the schema into the equivalent JSON schema diff --git a/packages/arktype/src/index.ts b/packages/arktype/src/index.ts index c5a15869..9a0904c4 100644 --- a/packages/arktype/src/index.ts +++ b/packages/arktype/src/index.ts @@ -13,10 +13,12 @@ import { createAssert, createValidate, createWrap, + createToJSONSchema, } from '@typeschema/core'; import {AdapterResolver} from './resolver'; import {validationAdapter} from './validation'; +import {serializationAdapter} from './serialization'; export type Schema = SchemaFrom; export type Infer = UnknownIfNever< @@ -30,8 +32,10 @@ export const validate = createValidate(validationAdapter); export const assert = createAssert(validate); export const wrap = createWrap(assert, validate); +export const toJSONSchema = createToJSONSchema(serializationAdapter); export { AdapterResolver, validationAdapter, + serializationAdapter, }; diff --git a/packages/arktype/src/serialization.ts b/packages/arktype/src/serialization.ts new file mode 100644 index 00000000..e05df56a --- /dev/null +++ b/packages/arktype/src/serialization.ts @@ -0,0 +1,9 @@ +import type {AdapterResolver} from './resolver'; +import type {SerializationAdapter} from '@typeschema/core'; + +export const serializationAdapter: SerializationAdapter< + AdapterResolver +> = async schema => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return schema.toJsonSchema() as Promise; +}; diff --git a/packages/main/src/serialization.ts b/packages/main/src/serialization.ts index a232a999..c495daab 100644 --- a/packages/main/src/serialization.ts +++ b/packages/main/src/serialization.ts @@ -12,6 +12,11 @@ import {memoize, unsupportedAdapter} from '@typeschema/core'; import {select} from './selector'; +const importArktypeSerializationAdapter = memoize(async () => { + const {serializationAdapter} = await import('@typeschema/arktype'); + return serializationAdapter; +}); + const importEffectSerializationAdapter = memoize(async () => { const {serializationAdapter} = await import('@typeschema/effect'); return serializationAdapter; @@ -53,7 +58,7 @@ const importZodSerializationAdapter = memoize(async () => { }); export const serializationAdapter: SerializationAdapter = select({ - arktype: unsupportedAdapter('@typeschema/arktype'), + arktype: async schema => (await importArktypeSerializationAdapter())(schema), classValidator: unsupportedAdapter('@typeschema/class-validator'), deepkit: unsupportedAdapter('@typeschema/deepkit'), effect: async schema => (await importEffectSerializationAdapter())(schema),