From e50bbd8e8cb50359bbb73ee47a0e3124ac62c1bc Mon Sep 17 00:00:00 2001 From: Ben Durrant Date: Tue, 16 Sep 2025 12:02:42 +0100 Subject: [PATCH] feat: use namespaces to export "internal" types that are used in exported signatures --- library/eslint.config.js | 1 + library/src/actions/args/args.ts | 34 +-- library/src/actions/args/argsAsync.ts | 64 +++--- .../methods/getDescription/getDescription.ts | 62 +++--- .../src/methods/getMetadata/getMetadata.ts | 64 +++--- library/src/methods/getTitle/getTitle.ts | 61 +++--- library/src/methods/keyof/keyof.ts | 90 ++++---- library/src/methods/omit/omit.ts | 74 ++++--- library/src/methods/partial/partial.ts | 51 +++-- library/src/methods/partial/partialAsync.ts | 65 +++--- library/src/methods/pick/pick.ts | 74 ++++--- library/src/methods/required/required.ts | 57 ++--- library/src/methods/required/requiredAsync.ts | 63 +++--- .../_getLastMetadata/_getLastMetadata.ts | 70 ++++--- .../entriesFromObjects/entriesFromObjects.ts | 113 ++++++---- packages/to-json-schema/eslint.config.js | 1 + .../converters/convertSchema/convertSchema.ts | 198 ++++++++++-------- 17 files changed, 627 insertions(+), 515 deletions(-) diff --git a/library/eslint.config.js b/library/eslint.config.js index a57e255b6..9e755a259 100644 --- a/library/eslint.config.js +++ b/library/eslint.config.js @@ -83,6 +83,7 @@ export default tseslint.config( '@typescript-eslint/no-non-null-assertion': 'off', '@typescript-eslint/consistent-indexed-object-style': 'off', '@typescript-eslint/no-inferrable-types': 'off', + '@typescript-eslint/no-namespace': 'off', // Imports 'no-duplicate-imports': 'off', diff --git a/library/src/actions/args/args.ts b/library/src/actions/args/args.ts index afa7bd901..19e9ab179 100644 --- a/library/src/actions/args/args.ts +++ b/library/src/actions/args/args.ts @@ -18,18 +18,20 @@ import type { } from '../../types/index.ts'; import { ValiError } from '../../utils/index.ts'; -/** - * Schema type. - */ -type Schema = - | LooseTupleSchema | undefined> - | StrictTupleSchema | undefined> - | TupleSchema | undefined> - | TupleWithRestSchema< - TupleItems, - BaseSchema>, - ErrorMessage | undefined - >; +export namespace args { + /** + * Schema type. + */ + export type Schema = + | LooseTupleSchema | undefined> + | StrictTupleSchema | undefined> + | TupleSchema | undefined> + | TupleWithRestSchema< + TupleItems, + BaseSchema>, + ErrorMessage | undefined + >; +} /** * Args action type. @@ -37,7 +39,7 @@ type Schema = export interface ArgsAction< // eslint-disable-next-line @typescript-eslint/no-explicit-any TInput extends (...args: any[]) => unknown, - TSchema extends Schema, + TSchema extends args.Schema, > extends BaseTransformation< TInput, (...args: InferInput) => ReturnType, @@ -67,13 +69,13 @@ export interface ArgsAction< export function args< // eslint-disable-next-line @typescript-eslint/no-explicit-any TInput extends (...args: any[]) => unknown, - TSchema extends Schema, + TSchema extends args.Schema, >(schema: TSchema): ArgsAction; // @__NO_SIDE_EFFECTS__ export function args( - schema: Schema -): ArgsAction<(...args: unknown[]) => unknown, Schema> { + schema: args.Schema +): ArgsAction<(...args: unknown[]) => unknown, args.Schema> { return { kind: 'transformation', type: 'args', diff --git a/library/src/actions/args/argsAsync.ts b/library/src/actions/args/argsAsync.ts index bc72cf933..981ec36db 100644 --- a/library/src/actions/args/argsAsync.ts +++ b/library/src/actions/args/argsAsync.ts @@ -25,33 +25,35 @@ import type { } from '../../types/index.ts'; import { ValiError } from '../../utils/index.ts'; -/** - * Schema type. - */ -type Schema = - | LooseTupleSchema | undefined> - | LooseTupleSchemaAsync< - TupleItemsAsync, - ErrorMessage | undefined - > - | StrictTupleSchema | undefined> - | StrictTupleSchemaAsync< - TupleItemsAsync, - ErrorMessage | undefined - > - | TupleSchema | undefined> - | TupleSchemaAsync | undefined> - | TupleWithRestSchema< - TupleItems, - BaseSchema>, - ErrorMessage | undefined - > - | TupleWithRestSchemaAsync< - TupleItemsAsync, - | BaseSchema> - | BaseSchemaAsync>, - ErrorMessage | undefined - >; +export namespace argsAsync { + /** + * Schema type. + */ + export type Schema = + | LooseTupleSchema | undefined> + | LooseTupleSchemaAsync< + TupleItemsAsync, + ErrorMessage | undefined + > + | StrictTupleSchema | undefined> + | StrictTupleSchemaAsync< + TupleItemsAsync, + ErrorMessage | undefined + > + | TupleSchema | undefined> + | TupleSchemaAsync | undefined> + | TupleWithRestSchema< + TupleItems, + BaseSchema>, + ErrorMessage | undefined + > + | TupleWithRestSchemaAsync< + TupleItemsAsync, + | BaseSchema> + | BaseSchemaAsync>, + ErrorMessage | undefined + >; +} /** * Args action async type. @@ -59,7 +61,7 @@ type Schema = export interface ArgsActionAsync< // eslint-disable-next-line @typescript-eslint/no-explicit-any TInput extends (...args: any[]) => unknown, - TSchema extends Schema, + TSchema extends argsAsync.Schema, > extends BaseTransformation< TInput, (...args: InferInput) => Promise>>, @@ -89,13 +91,13 @@ export interface ArgsActionAsync< export function argsAsync< // eslint-disable-next-line @typescript-eslint/no-explicit-any TInput extends (...args: any[]) => unknown, - TSchema extends Schema, + TSchema extends argsAsync.Schema, >(schema: TSchema): ArgsActionAsync; // @__NO_SIDE_EFFECTS__ export function argsAsync( - schema: Schema -): ArgsActionAsync<(...args: unknown[]) => unknown, Schema> { + schema: argsAsync.Schema +): ArgsActionAsync<(...args: unknown[]) => unknown, argsAsync.Schema> { return { kind: 'transformation', type: 'args', diff --git a/library/src/methods/getDescription/getDescription.ts b/library/src/methods/getDescription/getDescription.ts index 51b401b62..273fdcad1 100644 --- a/library/src/methods/getDescription/getDescription.ts +++ b/library/src/methods/getDescription/getDescription.ts @@ -9,34 +9,36 @@ import type { import { _getLastMetadata } from '../../utils/index.ts'; import type { SchemaWithPipe, SchemaWithPipeAsync } from '../index.ts'; -/** - * Schema type. - */ -type Schema = - | BaseSchema> - | BaseSchemaAsync> - | SchemaWithPipe< - readonly [ - BaseSchema>, - ...( - | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any - | DescriptionAction - )[], - ] - > - | SchemaWithPipeAsync< - readonly [ - ( - | BaseSchema> - | BaseSchemaAsync> - ), - ...( - | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any - | PipeItemAsync> // eslint-disable-line @typescript-eslint/no-explicit-any - | DescriptionAction - )[], - ] - >; +export namespace getDescription { + /** + * Schema type. + */ + export type Schema = + | BaseSchema> + | BaseSchemaAsync> + | SchemaWithPipe< + readonly [ + BaseSchema>, + ...( + | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any + | DescriptionAction + )[], + ] + > + | SchemaWithPipeAsync< + readonly [ + ( + | BaseSchema> + | BaseSchemaAsync> + ), + ...( + | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any + | PipeItemAsync> // eslint-disable-line @typescript-eslint/no-explicit-any + | DescriptionAction + )[], + ] + >; +} /** * Returns the description of the schema. @@ -52,6 +54,8 @@ type Schema = */ // TODO: Investigate if return type can be strongly typed // @__NO_SIDE_EFFECTS__ -export function getDescription(schema: Schema): string | undefined { +export function getDescription( + schema: getDescription.Schema +): string | undefined { return _getLastMetadata(schema, 'description'); } diff --git a/library/src/methods/getMetadata/getMetadata.ts b/library/src/methods/getMetadata/getMetadata.ts index 361b8471b..4533d5310 100644 --- a/library/src/methods/getMetadata/getMetadata.ts +++ b/library/src/methods/getMetadata/getMetadata.ts @@ -10,34 +10,36 @@ import type { } from '../../types/index.ts'; import type { SchemaWithPipe, SchemaWithPipeAsync } from '../pipe/index.ts'; -/** - * Schema type. - */ -type Schema = - | BaseSchema> - | BaseSchemaAsync> - | SchemaWithPipe< - readonly [ - BaseSchema>, - ...( - | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any - | MetadataAction> - )[], - ] - > - | SchemaWithPipeAsync< - readonly [ - ( - | BaseSchema> - | BaseSchemaAsync> - ), - ...( - | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any - | PipeItemAsync> // eslint-disable-line @typescript-eslint/no-explicit-any - | MetadataAction> - )[], - ] - >; +export namespace getMetadata { + /** + * Schema type. + */ + export type Schema = + | BaseSchema> + | BaseSchemaAsync> + | SchemaWithPipe< + readonly [ + BaseSchema>, + ...( + | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any + | MetadataAction> + )[], + ] + > + | SchemaWithPipeAsync< + readonly [ + ( + | BaseSchema> + | BaseSchemaAsync> + ), + ...( + | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any + | PipeItemAsync> // eslint-disable-line @typescript-eslint/no-explicit-any + | MetadataAction> + )[], + ] + >; +} /** * Basic pipe item type. @@ -74,7 +76,7 @@ type RecursiveMerge< * * @beta */ -export type InferMetadata = +export type InferMetadata = // eslint-disable-next-line @typescript-eslint/no-explicit-any BaseSchema extends TSchema ? Record @@ -101,11 +103,11 @@ export type InferMetadata = * @beta */ // @__NO_SIDE_EFFECTS__ -export function getMetadata( +export function getMetadata( schema: TSchema ): InferMetadata { const result = {}; - function depthFirstMerge(schema: Schema): void { + function depthFirstMerge(schema: getMetadata.Schema): void { if ('pipe' in schema) { for (const item of schema.pipe) { if (item.kind === 'schema' && 'pipe' in item) { diff --git a/library/src/methods/getTitle/getTitle.ts b/library/src/methods/getTitle/getTitle.ts index 7f6bdc788..95b478235 100644 --- a/library/src/methods/getTitle/getTitle.ts +++ b/library/src/methods/getTitle/getTitle.ts @@ -9,35 +9,36 @@ import type { import { _getLastMetadata } from '../../utils/index.ts'; import type { SchemaWithPipe, SchemaWithPipeAsync } from '../index.ts'; -/** - * Schema type. - */ -type Schema = - | BaseSchema> - | BaseSchemaAsync> - | SchemaWithPipe< - readonly [ - BaseSchema>, - ...( - | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any - | TitleAction - )[], - ] - > - | SchemaWithPipeAsync< - readonly [ - ( - | BaseSchema> - | BaseSchemaAsync> - ), - ...( - | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any - | PipeItemAsync> // eslint-disable-line @typescript-eslint/no-explicit-any - | TitleAction - )[], - ] - >; - +export namespace getTitle { + /** + * Schema type. + */ + export type Schema = + | BaseSchema> + | BaseSchemaAsync> + | SchemaWithPipe< + readonly [ + BaseSchema>, + ...( + | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any + | TitleAction + )[], + ] + > + | SchemaWithPipeAsync< + readonly [ + ( + | BaseSchema> + | BaseSchemaAsync> + ), + ...( + | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any + | PipeItemAsync> // eslint-disable-line @typescript-eslint/no-explicit-any + | TitleAction + )[], + ] + >; +} /** * Returns the title of the schema. * @@ -52,6 +53,6 @@ type Schema = */ // TODO: Investigate if return type can be strongly typed // @__NO_SIDE_EFFECTS__ -export function getTitle(schema: Schema): string | undefined { +export function getTitle(schema: getTitle.Schema): string | undefined { return _getLastMetadata(schema, 'title'); } diff --git a/library/src/methods/keyof/keyof.ts b/library/src/methods/keyof/keyof.ts index 50a19e9bb..8625e7944 100644 --- a/library/src/methods/keyof/keyof.ts +++ b/library/src/methods/keyof/keyof.ts @@ -24,35 +24,43 @@ import type { UnionToTuple, } from '../../types/index.ts'; -/** - * Schema type. - */ -type Schema = - | LooseObjectSchema | undefined> - | LooseObjectSchemaAsync< - ObjectEntriesAsync, - ErrorMessage | undefined - > - | ObjectSchema | undefined> - | ObjectSchemaAsync | undefined> - | ObjectWithRestSchema< - ObjectEntries, - BaseSchema>, - ErrorMessage | undefined - > - | ObjectWithRestSchemaAsync< - ObjectEntriesAsync, - BaseSchema>, - ErrorMessage | undefined - > - | StrictObjectSchema< - ObjectEntries, - ErrorMessage | undefined - > - | StrictObjectSchemaAsync< - ObjectEntriesAsync, - ErrorMessage | undefined - >; +export namespace keyof_ { + /** + * Schema type. + */ + export type Schema = + | LooseObjectSchema< + ObjectEntries, + ErrorMessage | undefined + > + | LooseObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + | ObjectSchema | undefined> + | ObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + | ObjectWithRestSchema< + ObjectEntries, + BaseSchema>, + ErrorMessage | undefined + > + | ObjectWithRestSchemaAsync< + ObjectEntriesAsync, + BaseSchema>, + ErrorMessage | undefined + > + | StrictObjectSchema< + ObjectEntries, + ErrorMessage | undefined + > + | StrictObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + >; +} /** * Force tuple type. @@ -62,7 +70,7 @@ type ForceTuple = T extends [string, ...string[]] ? T : []; /** * Object keys type. */ -type ObjectKeys = ForceTuple< +type ObjectKeys = ForceTuple< UnionToTuple >; @@ -73,7 +81,7 @@ type ObjectKeys = ForceTuple< * * @returns A picklist schema. */ -export function keyof( +export function keyof_( schema: TSchema ): PicklistSchema, undefined>; @@ -85,8 +93,8 @@ export function keyof( * * @returns A picklist schema. */ -export function keyof< - const TSchema extends Schema, +export function keyof_< + const TSchema extends keyof_.Schema, const TMessage extends ErrorMessage | undefined, >( schema: TSchema, @@ -94,9 +102,17 @@ export function keyof< ): PicklistSchema, TMessage>; // @__NO_SIDE_EFFECTS__ -export function keyof( - schema: Schema, +export function keyof_( + schema: keyof_.Schema, message?: ErrorMessage -): PicklistSchema, ErrorMessage | undefined> { - return picklist(Object.keys(schema.entries) as ObjectKeys, message); +): PicklistSchema< + ObjectKeys, + ErrorMessage | undefined +> { + return picklist( + Object.keys(schema.entries) as ObjectKeys, + message + ); } + +export { keyof_ as keyof }; diff --git a/library/src/methods/omit/omit.ts b/library/src/methods/omit/omit.ts index 5d2e952c3..54c3a5a2b 100644 --- a/library/src/methods/omit/omit.ts +++ b/library/src/methods/omit/omit.ts @@ -34,43 +34,51 @@ import type { } from '../../types/index.ts'; import { _getStandardProps } from '../../utils/index.ts'; -/** - * Schema type. - */ -type Schema = SchemaWithoutPipe< - | LooseObjectSchema | undefined> - | LooseObjectSchemaAsync< - ObjectEntriesAsync, - ErrorMessage | undefined - > - | ObjectSchema | undefined> - | ObjectSchemaAsync | undefined> - | ObjectWithRestSchema< - ObjectEntries, - BaseSchema>, - ErrorMessage | undefined - > - | ObjectWithRestSchemaAsync< - ObjectEntriesAsync, - | BaseSchema> - | BaseSchemaAsync>, - ErrorMessage | undefined - > - | StrictObjectSchema< - ObjectEntries, - ErrorMessage | undefined - > - | StrictObjectSchemaAsync< - ObjectEntriesAsync, - ErrorMessage | undefined - > ->; +export namespace omit { + /** + * Schema type. + */ + export type Schema = SchemaWithoutPipe< + | LooseObjectSchema< + ObjectEntries, + ErrorMessage | undefined + > + | LooseObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + | ObjectSchema | undefined> + | ObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + | ObjectWithRestSchema< + ObjectEntries, + BaseSchema>, + ErrorMessage | undefined + > + | ObjectWithRestSchemaAsync< + ObjectEntriesAsync, + | BaseSchema> + | BaseSchemaAsync>, + ErrorMessage | undefined + > + | StrictObjectSchema< + ObjectEntries, + ErrorMessage | undefined + > + | StrictObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + >; +} /** * Schema with omit type. */ export type SchemaWithOmit< - TSchema extends Schema, + TSchema extends omit.Schema, TKeys extends ObjectKeys, > = TSchema extends | ObjectSchema | undefined> @@ -465,7 +473,7 @@ export type SchemaWithOmit< */ // @__NO_SIDE_EFFECTS__ export function omit< - const TSchema extends Schema, + const TSchema extends omit.Schema, const TKeys extends ObjectKeys, >(schema: TSchema, keys: TKeys): SchemaWithOmit { // Create modified object entries diff --git a/library/src/methods/partial/partial.ts b/library/src/methods/partial/partial.ts index 8e4d5438c..9e907b96d 100644 --- a/library/src/methods/partial/partial.ts +++ b/library/src/methods/partial/partial.ts @@ -29,22 +29,27 @@ import type { } from '../../types/index.ts'; import { _getStandardProps } from '../../utils/index.ts'; -/** - * Schema type. - */ -type Schema = SchemaWithoutPipe< - | LooseObjectSchema | undefined> - | ObjectSchema | undefined> - | ObjectWithRestSchema< - ObjectEntries, - BaseSchema>, - ErrorMessage | undefined - > - | StrictObjectSchema< - ObjectEntries, - ErrorMessage | undefined - > ->; +export namespace partial { + /** + * Schema type. + */ + export type Schema = SchemaWithoutPipe< + | LooseObjectSchema< + ObjectEntries, + ErrorMessage | undefined + > + | ObjectSchema | undefined> + | ObjectWithRestSchema< + ObjectEntries, + BaseSchema>, + ErrorMessage | undefined + > + | StrictObjectSchema< + ObjectEntries, + ErrorMessage | undefined + > + >; +} /** * Partial entries type. @@ -64,7 +69,7 @@ type PartialEntries< * Schema with partial type. */ export type SchemaWithPartial< - TSchema extends Schema, + TSchema extends partial.Schema, TKeys extends ObjectKeys | undefined, > = TSchema extends | ObjectSchema | undefined> @@ -248,7 +253,7 @@ export type SchemaWithPartial< * * @returns An object schema. */ -export function partial( +export function partial( schema: TSchema ): SchemaWithPartial; @@ -262,17 +267,17 @@ export function partial( * @returns An object schema. */ export function partial< - const TSchema extends Schema, + const TSchema extends partial.Schema, const TKeys extends ObjectKeys, >(schema: TSchema, keys: TKeys): SchemaWithPartial; // @__NO_SIDE_EFFECTS__ export function partial( - schema: Schema, - keys?: ObjectKeys -): SchemaWithPartial | undefined> { + schema: partial.Schema, + keys?: ObjectKeys +): SchemaWithPartial | undefined> { // Create modified object entries - const entries: PartialEntries> = {}; + const entries: PartialEntries> = {}; for (const key in schema.entries) { // @ts-expect-error entries[key] = diff --git a/library/src/methods/partial/partialAsync.ts b/library/src/methods/partial/partialAsync.ts index 53aa2457d..5fbdc0c69 100644 --- a/library/src/methods/partial/partialAsync.ts +++ b/library/src/methods/partial/partialAsync.ts @@ -30,26 +30,31 @@ import type { } from '../../types/index.ts'; import { _getStandardProps } from '../../utils/index.ts'; -/** - * Schema type. - */ -type Schema = SchemaWithoutPipe< - | LooseObjectSchemaAsync< - ObjectEntriesAsync, - ErrorMessage | undefined - > - | ObjectSchemaAsync | undefined> - | ObjectWithRestSchemaAsync< - ObjectEntriesAsync, - | BaseSchema> - | BaseSchemaAsync>, - ErrorMessage | undefined - > - | StrictObjectSchemaAsync< - ObjectEntriesAsync, - ErrorMessage | undefined - > ->; +export namespace partialAsync { + /** + * Schema type. + */ + export type Schema = SchemaWithoutPipe< + | LooseObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + | ObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + | ObjectWithRestSchemaAsync< + ObjectEntriesAsync, + | BaseSchema> + | BaseSchemaAsync>, + ErrorMessage | undefined + > + | StrictObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + >; +} /** * Partial entries type. @@ -69,7 +74,7 @@ type PartialEntries< * Schema with partial type. */ export type SchemaWithPartialAsync< - TSchema extends Schema, + TSchema extends partialAsync.Schema, TKeys extends ObjectKeys | undefined, > = TSchema extends | ObjectSchemaAsync | undefined> @@ -259,7 +264,7 @@ export type SchemaWithPartialAsync< * * @returns An object schema. */ -export function partialAsync( +export function partialAsync( schema: TSchema ): SchemaWithPartialAsync; @@ -273,17 +278,23 @@ export function partialAsync( * @returns An object schema. */ export function partialAsync< - const TSchema extends Schema, + const TSchema extends partialAsync.Schema, const TKeys extends ObjectKeys, >(schema: TSchema, keys: TKeys): SchemaWithPartialAsync; // @__NO_SIDE_EFFECTS__ export function partialAsync( - schema: Schema, - keys?: ObjectKeys -): SchemaWithPartialAsync | undefined> { + schema: partialAsync.Schema, + keys?: ObjectKeys +): SchemaWithPartialAsync< + partialAsync.Schema, + ObjectKeys | undefined +> { // Create modified object entries - const entries: PartialEntries> = {}; + const entries: PartialEntries< + ObjectEntriesAsync, + ObjectKeys + > = {}; for (const key in schema.entries) { // @ts-expect-error entries[key] = diff --git a/library/src/methods/pick/pick.ts b/library/src/methods/pick/pick.ts index fcb8f6deb..e48a2b02c 100644 --- a/library/src/methods/pick/pick.ts +++ b/library/src/methods/pick/pick.ts @@ -34,43 +34,51 @@ import type { } from '../../types/index.ts'; import { _getStandardProps } from '../../utils/index.ts'; -/** - * The schema type. - */ -type Schema = SchemaWithoutPipe< - | LooseObjectSchema | undefined> - | LooseObjectSchemaAsync< - ObjectEntriesAsync, - ErrorMessage | undefined - > - | ObjectSchema | undefined> - | ObjectSchemaAsync | undefined> - | ObjectWithRestSchema< - ObjectEntries, - BaseSchema>, - ErrorMessage | undefined - > - | ObjectWithRestSchemaAsync< - ObjectEntriesAsync, - | BaseSchema> - | BaseSchemaAsync>, - ErrorMessage | undefined - > - | StrictObjectSchema< - ObjectEntries, - ErrorMessage | undefined - > - | StrictObjectSchemaAsync< - ObjectEntriesAsync, - ErrorMessage | undefined - > ->; +export namespace pick { + /** + * The schema type. + */ + export type Schema = SchemaWithoutPipe< + | LooseObjectSchema< + ObjectEntries, + ErrorMessage | undefined + > + | LooseObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + | ObjectSchema | undefined> + | ObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + | ObjectWithRestSchema< + ObjectEntries, + BaseSchema>, + ErrorMessage | undefined + > + | ObjectWithRestSchemaAsync< + ObjectEntriesAsync, + | BaseSchema> + | BaseSchemaAsync>, + ErrorMessage | undefined + > + | StrictObjectSchema< + ObjectEntries, + ErrorMessage | undefined + > + | StrictObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + >; +} /** * Schema with pick type. */ export type SchemaWithPick< - TSchema extends Schema, + TSchema extends pick.Schema, TKeys extends ObjectKeys, > = TSchema extends | ObjectSchema | undefined> @@ -465,7 +473,7 @@ export type SchemaWithPick< */ // @__NO_SIDE_EFFECTS__ export function pick< - const TSchema extends Schema, + const TSchema extends pick.Schema, const TKeys extends ObjectKeys, >(schema: TSchema, keys: TKeys): SchemaWithPick { // Create modified object entries diff --git a/library/src/methods/required/required.ts b/library/src/methods/required/required.ts index 2355c94bf..fdb6d9f28 100644 --- a/library/src/methods/required/required.ts +++ b/library/src/methods/required/required.ts @@ -30,22 +30,27 @@ import type { } from '../../types/index.ts'; import { _getStandardProps } from '../../utils/index.ts'; -/** - * Schema type. - */ -type Schema = SchemaWithoutPipe< - | LooseObjectSchema | undefined> - | ObjectSchema | undefined> - | ObjectWithRestSchema< - ObjectEntries, - BaseSchema>, - ErrorMessage | undefined - > - | StrictObjectSchema< - ObjectEntries, - ErrorMessage | undefined - > ->; +export namespace required { + /** + * Schema type. + */ + export type Schema = SchemaWithoutPipe< + | LooseObjectSchema< + ObjectEntries, + ErrorMessage | undefined + > + | ObjectSchema | undefined> + | ObjectWithRestSchema< + ObjectEntries, + BaseSchema>, + ErrorMessage | undefined + > + | StrictObjectSchema< + ObjectEntries, + ErrorMessage | undefined + > + >; +} /** * Required entries type. @@ -66,7 +71,7 @@ type RequiredEntries< * Schema with required type. */ export type SchemaWithRequired< - TSchema extends Schema, + TSchema extends required.Schema, TKeys extends ObjectKeys | undefined, TMessage extends ErrorMessage | undefined, > = TSchema extends @@ -257,7 +262,7 @@ export type SchemaWithRequired< */ // @ts-expect-error FIXME: TypeScript incorrectly claims that the overload // signature is not compatible with the implementation signature -export function required( +export function required( schema: TSchema ): SchemaWithRequired; @@ -270,7 +275,7 @@ export function required( * @returns An object schema. */ export function required< - const TSchema extends Schema, + const TSchema extends required.Schema, const TMessage extends ErrorMessage | undefined, >( schema: TSchema, @@ -287,7 +292,7 @@ export function required< * @returns An object schema. */ export function required< - const TSchema extends Schema, + const TSchema extends required.Schema, const TKeys extends ObjectKeys, >(schema: TSchema, keys: TKeys): SchemaWithRequired; @@ -302,7 +307,7 @@ export function required< * @returns An object schema. */ export function required< - const TSchema extends Schema, + const TSchema extends required.Schema, const TKeys extends ObjectKeys, const TMessage extends ErrorMessage | undefined, >( @@ -313,12 +318,12 @@ export function required< // @__NO_SIDE_EFFECTS__ export function required( - schema: Schema, - arg2?: ErrorMessage | ObjectKeys, + schema: required.Schema, + arg2?: ErrorMessage | ObjectKeys, arg3?: ErrorMessage ): SchemaWithRequired< - Schema, - ObjectKeys | undefined, + required.Schema, + ObjectKeys | undefined, ErrorMessage | undefined > { // Get keys and message from arguments @@ -330,7 +335,7 @@ export function required( // Create modified object entries const entries: RequiredEntries< ObjectEntries, - ObjectKeys, + ObjectKeys, ErrorMessage | undefined > = {}; for (const key in schema.entries) { diff --git a/library/src/methods/required/requiredAsync.ts b/library/src/methods/required/requiredAsync.ts index 20de2b5e1..01c1bf135 100644 --- a/library/src/methods/required/requiredAsync.ts +++ b/library/src/methods/required/requiredAsync.ts @@ -31,26 +31,31 @@ import type { } from '../../types/index.ts'; import { _getStandardProps } from '../../utils/index.ts'; -/** - * Schema type. - */ -type Schema = SchemaWithoutPipe< - | LooseObjectSchemaAsync< - ObjectEntriesAsync, - ErrorMessage | undefined - > - | ObjectSchemaAsync | undefined> - | ObjectWithRestSchemaAsync< - ObjectEntriesAsync, - | BaseSchema> - | BaseSchemaAsync>, - ErrorMessage | undefined - > - | StrictObjectSchemaAsync< - ObjectEntriesAsync, - ErrorMessage | undefined - > ->; +export namespace requiredAsync { + /** + * Schema type. + */ + export type Schema = SchemaWithoutPipe< + | LooseObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + | ObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + | ObjectWithRestSchemaAsync< + ObjectEntriesAsync, + | BaseSchema> + | BaseSchemaAsync>, + ErrorMessage | undefined + > + | StrictObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + >; +} /** * Required entries type. @@ -71,7 +76,7 @@ type RequiredEntries< * Schema with required type. */ export type SchemaWithRequiredAsync< - TSchema extends Schema, + TSchema extends requiredAsync.Schema, TKeys extends ObjectKeys | undefined, TMessage extends ErrorMessage | undefined, > = TSchema extends @@ -281,7 +286,7 @@ export function requiredAsync( * @returns An object schema. */ export function requiredAsync< - const TSchema extends Schema, + const TSchema extends requiredAsync.Schema, const TMessage extends ErrorMessage | undefined, >( schema: TSchema, @@ -298,7 +303,7 @@ export function requiredAsync< * @returns An object schema. */ export function requiredAsync< - const TSchema extends Schema, + const TSchema extends requiredAsync.Schema, const TKeys extends ObjectKeys, >( schema: TSchema, @@ -316,7 +321,7 @@ export function requiredAsync< * @returns An object schema. */ export function requiredAsync< - const TSchema extends Schema, + const TSchema extends requiredAsync.Schema, const TKeys extends ObjectKeys, const TMessage extends ErrorMessage | undefined, >( @@ -327,12 +332,12 @@ export function requiredAsync< // @__NO_SIDE_EFFECTS__ export function requiredAsync( - schema: Schema, - arg2?: ErrorMessage | ObjectKeys, + schema: requiredAsync.Schema, + arg2?: ErrorMessage | ObjectKeys, arg3?: ErrorMessage ): SchemaWithRequiredAsync< - Schema, - ObjectKeys | undefined, + requiredAsync.Schema, + ObjectKeys | undefined, ErrorMessage | undefined > { // Get keys and message from arguments @@ -344,7 +349,7 @@ export function requiredAsync( // Create modified object entries const entries: RequiredEntries< ObjectEntriesAsync, - ObjectKeys, + ObjectKeys, ErrorMessage | undefined > = {}; for (const key in schema.entries) { diff --git a/library/src/utils/_getLastMetadata/_getLastMetadata.ts b/library/src/utils/_getLastMetadata/_getLastMetadata.ts index f9bd93175..fed0671c1 100644 --- a/library/src/utils/_getLastMetadata/_getLastMetadata.ts +++ b/library/src/utils/_getLastMetadata/_getLastMetadata.ts @@ -11,39 +11,41 @@ import type { PipeItemAsync, } from '../../types/index.ts'; -/** - * Metadata action type. - */ -type MetadataAction = - | TitleAction - | DescriptionAction; +export namespace _getLastMetadata { + /** + * Metadata action type. + */ + type MetadataAction = + | TitleAction + | DescriptionAction; -/** - * Schema type. - */ -type Schema = - | BaseSchema> - | BaseSchemaAsync> - | SchemaWithPipe< - readonly [ - BaseSchema>, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ...(PipeItem> | MetadataAction)[], - ] - > - | SchemaWithPipeAsync< - readonly [ - ( - | BaseSchema> - | BaseSchemaAsync> - ), - ...( - | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any - | PipeItemAsync> // eslint-disable-line @typescript-eslint/no-explicit-any - | MetadataAction - )[], - ] - >; + /** + * Schema type. + */ + export type Schema = + | BaseSchema> + | BaseSchemaAsync> + | SchemaWithPipe< + readonly [ + BaseSchema>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ...(PipeItem> | MetadataAction)[], + ] + > + | SchemaWithPipeAsync< + readonly [ + ( + | BaseSchema> + | BaseSchemaAsync> + ), + ...( + | PipeItem> // eslint-disable-line @typescript-eslint/no-explicit-any + | PipeItemAsync> // eslint-disable-line @typescript-eslint/no-explicit-any + | MetadataAction + )[], + ] + >; +} /** * Returns the last top-level value of a given metadata type from a schema @@ -58,11 +60,11 @@ type Schema = */ // @__NO_SIDE_EFFECTS__ export function _getLastMetadata( - schema: Schema, + schema: _getLastMetadata.Schema, type: 'title' | 'description' ): string | undefined { if ('pipe' in schema) { - const nestedSchemas: Schema[] = []; + const nestedSchemas: _getLastMetadata.Schema[] = []; for (let index = schema.pipe.length - 1; index >= 0; index--) { const item = schema.pipe[index]; if (item.kind === 'schema' && 'pipe' in item) { diff --git a/library/src/utils/entriesFromObjects/entriesFromObjects.ts b/library/src/utils/entriesFromObjects/entriesFromObjects.ts index d73ce912a..dc0291085 100644 --- a/library/src/utils/entriesFromObjects/entriesFromObjects.ts +++ b/library/src/utils/entriesFromObjects/entriesFromObjects.ts @@ -23,56 +23,76 @@ import type { Prettify, } from '../../types/index.ts'; -/** - * Schema type. - */ -type Schema = - | LooseObjectSchema | undefined> - | LooseObjectSchemaAsync< - ObjectEntriesAsync, - ErrorMessage | undefined - > - | ObjectSchema | undefined> - | ObjectSchemaAsync | undefined> - | ObjectWithRestSchema< - ObjectEntries, - BaseSchema>, - ErrorMessage | undefined - > - | ObjectWithRestSchemaAsync< - ObjectEntriesAsync, - | BaseSchema> - | BaseSchemaAsync>, - ErrorMessage | undefined - > - | StrictObjectSchema< - ObjectEntries, - ErrorMessage | undefined - > - | StrictObjectSchemaAsync< - ObjectEntriesAsync, - ErrorMessage | undefined - >; +export namespace entriesFromObjects { + /** + * Schema type. + */ + export type Schema = + | LooseObjectSchema< + ObjectEntries, + ErrorMessage | undefined + > + | LooseObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + | ObjectSchema | undefined> + | ObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + > + | ObjectWithRestSchema< + ObjectEntries, + BaseSchema>, + ErrorMessage | undefined + > + | ObjectWithRestSchemaAsync< + ObjectEntriesAsync, + | BaseSchema> + | BaseSchemaAsync>, + ErrorMessage | undefined + > + | StrictObjectSchema< + ObjectEntries, + ErrorMessage | undefined + > + | StrictObjectSchemaAsync< + ObjectEntriesAsync, + ErrorMessage | undefined + >; +} /** * Recursive merge type. */ -type RecursiveMerge = - TSchemas extends readonly [infer TFirstSchema extends Schema] - ? TFirstSchema['entries'] - : TSchemas extends readonly [ - infer TFirstSchema extends Schema, - ...infer TRestSchemas extends readonly [Schema, ...Schema[]], - ] - ? Merge> - : never; +type RecursiveMerge< + TSchemas extends readonly [ + entriesFromObjects.Schema, + ...entriesFromObjects.Schema[], + ], +> = TSchemas extends readonly [ + infer TFirstSchema extends entriesFromObjects.Schema, +] + ? TFirstSchema['entries'] + : TSchemas extends readonly [ + infer TFirstSchema extends entriesFromObjects.Schema, + ...infer TRestSchemas extends readonly [ + entriesFromObjects.Schema, + ...entriesFromObjects.Schema[], + ], + ] + ? Merge> + : never; /** * Merged entries types. */ -type MergedEntries = Prettify< - RecursiveMerge ->; +type MergedEntries< + TSchemas extends readonly [ + entriesFromObjects.Schema, + ...entriesFromObjects.Schema[], + ], +> = Prettify>; /** * Creates a new object entries definition from existing object schemas. @@ -82,13 +102,16 @@ type MergedEntries = Prettify< * @returns The object entries from the schemas. */ export function entriesFromObjects< - const TSchemas extends readonly [Schema, ...Schema[]], + const TSchemas extends readonly [ + entriesFromObjects.Schema, + ...entriesFromObjects.Schema[], + ], >(schemas: TSchemas): MergedEntries; // @__NO_SIDE_EFFECTS__ export function entriesFromObjects( - schemas: [Schema, ...Schema[]] -): MergedEntries<[Schema, ...Schema[]]> { + schemas: [entriesFromObjects.Schema, ...entriesFromObjects.Schema[]] +): MergedEntries<[entriesFromObjects.Schema, ...entriesFromObjects.Schema[]]> { const entries = {}; for (const schema of schemas) { Object.assign(entries, schema.entries); diff --git a/packages/to-json-schema/eslint.config.js b/packages/to-json-schema/eslint.config.js index 82b369a20..970a819f9 100644 --- a/packages/to-json-schema/eslint.config.js +++ b/packages/to-json-schema/eslint.config.js @@ -63,6 +63,7 @@ export default tseslint.config( // TypeScript '@typescript-eslint/ban-ts-comment': 'off', '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-namespace': 'off', // Imports 'no-duplicate-imports': 'off', diff --git a/packages/to-json-schema/src/converters/convertSchema/convertSchema.ts b/packages/to-json-schema/src/converters/convertSchema/convertSchema.ts index ef8dc3f5b..3b056cd1d 100644 --- a/packages/to-json-schema/src/converters/convertSchema/convertSchema.ts +++ b/packages/to-json-schema/src/converters/convertSchema/convertSchema.ts @@ -4,107 +4,123 @@ import type { ConversionConfig, ConversionContext } from '../../type.ts'; import { addError, handleError } from '../../utils/index.ts'; import { convertAction } from '../convertAction/index.ts'; -/** - * Schema type. - */ -type Schema = - | v.AnySchema - | v.UnknownSchema - | v.NullableSchema< - v.BaseSchema>, - v.Default>, null> - > - | v.NullishSchema< - v.BaseSchema>, - v.Default< +export namespace convertSchema { + /** + * Schema type. + */ + export type Schema = + | v.AnySchema + | v.UnknownSchema + | v.NullableSchema< + v.BaseSchema>, + v.Default>, null> + > + | v.NullishSchema< + v.BaseSchema>, + v.Default< + v.BaseSchema>, + null | undefined + > + > + | v.NullSchema | undefined> + | v.StringSchema | undefined> + | v.BooleanSchema | undefined> + | v.NumberSchema | undefined> + | v.LiteralSchema | undefined> + | v.PicklistSchema< + v.PicklistOptions, + v.ErrorMessage | undefined + > + | v.EnumSchema | undefined> + | v.VariantSchema< + string, + v.VariantOptions, + v.ErrorMessage | undefined + > + | v.UnionSchema< + v.UnionOptions, + v.ErrorMessage>> | undefined + > + | v.IntersectSchema< + v.IntersectOptions, + v.ErrorMessage | undefined + > + | v.ObjectSchema | undefined> + | v.ObjectWithRestSchema< + v.ObjectEntries, + v.BaseSchema>, + v.ErrorMessage | undefined + > + | v.ExactOptionalSchema< + v.BaseSchema>, + v.Default< + v.BaseSchema>, + undefined + > + > + | v.OptionalSchema< v.BaseSchema>, - null | undefined + v.Default< + v.BaseSchema>, + undefined + > > - > - | v.NullSchema | undefined> - | v.StringSchema | undefined> - | v.BooleanSchema | undefined> - | v.NumberSchema | undefined> - | v.LiteralSchema | undefined> - | v.PicklistSchema< - v.PicklistOptions, - v.ErrorMessage | undefined - > - | v.EnumSchema | undefined> - | v.VariantSchema< - string, - v.VariantOptions, - v.ErrorMessage | undefined - > - | v.UnionSchema< - v.UnionOptions, - v.ErrorMessage>> | undefined - > - | v.IntersectSchema< - v.IntersectOptions, - v.ErrorMessage | undefined - > - | v.ObjectSchema | undefined> - | v.ObjectWithRestSchema< - v.ObjectEntries, - v.BaseSchema>, - v.ErrorMessage | undefined - > - | v.ExactOptionalSchema< - v.BaseSchema>, - v.Default>, undefined> - > - | v.OptionalSchema< - v.BaseSchema>, - v.Default>, undefined> - > - | v.UndefinedableSchema< - v.BaseSchema>, - v.Default>, undefined> - > - | v.StrictObjectSchema< - v.ObjectEntries, - v.ErrorMessage | undefined - > - | v.LooseObjectSchema< - v.ObjectEntries, - v.ErrorMessage | undefined - > - | v.RecordSchema< - v.BaseSchema>, - v.BaseSchema>, - v.ErrorMessage | undefined - > - | v.TupleSchema | undefined> - | v.TupleWithRestSchema< - v.TupleItems, - v.BaseSchema>, - v.ErrorMessage | undefined - > - | v.LooseTupleSchema< - v.TupleItems, - v.ErrorMessage | undefined - > - | v.StrictTupleSchema< - v.TupleItems, - v.ErrorMessage | undefined - > - | v.ArraySchema< - v.BaseSchema>, - v.ErrorMessage | undefined - > - | v.LazySchema>>; + | v.UndefinedableSchema< + v.BaseSchema>, + v.Default< + v.BaseSchema>, + undefined + > + > + | v.StrictObjectSchema< + v.ObjectEntries, + v.ErrorMessage | undefined + > + | v.LooseObjectSchema< + v.ObjectEntries, + v.ErrorMessage | undefined + > + | v.RecordSchema< + v.BaseSchema>, + v.BaseSchema>, + v.ErrorMessage | undefined + > + | v.TupleSchema | undefined> + | v.TupleWithRestSchema< + v.TupleItems, + v.BaseSchema>, + v.ErrorMessage | undefined + > + | v.LooseTupleSchema< + v.TupleItems, + v.ErrorMessage | undefined + > + | v.StrictTupleSchema< + v.TupleItems, + v.ErrorMessage | undefined + > + | v.ArraySchema< + v.BaseSchema>, + v.ErrorMessage | undefined + > + | v.LazySchema>>; +} /** * Pipe type. */ -// eslint-disable-next-line @typescript-eslint/no-explicit-any -type Pipe = readonly (Schema | v.PipeAction>)[]; + +type Pipe = readonly ( + | convertSchema.Schema + | v.PipeAction> +)[]; /** * Schema or pipe type. */ -type SchemaOrPipe = Schema | v.SchemaWithPipe; +type SchemaOrPipe = + | convertSchema.Schema + | v.SchemaWithPipe; /** * Flattens a Valibot pipe by recursively expanding nested pipes.