From e1def77d401351b227307df9df8345de05b2c304 Mon Sep 17 00:00:00 2001 From: g4rcez Date: Sat, 8 Oct 2022 00:59:52 -0300 Subject: [PATCH 1/3] feat: add improvements in Typescript API --- types/FluentJSONSchema.d.ts | 41 ++++++++++++++++---------------- types/FluentJSONSchema.test-d.ts | 33 ++++++++++++++++++++++--- 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/types/FluentJSONSchema.d.ts b/types/FluentJSONSchema.d.ts index 2d5ec35..e9e496d 100644 --- a/types/FluentJSONSchema.d.ts +++ b/types/FluentJSONSchema.d.ts @@ -114,20 +114,21 @@ export interface ArraySchema extends BaseSchema { maxItems: (max: number) => ArraySchema } -export interface ObjectSchema extends BaseSchema { - definition: (name: string, props?: JSONSchema) => ObjectSchema - prop: (name: string, props?: JSONSchema) => ObjectSchema - additionalProperties: (value: JSONSchema | boolean) => ObjectSchema - maxProperties: (max: number) => ObjectSchema - minProperties: (min: number) => ObjectSchema - patternProperties: (options: PatternPropertiesOptions) => ObjectSchema - dependencies: (options: DependenciesOptions) => ObjectSchema - propertyNames: (value: JSONSchema) => ObjectSchema - extend: (schema: ObjectSchema | ExtendedSchema) => ExtendedSchema - only: (properties: string[]) => ObjectSchema - without: (properties: string[]) => ObjectSchema - dependentRequired: (options: DependentRequiredOptions) => ObjectSchema - dependentSchemas: (options: DependentSchemaOptions) => ObjectSchema + +export interface ObjectSchema = Record> extends BaseSchema> { + definition: (name: Key, props?: JSONSchema) => ObjectSchema + prop: (name: Key, props?: JSONSchema) => ObjectSchema + additionalProperties: (value: JSONSchema | boolean) => ObjectSchema + maxProperties: (max: number) => ObjectSchema + minProperties: (min: number) => ObjectSchema + patternProperties: (options: PatternPropertiesOptions) => ObjectSchema + dependencies: (options: DependenciesOptions) => ObjectSchema + propertyNames: (value: JSONSchema) => ObjectSchema + extend: (schema: ObjectSchema | ExtendedSchema) => ExtendedSchema + only: (properties: string[]) => ObjectSchema + without: (properties: string[]) => ObjectSchema + dependentRequired: (options: DependentRequiredOptions) => ObjectSchema + dependentSchemas: (options: DependentSchemaOptions) => ObjectSchema } export type ExtendedSchema = Pick @@ -222,13 +223,11 @@ interface DependenciesOptions { [key: string]: JSONSchema[] } -interface DependentSchemaOptions { - [key: string]: JSONSchema -} +type Key = keyof T | (string & {}) -interface DependentRequiredOptions { - [key: string]: string[] -} +type DependentSchemaOptions>> = Partial> + +type DependentRequiredOptions>> = Partial> export function withOptions(options: SchemaOptions): T @@ -238,7 +237,7 @@ export interface S extends BaseSchema { integer: () => IntegerSchema boolean: () => BooleanSchema array: () => ArraySchema - object: () => ObjectSchema + object: () => ObjectSchema null: () => NullSchema mixed: < T extends diff --git a/types/FluentJSONSchema.test-d.ts b/types/FluentJSONSchema.test-d.ts index 1ca639b..8ccf9b0 100644 --- a/types/FluentJSONSchema.test-d.ts +++ b/types/FluentJSONSchema.test-d.ts @@ -110,7 +110,12 @@ const rawNullableSchema = S.object() console.log('raw schema with nullable props\n', JSON.stringify(rawNullableSchema)) -const dependentRequired = S.object() +type Foo = { + foo: string + bar: string +} + +const dependentRequired = S.object() .dependentRequired({ foo: ['bar'], }) @@ -120,11 +125,11 @@ const dependentRequired = S.object() console.log('dependentRequired:\n', JSON.stringify(dependentRequired)) -const dependentSchemas = S.object() +const dependentSchemas = S.object() .dependentSchemas({ foo: S.object().prop('bar'), }) - .prop('foo', S.object().prop('bar')) + .prop('bar', S.object().prop('bar')) .valueOf() console.log('dependentRequired:\n', JSON.stringify(dependentSchemas)) @@ -135,3 +140,25 @@ const deprecatedSchema = S.object() .valueOf() console.log('deprecatedSchema:\n', JSON.stringify(deprecatedSchema)) + +type ReallyLongType = { + foo: string + bar: string + baz: string + xpto: string + abcd: number + kct: { + a: string + b: number + d: null + } +} + +const deepTestOnTypes = S.object() + .prop('bar', S.object().prop('bar')) + // you can provide any string, to avoid breaking changes + .prop('aaaa', S.anyOf([S.string()])) + .definition('abcd', S.number()) + .valueOf() + +console.log('deepTestOnTypes:\n', JSON.stringify(deepTestOnTypes)) From f33522f0b5ef0e800313243845e8c84fc86c776d Mon Sep 17 00:00:00 2001 From: g4rcez Date: Sun, 9 Oct 2022 23:40:39 -0300 Subject: [PATCH 2/3] feat: duplicate tests to use with/without type inference --- types/FluentJSONSchema.test-d.ts | 38 +++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/types/FluentJSONSchema.test-d.ts b/types/FluentJSONSchema.test-d.ts index 8ccf9b0..7d3ef79 100644 --- a/types/FluentJSONSchema.test-d.ts +++ b/types/FluentJSONSchema.test-d.ts @@ -110,12 +110,38 @@ const rawNullableSchema = S.object() console.log('raw schema with nullable props\n', JSON.stringify(rawNullableSchema)) +const dependentRequired = S.object() + .dependentRequired({ + foo: ['bar'], + }) + .prop('foo') + .prop('bar') + .valueOf() + +console.log('dependentRequired:\n', JSON.stringify(dependentRequired)) + +const dependentSchemas = S.object() + .dependentSchemas({ + foo: S.object().prop('bar'), + }) + .prop('bar', S.object().prop('bar')) + .valueOf() + +console.log('dependentRequired:\n', JSON.stringify(dependentSchemas)) + +const deprecatedSchema = S.object() + .deprecated() + .prop('foo', S.string().deprecated()) + .valueOf() + +console.log('deprecatedSchema:\n', JSON.stringify(deprecatedSchema)) + type Foo = { foo: string bar: string } -const dependentRequired = S.object() +const dependentRequiredWithType = S.object() .dependentRequired({ foo: ['bar'], }) @@ -123,23 +149,23 @@ const dependentRequired = S.object() .prop('bar') .valueOf() -console.log('dependentRequired:\n', JSON.stringify(dependentRequired)) +console.log('dependentRequired:\n', JSON.stringify(dependentRequiredWithType)) -const dependentSchemas = S.object() +const dependentSchemasWithType = S.object() .dependentSchemas({ foo: S.object().prop('bar'), }) .prop('bar', S.object().prop('bar')) .valueOf() -console.log('dependentRequired:\n', JSON.stringify(dependentSchemas)) +console.log('dependentSchemasWithType:\n', JSON.stringify(dependentSchemasWithType)) -const deprecatedSchema = S.object() +const deprecatedSchemaWithType = S.object() .deprecated() .prop('foo', S.string().deprecated()) .valueOf() -console.log('deprecatedSchema:\n', JSON.stringify(deprecatedSchema)) +console.log('deprecatedSchemaWithType:\n', JSON.stringify(deprecatedSchemaWithType)) type ReallyLongType = { foo: string From 0d55c77d60609c87ef135095cb38b18125b38b72 Mon Sep 17 00:00:00 2001 From: g4rcez Date: Tue, 18 Oct 2022 09:56:26 -0300 Subject: [PATCH 3/3] fix: pr issues about spaces and {} type --- types/FluentJSONSchema.d.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/types/FluentJSONSchema.d.ts b/types/FluentJSONSchema.d.ts index e9e496d..fba1db0 100644 --- a/types/FluentJSONSchema.d.ts +++ b/types/FluentJSONSchema.d.ts @@ -114,8 +114,7 @@ export interface ArraySchema extends BaseSchema { maxItems: (max: number) => ArraySchema } - -export interface ObjectSchema = Record> extends BaseSchema> { +export interface ObjectSchema = Record> extends BaseSchema> { definition: (name: Key, props?: JSONSchema) => ObjectSchema prop: (name: Key, props?: JSONSchema) => ObjectSchema additionalProperties: (value: JSONSchema | boolean) => ObjectSchema @@ -231,13 +230,15 @@ type DependentRequiredOptions>> = Par export function withOptions(options: SchemaOptions): T +type ObjectPlaceholder = Record; + export interface S extends BaseSchema { string: () => StringSchema number: () => NumberSchema integer: () => IntegerSchema boolean: () => BooleanSchema array: () => ArraySchema - object: () => ObjectSchema + object: () => ObjectSchema null: () => NullSchema mixed: < T extends