Skip to content

Commit

Permalink
Merge pull request #156 from ThomasAribart/use-caps-maj-instead-of-fi…
Browse files Browse the repository at this point in the history
…rst-letter

Use caps maj instead of first letter
  • Loading branch information
ThomasAribart authored Aug 10, 2023
2 parents 8f57a05 + 45b1d5b commit 71b0de8
Show file tree
Hide file tree
Showing 37 changed files with 630 additions and 503 deletions.
104 changes: 57 additions & 47 deletions src/definitions/extendedJsonSchema7.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { $JSONSchema7 } from "./jsonSchema7";
export type JSONSchema7Extension = Record<string, unknown>;

export type ExtendedJSONSchema7<
E extends JSONSchema7Extension = JSONSchema7Extension,
EXTENSION extends JSONSchema7Extension = JSONSchema7Extension,
> =
| boolean
| (Omit<
Expand Down Expand Up @@ -33,25 +33,25 @@ export type ExtendedJSONSchema7<
> & {
const?: unknown;
enum?: unknown;
items?: ExtendedJSONSchema7<E> | ExtendedJSONSchema7<E>[];
additionalItems?: ExtendedJSONSchema7<E>;
contains?: ExtendedJSONSchema7<E>;
properties?: Record<string, ExtendedJSONSchema7<E>>;
patternProperties?: Record<string, ExtendedJSONSchema7<E>>;
additionalProperties?: ExtendedJSONSchema7<E>;
items?: ExtendedJSONSchema7<EXTENSION> | ExtendedJSONSchema7<EXTENSION>[];
additionalItems?: ExtendedJSONSchema7<EXTENSION>;
contains?: ExtendedJSONSchema7<EXTENSION>;
properties?: Record<string, ExtendedJSONSchema7<EXTENSION>>;
patternProperties?: Record<string, ExtendedJSONSchema7<EXTENSION>>;
additionalProperties?: ExtendedJSONSchema7<EXTENSION>;
dependencies?: {
[key: string]: ExtendedJSONSchema7<E> | string[];
[key: string]: ExtendedJSONSchema7<EXTENSION> | string[];
};
propertyNames?: ExtendedJSONSchema7<E>;
if?: ExtendedJSONSchema7<E>;
then?: ExtendedJSONSchema7<E>;
else?: ExtendedJSONSchema7<E>;
allOf?: ExtendedJSONSchema7<E>[];
anyOf?: ExtendedJSONSchema7<E>[];
oneOf?: ExtendedJSONSchema7<E>[];
not?: ExtendedJSONSchema7<E>;
propertyNames?: ExtendedJSONSchema7<EXTENSION>;
if?: ExtendedJSONSchema7<EXTENSION>;
then?: ExtendedJSONSchema7<EXTENSION>;
else?: ExtendedJSONSchema7<EXTENSION>;
allOf?: ExtendedJSONSchema7<EXTENSION>[];
anyOf?: ExtendedJSONSchema7<EXTENSION>[];
oneOf?: ExtendedJSONSchema7<EXTENSION>[];
not?: ExtendedJSONSchema7<EXTENSION>;
nullable?: boolean;
definitions?: { [key: string]: ExtendedJSONSchema7<E> };
definitions?: { [key: string]: ExtendedJSONSchema7<EXTENSION> };
// Required to avoid applying Readonly to Array interface, which results in invalid type (Array is treated as Object):
// https://github.com/ThomasAribart/json-schema-to-ts/issues/48
// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/0e40d820c92ec6457854fa6726bbff2ffea4e7dd/types/json-schema/index.d.ts#L590
Expand All @@ -60,51 +60,61 @@ export type ExtendedJSONSchema7<
// Required to allow array values in default field
// https://github.com/ThomasAribart/json-schema-to-ts/issues/80
default?: unknown;
} & Partial<E>);
} & Partial<EXTENSION>);

export type ExtendedJSONSchema7Reference<
E extends JSONSchema7Extension = JSONSchema7Extension,
> = ExtendedJSONSchema7<E> & { $id: string };
EXTENSION extends JSONSchema7Extension = JSONSchema7Extension,
> = ExtendedJSONSchema7<EXTENSION> & { $id: string };

