Skip to content

Commit

Permalink
refactor: improve adapter selector
Browse files Browse the repository at this point in the history
Summary:

Test Plan:
  • Loading branch information
decs committed Mar 9, 2024
1 parent af243ef commit 2fecd93
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 51 deletions.
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export {
IfDefined,
memoize,
memoizeWithKey,
Selector,
UnknownIfNever,
unsupportedAdapter,
} from './utils';
Expand Down
12 changes: 12 additions & 0 deletions packages/core/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,15 @@ export function unsupportedAdapter<TResolver extends Resolver>(
throw new Error(`This feature is unsupported for ${adapterName}`);
};
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface Selector<T extends Record<string, any>> {
value: T[keyof T];
kind: keyof T;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
fn: <TMap extends {[K in keyof T]: (value: T[K]) => any}>(
map: TMap,
) => <U extends T[keyof T]>(
value: U,
) => ReturnType<TMap[(this & {value: U})['kind']]>;
}
12 changes: 9 additions & 3 deletions packages/main/src/resolver.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {AdapterResolvers} from './adapters';
import type {Select} from './selector';
import type {SchemaKind} from './selector';
import type {
InputFrom,
OutputFrom,
Expand All @@ -11,6 +11,12 @@ export interface AdapterResolver extends Resolver {
base: {
[TModule in keyof AdapterResolvers]: SchemaFrom<AdapterResolvers[TModule]>;
}[keyof AdapterResolvers];
input: InputFrom<AdapterResolvers[Select<this['schema']>], this['schema']>;
output: OutputFrom<AdapterResolvers[Select<this['schema']>], this['schema']>;
input: InputFrom<
AdapterResolvers[SchemaKind<this['schema']>],
this['schema']
>;
output: OutputFrom<
AdapterResolvers[SchemaKind<this['schema']>],
this['schema']
>;
}
79 changes: 31 additions & 48 deletions packages/main/src/selector.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {AdapterResolvers} from './adapters';
import type {AdapterResolver} from './resolver';
import type {Kind} from '@sinclair/typebox';
import type {IfDefined, SchemaFrom} from '@typeschema/core';
import type {IfDefined, SchemaFrom, Selector} from '@typeschema/core';
import type {CoreValidator} from 'suretype';

type IsTypeboxSchema<TSchema> = [IfDefined<typeof Kind>] extends [never]
Expand Down Expand Up @@ -48,54 +48,37 @@ function notJSON<TSchema>(
return schema as any;
}

export type Select<TSchema> =
// eslint-disable-next-line @typescript-eslint/ban-types
TSchema extends Function
? TSchema extends {assert: unknown}
? 'arktype'
: IsClassValidatorSchema<TSchema> extends true
? 'classValidator'
: 'function'
: IsTypeboxSchema<TSchema> extends true
? 'typebox'
: IsSuretypeSchema<TSchema> extends true
? 'suretype'
: TSchema extends {__isYupSchema__: unknown}
? 'yup'
: TSchema extends {_def: unknown}
? 'zod'
: TSchema extends {async: unknown}
? 'valibot'
: TSchema extends {refiner: unknown}
? 'superstruct'
: TSchema extends {_flags: unknown}
? 'joi'
: TSchema extends {encode: unknown}
? 'ioTs'
: TSchema extends {reflect: unknown}
? 'runtypes'
: TSchema extends {ast: unknown}
? 'effect'
: TSchema extends {kind: unknown}
? 'deepkit'
: TSchema extends {addValidator: unknown}
? 'ow'
: TSchema extends {toTerminals: unknown}
? 'valita'
: 'json';
interface SchemaSelector
extends Selector<{
[TModule in keyof AdapterResolvers]: SchemaFrom<AdapterResolvers[TModule]>;
}> {
// prettier-ignore
kind:
// eslint-disable-next-line @typescript-eslint/ban-types
this['value'] extends Function
? this['value'] extends {assert: unknown} ? 'arktype'
: IsClassValidatorSchema<this['value']> extends true ? 'classValidator'
: 'function'
: this['value'] extends object
? IsTypeboxSchema<this['value']> extends true ? 'typebox'
: IsSuretypeSchema<this['value']> extends true ? 'suretype'
: this['value'] extends {__isYupSchema__: unknown} ? 'yup'
: this['value'] extends {_def: unknown} ? 'zod'
: this['value'] extends {async: unknown} ? 'valibot'
: this['value'] extends {refiner: unknown} ? 'superstruct'
: this['value'] extends {_flags: unknown} ? 'joi'
: this['value'] extends {encode: unknown} ? 'ioTs'
: this['value'] extends {reflect: unknown} ? 'runtypes'
: this['value'] extends {ast: unknown} ? 'effect'
: this['value'] extends {kind: unknown} ? 'deepkit'
: this['value'] extends {addValidator: unknown} ? 'ow'
: this['value'] extends {toTerminals: unknown} ? 'valita'
: 'json'
: never;
}
export type SchemaKind<T> = (SchemaSelector & {value: T})['kind'];

export const select: <
TMap extends {
[TModule in keyof AdapterResolvers]: (
schema: SchemaFrom<AdapterResolvers[TModule]>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
) => any;
},
>(
is: TMap,
) => <TSchema extends SchemaFrom<AdapterResolver>>(
schema: TSchema,
) => ReturnType<TMap[Select<TSchema>]> =
export const select: SchemaSelector['fn'] =
/* @__NO_SIDE_EFFECTS__ */
is => schema => {
switch (typeof schema) {
Expand Down

0 comments on commit 2fecd93

Please sign in to comment.