type UnextendJSONSchema7Tuple<
E extends JSONSchema7Extension,
S extends ExtendedJSONSchema7<E>[],
> = S extends [infer H, ...infer T]
? H extends ExtendedJSONSchema7<E>
? T extends ExtendedJSONSchema7<E>[]
? [UnextendJSONSchema7<E, H>, ...UnextendJSONSchema7Tuple<E, T>]
EXTENSION extends JSONSchema7Extension,
EXTENDED_SCHEMAS extends ExtendedJSONSchema7<EXTENSION>[],
> = EXTENDED_SCHEMAS extends [
infer EXTENDED_SCHEMAS_HEAD,
...infer EXTENDED_SCHEMAS_TAIL,
]
? EXTENDED_SCHEMAS_HEAD extends ExtendedJSONSchema7<EXTENSION>
? EXTENDED_SCHEMAS_TAIL extends ExtendedJSONSchema7<EXTENSION>[]
? [
UnextendJSONSchema7<EXTENSION, EXTENDED_SCHEMAS_HEAD>,
...UnextendJSONSchema7Tuple<EXTENSION, EXTENDED_SCHEMAS_TAIL>,
]
: never
: never
: [];

type UnextendJSONSchema7Record<
E extends JSONSchema7Extension,
S extends Record<string, unknown>,
EXTENSION extends JSONSchema7Extension,
SCHEMA_RECORD extends Record<string, unknown>,
> = {
[key in keyof S]: S[key] extends ExtendedJSONSchema7<E>
? UnextendJSONSchema7<E, S[key]>
: S[key];
[KEY in keyof SCHEMA_RECORD]: SCHEMA_RECORD[KEY] extends ExtendedJSONSchema7<EXTENSION>
? UnextendJSONSchema7<EXTENSION, SCHEMA_RECORD[KEY]>
: SCHEMA_RECORD[KEY];
};

export type UnextendJSONSchema7<
E extends JSONSchema7Extension,
S,
> = S extends boolean
? S
EXTENSION extends JSONSchema7Extension,
EXTENDED_SCHEMA,
> = EXTENDED_SCHEMA extends boolean
? EXTENDED_SCHEMA
: {
[key in $JSONSchema7 | keyof S]: key extends keyof S
? S extends { [k in key]: ExtendedJSONSchema7<E> }
? UnextendJSONSchema7<E, S[key]>
: S extends { [k in key]: ExtendedJSONSchema7<E>[] }
? number extends S[key]["length"]
? UnextendJSONSchema7<E, S[key][number]>[]
: S[key] extends ExtendedJSONSchema7<E>[]
? UnextendJSONSchema7Tuple<E, S[key]>
[KEY in
| $JSONSchema7
| keyof EXTENDED_SCHEMA]: KEY extends keyof EXTENDED_SCHEMA
? EXTENDED_SCHEMA extends { [K in KEY]: ExtendedJSONSchema7<EXTENSION> }
? UnextendJSONSchema7<EXTENSION, EXTENDED_SCHEMA[KEY]>
: EXTENDED_SCHEMA extends {
[K in KEY]: ExtendedJSONSchema7<EXTENSION>[];
}
? number extends EXTENDED_SCHEMA[KEY]["length"]
? UnextendJSONSchema7<EXTENSION, EXTENDED_SCHEMA[KEY][number]>[]
: EXTENDED_SCHEMA[KEY] extends ExtendedJSONSchema7<EXTENSION>[]
? UnextendJSONSchema7Tuple<EXTENSION, EXTENDED_SCHEMA[KEY]>
: never
: S extends { [k in key]: Record<string, unknown> }
? UnextendJSONSchema7Record<E, S[key]>
: S[key]
: key extends $JSONSchema7
: EXTENDED_SCHEMA extends { [K in KEY]: Record<string, unknown> }
? UnextendJSONSchema7Record<EXTENSION, EXTENDED_SCHEMA[KEY]>
: EXTENDED_SCHEMA[KEY]
: KEY extends $JSONSchema7
? $JSONSchema7
: never;
};
13 changes: 7 additions & 6 deletions src/definitions/fromSchemaOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ export type FromSchemaOptions = {
/**
* FromExtendedSchema options constraints
*/
export type FromExtendedSchemaOptions<E extends JSONSchema7Extension> = {
parseNotKeyword?: boolean;
parseIfThenElseKeywords?: boolean;
references?: ExtendedJSONSchema7Reference<E>[] | false;
deserialize?: DeserializationPattern[] | false;
};
export type FromExtendedSchemaOptions<EXTENSION extends JSONSchema7Extension> =
{
parseNotKeyword?: boolean;
parseIfThenElseKeywords?: boolean;
references?: ExtendedJSONSchema7Reference<EXTENSION>[] | false;
deserialize?: DeserializationPattern[] | false;
};

/**
* FromSchema default options
Expand Down
63 changes: 36 additions & 27 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { M } from "ts-algebra";

import type {
JSONSchema7 as $JSONSchema7,
JSONSchema7Reference as $JSONSchema7Reference,
JSONSchema7 as WritableJSONSchema7,
JSONSchema7Reference as WritableJSONSchema7Reference,
JSONSchema7Extension,
ExtendedJSONSchema7 as $ExtendedJSONSchema7,
ExtendedJSONSchema7Reference as $ExtendedJSONSchema7Reference,
ExtendedJSONSchema7 as WritableExtendedJSONSchema7,
ExtendedJSONSchema7Reference as WritableExtendedJSONSchema7Reference,
UnextendJSONSchema7,
FromSchemaOptions,
FromSchemaDefaultOptions,
Expand All @@ -32,28 +32,30 @@ export {
/**
* Unwidened V7 JSON schema (e.g. defined with the `as const` statement)
*/
export type JSONSchema7 = $JSONSchema7 | Readonly<$JSONSchema7>;
export type JSONSchema7 = WritableJSONSchema7 | Readonly<WritableJSONSchema7>;

/**
* Unwidened extended V7 JSON schema (e.g. defined with the `as const` statement)
*/
export type ExtendedJSONSchema7<E extends JSONSchema7Extension> =
| $ExtendedJSONSchema7<E>
| Readonly<$ExtendedJSONSchema7<E>>;
export type ExtendedJSONSchema7<EXTENSION extends JSONSchema7Extension> =
| WritableExtendedJSONSchema7<EXTENSION>
| Readonly<WritableExtendedJSONSchema7<EXTENSION>>;

/**
* Unwidened V7 JSON schema reference (e.g. defined with the `as const` statement)
*/
export type JSONSchema7Reference =
| $JSONSchema7Reference
| Readonly<$JSONSchema7Reference>;
| WritableJSONSchema7Reference
| Readonly<WritableJSONSchema7Reference>;

/**
* Unwidened extended V7 JSON schema reference (e.g. defined with the `as const` statement)
*/
export type ExtendedJSONSchema7Reference<E extends JSONSchema7Extension> =
| $ExtendedJSONSchema7Reference<E>
| Readonly<$ExtendedJSONSchema7Reference<E>>;
export type ExtendedJSONSchema7Reference<
EXTENSION extends JSONSchema7Extension,
> =
| WritableExtendedJSONSchema7Reference<EXTENSION>
| Readonly<WritableExtendedJSONSchema7Reference<EXTENSION>>;

/**
* Unwidened JSON schema (e.g. defined with the `as const` statement)
Expand All @@ -63,30 +65,37 @@ export type JSONSchema = JSONSchema7;
/**
* Unwidened extended JSON schema (e.g. defined with the `as const` statement)
*/
export type ExtendedJSONSchema<E extends JSONSchema7Extension> =
ExtendedJSONSchema7<E>;
export type ExtendedJSONSchema<EXTENSION extends JSONSchema7Extension> =
ExtendedJSONSchema7<EXTENSION>;

/**
* Given a JSON schema defined with the `as const` statement, infers the type of valid instances
*
* @param S JSON schema
*/
export type FromSchema<
S extends JSONSchema,
Opt extends FromSchemaOptions = FromSchemaDefaultOptions,
W extends $JSONSchema7 = S extends Record<string | number | symbol, unknown>
? Writable<S>
: S,
> = M.$Resolve<ParseSchema<W, ParseOptions<W, Opt>>>;
SCHEMA extends JSONSchema,
OPTIONS extends FromSchemaOptions = FromSchemaDefaultOptions,
WRITABLE_SCHEMA extends WritableJSONSchema7 = SCHEMA extends Record<
string | number | symbol,
unknown
>
? Writable<SCHEMA>
: SCHEMA,
> = M.$Resolve<
ParseSchema<WRITABLE_SCHEMA, ParseOptions<WRITABLE_SCHEMA, OPTIONS>>
>;

/**
* Given an extended JSON schema defined with the `as const` statement, infers the type of valid instances
*
* @param S JSON schema
* @param SCHEMA JSON schema
*/
export type FromExtendedSchema<
E extends JSONSchema7Extension,
S extends ExtendedJSONSchema<E>,
Opt extends FromExtendedSchemaOptions<E> = FromSchemaDefaultOptions,
U = UnextendJSONSchema7<E, S>,
> = U extends JSONSchema ? FromSchema<U, Opt> : never;
EXTENSION extends JSONSchema7Extension,
SCHEMA extends ExtendedJSONSchema<EXTENSION>,
OPTIONS extends FromExtendedSchemaOptions<EXTENSION> = FromSchemaDefaultOptions,
UNEXTENDED_SCHEMA = UnextendJSONSchema7<EXTENSION, SCHEMA>,
> = UNEXTENDED_SCHEMA extends JSONSchema
? FromSchema<UNEXTENDED_SCHEMA, OPTIONS>
: never;
42 changes: 25 additions & 17 deletions src/parse-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,37 @@ import type { JSONSchema7Reference } from "./index";
import type { Writable } from "./type-utils";

export type ParseReferences<
S extends JSONSchema7Reference[],
R extends Record<string, JSONSchema7> = {},
> = S extends [infer H, ...infer T]
REF_SCHEMAS extends JSONSchema7Reference[],
REFERENCES extends Record<string, JSONSchema7> = {},
> = REF_SCHEMAS extends [infer REF_SCHEMAS_HEAD, ...infer REF_SCHEMAS_TAIL]
? // TODO increase TS version and use "extends" in Array https://devblogs.microsoft.com/typescript/announcing-typescript-4-8/#improved-inference-for-infer-types-in-template-string-types
H extends JSONSchema7Reference
? T extends JSONSchema7Reference[]
? ParseReferences<T, R & { [key in H["$id"]]: Writable<H> }>
REF_SCHEMAS_HEAD extends JSONSchema7Reference
? REF_SCHEMAS_TAIL extends JSONSchema7Reference[]
? ParseReferences<
REF_SCHEMAS_TAIL,
REFERENCES & {
[key in REF_SCHEMAS_HEAD["$id"]]: Writable<REF_SCHEMAS_HEAD>;
}
>
: never
: never
: R;
: REFERENCES;

export type ParseOptions<S extends JSONSchema7, O extends FromSchemaOptions> = {
parseNotKeyword: O["parseNotKeyword"] extends boolean
? O["parseNotKeyword"]
export type ParseOptions<
SCHEMA extends JSONSchema7,
OPTIONS extends FromSchemaOptions,
> = {
parseNotKeyword: OPTIONS["parseNotKeyword"] extends boolean
? OPTIONS["parseNotKeyword"]
: FromSchemaDefaultOptions["parseNotKeyword"];
parseIfThenElseKeywords: O["parseIfThenElseKeywords"] extends boolean
? O["parseIfThenElseKeywords"]
parseIfThenElseKeywords: OPTIONS["parseIfThenElseKeywords"] extends boolean
? OPTIONS["parseIfThenElseKeywords"]
: FromSchemaDefaultOptions["parseIfThenElseKeywords"];
rootSchema: S;
references: O["references"] extends JSONSchema7Reference[]
? ParseReferences<O["references"]>
rootSchema: SCHEMA;
references: OPTIONS["references"] extends JSONSchema7Reference[]
? ParseReferences<OPTIONS["references"]>
: {};
deserialize: O["deserialize"] extends DeserializationPattern[] | false
? O["deserialize"]
deserialize: OPTIONS["deserialize"] extends DeserializationPattern[] | false
? OPTIONS["deserialize"]
: FromSchemaDefaultOptions["deserialize"];
};
41 changes: 26 additions & 15 deletions src/parse-schema/allOf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,36 @@ import type { MergeSubSchema } from "./utils";
export type AllOfSchema = JSONSchema7 & { allOf: JSONSchema7[] };

export type ParseAllOfSchema<
P extends AllOfSchema,
O extends ParseSchemaOptions,
> = RecurseOnAllOfSchema<P["allOf"], P, O, ParseSchema<Omit<P, "allOf">, O>>;
SCHEMA extends AllOfSchema,
OPTIONS extends ParseSchemaOptions,
> = RecurseOnAllOfSchema<
SCHEMA["allOf"],
SCHEMA,
OPTIONS,
ParseSchema<Omit<SCHEMA, "allOf">, OPTIONS>
>;

type RecurseOnAllOfSchema<
S extends JSONSchema7[],
P extends AllOfSchema,
O extends ParseSchemaOptions,
R,
> = S extends [infer H, ...infer T]
SUB_SCHEMAS extends JSONSchema7[],
ROOT_SCHEMA extends AllOfSchema,
OPTIONS extends ParseSchemaOptions,
PARSED_ROOT_SCHEMA,
> = SUB_SCHEMAS extends [infer SUB_SCHEMAS_HEAD, ...infer SUB_SCHEMAS_TAIL]
? // TODO increase TS version and use "extends" in Array https://devblogs.microsoft.com/typescript/announcing-typescript-4-8/#improved-inference-for-infer-types-in-template-string-types
H extends JSONSchema7
? T extends JSONSchema7[]
SUB_SCHEMAS_HEAD extends JSONSchema7
? SUB_SCHEMAS_TAIL extends JSONSchema7[]
? RecurseOnAllOfSchema<
T,
P,
O,
M.$Intersect<ParseSchema<MergeSubSchema<Omit<P, "allOf">, H>, O>, R>
SUB_SCHEMAS_TAIL,
ROOT_SCHEMA,
OPTIONS,
M.$Intersect<
ParseSchema<
MergeSubSchema<Omit<ROOT_SCHEMA, "allOf">, SUB_SCHEMAS_HEAD>,
OPTIONS
>,
PARSED_ROOT_SCHEMA
>
>
: never
: never
: R;
: PARSED_ROOT_SCHEMA;
Loading

0 comments on commit 71b0de8

Please sign in to comment.