diff --git a/library/src/schemas/index.ts b/library/src/schemas/index.ts index 1d43af2a2..794cfac1b 100644 --- a/library/src/schemas/index.ts +++ b/library/src/schemas/index.ts @@ -26,6 +26,7 @@ export * from './nullable/index.ts'; export * from './nullish/index.ts'; export * from './number/index.ts'; export * from './object/index.ts'; +export * from './recordWithPatterns/index.ts'; export * from './objectWithRest/index.ts'; export * from './optional/index.ts'; export * from './picklist/index.ts'; diff --git a/library/src/schemas/recordWithPatterns/index.ts b/library/src/schemas/recordWithPatterns/index.ts new file mode 100644 index 000000000..66b1da8bc --- /dev/null +++ b/library/src/schemas/recordWithPatterns/index.ts @@ -0,0 +1,3 @@ +export * from './recordWithPatterns.ts'; +export * from './recordWithPatternsAsync.ts'; +export * from './types.ts'; diff --git a/library/src/schemas/recordWithPatterns/recordWithPatterns.test-d.ts b/library/src/schemas/recordWithPatterns/recordWithPatterns.test-d.ts new file mode 100644 index 000000000..8c07a0440 --- /dev/null +++ b/library/src/schemas/recordWithPatterns/recordWithPatterns.test-d.ts @@ -0,0 +1,136 @@ +import { describe, expectTypeOf, test } from 'vitest'; +import { transform } from '../../actions/index.ts'; +import { pipe } from '../../methods/index.ts'; +import type { InferInput, InferIssue, InferOutput } from '../../types/index.ts'; +import type { BooleanIssue, BooleanSchema } from '../boolean/boolean.ts'; +import { boolean } from '../boolean/boolean.ts'; +import { custom } from '../custom/custom.ts'; +import type { CustomIssue } from '../custom/types.ts'; +import type { NumberIssue, NumberSchema } from '../number/number.ts'; +import { number } from '../number/number.ts'; +import type { StringIssue, StringSchema } from '../string/string.ts'; +import { string } from '../string/string.ts'; +import type { RecordWithPatternsSchema } from './recordWithPatterns.ts'; +import { recordWithPatterns } from './recordWithPatterns.ts'; +import type { RecordWithPatternsIssue } from './types.ts'; + +const FooKeySchema = custom<`foo(${string})`>( + (input) => + typeof input === 'string' && input.startsWith('foo(') && input.endsWith(')') +); + +const BarKeySchema = pipe( + custom<`bar(${string})`>( + (input) => + typeof input === 'string' && + input.startsWith('bar(') && + input.endsWith(')') + ), + transform((input) => input.toUpperCase() as Uppercase) +); + +describe('recordWithPatterns', () => { + describe('should return schema object', () => { + test('without message', () => { + expectTypeOf( + recordWithPatterns( + [ + [FooKeySchema, string()], + [BarKeySchema, number()], + ], + boolean() + ) + ).toEqualTypeOf< + RecordWithPatternsSchema< + readonly [ + readonly [typeof FooKeySchema, StringSchema], + readonly [typeof BarKeySchema, NumberSchema], + ], + BooleanSchema, + undefined + > + >(); + }); + test('with message', () => { + expectTypeOf( + recordWithPatterns( + [ + [FooKeySchema, string()], + [BarKeySchema, number()], + ], + boolean(), + 'message' + ) + ).toEqualTypeOf< + RecordWithPatternsSchema< + readonly [ + readonly [typeof FooKeySchema, StringSchema], + readonly [typeof BarKeySchema, NumberSchema], + ], + BooleanSchema, + 'message' + > + >(); + }); + }); + describe('should return inference types', () => { + test('of input', () => { + expectTypeOf< + InferInput< + RecordWithPatternsSchema< + readonly [ + readonly [typeof FooKeySchema, StringSchema], + readonly [typeof BarKeySchema, NumberSchema], + ], + BooleanSchema, + undefined + > + > + >().toEqualTypeOf< + { + [key: `foo(${string})`]: string | undefined; + [key: `bar(${string})`]: number | undefined; + } & { [key: string]: boolean } + >(); + }); + test('of output', () => { + expectTypeOf< + InferOutput< + RecordWithPatternsSchema< + readonly [ + readonly [typeof FooKeySchema, StringSchema], + readonly [typeof BarKeySchema, NumberSchema], + ], + BooleanSchema, + undefined + > + > + >().toEqualTypeOf< + { + [key: `foo(${string})`]: string | undefined; + [key: `BAR(${Uppercase})`]: number | undefined; + } & { [key: string]: boolean } + >(); + }); + test('of issue', () => { + expectTypeOf< + InferIssue< + RecordWithPatternsSchema< + readonly [ + readonly [typeof FooKeySchema, StringSchema], + readonly [typeof BarKeySchema, NumberSchema], + ], + BooleanSchema, + undefined + > + > + >().toEqualTypeOf< + | RecordWithPatternsIssue + | CustomIssue + | StringIssue + | NumberIssue + | BooleanIssue + >(); + }); + }); +}); diff --git a/library/src/schemas/recordWithPatterns/recordWithPatterns.test.ts b/library/src/schemas/recordWithPatterns/recordWithPatterns.test.ts new file mode 100644 index 000000000..e3c6a32b9 --- /dev/null +++ b/library/src/schemas/recordWithPatterns/recordWithPatterns.test.ts @@ -0,0 +1,378 @@ +import { describe, expect, test } from 'vitest'; +import { transform } from '../../actions/index.ts'; +import { pipe } from '../../methods/index.ts'; +import { + boolean, + custom, + never, + number, + object, + string, +} from '../../schemas/index.ts'; +import type { FailureDataset } from '../../types/dataset.ts'; +import type { InferIssue } from '../../types/infer.ts'; +import { expectNoSchemaIssue } from '../../vitest/expectNoSchemaIssue.ts'; +import { expectSchemaIssue } from '../../vitest/expectSchemaIssue.ts'; +import type { RecordWithPatternsSchema } from './recordWithPatterns.ts'; +import { recordWithPatterns } from './recordWithPatterns.ts'; +import type { RecordWithPatternsIssue } from './types.ts'; + +const FooKeySchema = custom<`foo(${string})`>( + (input) => + typeof input === 'string' && input.startsWith('foo(') && input.endsWith(')') +); + +const BarKeySchema = pipe( + custom<`bar(${string})`>( + (input) => + typeof input === 'string' && + input.startsWith('bar(') && + input.endsWith(')') + ), + transform((input) => input.toUpperCase() as Uppercase) +); + +describe('recordWithPatterns', () => { + describe('should return schema object', () => { + const patterns = [ + [FooKeySchema, string()], + [BarKeySchema, number()], + ] as const; + type Patterns = typeof patterns; + const rest = boolean(); + type Rest = typeof rest; + const baseSchema: Omit< + RecordWithPatternsSchema, + 'message' + > = { + kind: 'schema', + type: 'record_with_patterns', + reference: recordWithPatterns, + expects: 'Object', + patterns, + rest, + async: false, + '~standard': { + version: 1, + vendor: 'valibot', + validate: expect.any(Function), + }, + '~run': expect.any(Function), + }; + test('without message', () => { + expect(recordWithPatterns(patterns, rest)).toStrictEqual({ + ...baseSchema, + message: undefined, + }); + }); + test('with message', () => { + expect(recordWithPatterns(patterns, rest, 'message')).toStrictEqual({ + ...baseSchema, + message: 'message', + }); + }); + }); + describe('should return dataset without issues', () => { + test('for empty object', () => { + expectNoSchemaIssue( + recordWithPatterns([[FooKeySchema, string()]], boolean()), + [{}] + ); + }); + test('for simple object', () => { + expect( + recordWithPatterns( + [ + [FooKeySchema, string()], + [BarKeySchema, number()], + ], + boolean() + )['~run']( + { value: { 'foo(bar)': 'foo', 'bar(baz)': 123, other: true } }, + {} + ) + ).toStrictEqual({ + typed: true, + value: { 'foo(bar)': 'foo', 'BAR(BAZ)': 123, other: true }, + }); + }); + }); + describe('should return dataset with issues', () => { + const schema = recordWithPatterns( + [[FooKeySchema, string()]], + never(), + 'message' + ); + const baseIssue: Omit = { + kind: 'schema', + type: 'record_with_patterns', + expected: 'Object', + message: 'message', + }; + + // for primitive types + + test('for bigints', () => { + expectSchemaIssue(schema, baseIssue, [-1n, 0n, 123n]); + }); + + test('for booleans', () => { + expectSchemaIssue(schema, baseIssue, [true, false]); + }); + + test('for null', () => { + expectSchemaIssue(schema, baseIssue, [null]); + }); + + test('for numbers', () => { + expectSchemaIssue(schema, baseIssue, [-1, 0, 123, 45.67]); + }); + + test('for strings', () => { + expectSchemaIssue(schema, baseIssue, ['foo', 'bar', 'baz']); + }); + + test('for symbols', () => { + expectSchemaIssue(schema, baseIssue, [ + Symbol('foo'), + Symbol('bar'), + Symbol('baz'), + ]); + }); + + // complex types + + // TODO: Enable this test again in case we find a reliable way to check for + // plain objects + // test('for arrays', () => { + // expectSchemaIssue(schema, baseIssue, [[], ['value']]); + // }); + + test('for functions', () => { + // eslint-disable-next-line @typescript-eslint/no-empty-function + expectSchemaIssue(schema, baseIssue, [() => {}, function () {}]); + }); + }); + + describe('should return dataset without nested issues', () => { + test('for simple object', () => { + expectNoSchemaIssue( + recordWithPatterns([[FooKeySchema, string()]], boolean()), + // @ts-expect-error + [{ 'foo(bar)': 'foo', other: true }] + ); + }); + + test('for nested object', () => { + expectNoSchemaIssue( + recordWithPatterns( + [[FooKeySchema, object({ key: string() })]], + object({ key: number() }) + ), + // @ts-expect-error + [{ 'foo(bar)': { key: 'foo' }, other: { key: 123 } }] + ); + }); + }); + describe('should return dataset with nested issues', () => { + const schema = recordWithPatterns( + [ + [FooKeySchema, string()], + [BarKeySchema, object({ key: number() })], + ], + object({ key: number() }), + 'message' + ); + + const baseInfo = { + message: expect.any(String), + requirement: undefined, + issues: undefined, + lang: undefined, + abortEarly: undefined, + abortPipeEarly: undefined, + }; + + test('for invalid entries', () => { + const input = { 'foo(bar)': false, 'bar(baz)': '123', other: 'foo' }; + expect(schema['~run']({ value: input }, {})).toStrictEqual({ + typed: false, + value: { 'foo(bar)': false, 'BAR(BAZ)': '123', other: 'foo' }, + issues: [ + { + ...baseInfo, + kind: 'schema', + type: 'string', + input: false, + expected: 'string', + received: 'false', + path: [ + { + type: 'object', + origin: 'value', + input, + key: 'foo(bar)', + value: false, + }, + ], + }, + { + ...baseInfo, + kind: 'schema', + type: 'object', + input: '123', + expected: 'Object', + received: '"123"', + path: [ + { + type: 'object', + origin: 'value', + input, + key: 'bar(baz)', + value: '123', + }, + ], + }, + { + ...baseInfo, + kind: 'schema', + type: 'object', + input: 'foo', + expected: 'Object', + received: '"foo"', + path: [ + { + type: 'object', + origin: 'value', + input, + key: 'other', + value: 'foo', + }, + ], + }, + ], + } satisfies FailureDataset>); + }); + test('for invalid nested entries', () => { + const input = { 'bar(baz)': { key: '123' } }; + expect(schema['~run']({ value: input }, {})).toStrictEqual({ + typed: false, + value: { 'BAR(BAZ)': { key: '123' } }, + issues: [ + { + ...baseInfo, + kind: 'schema', + type: 'number', + input: '123', + expected: 'number', + received: '"123"', + path: [ + { + type: 'object', + origin: 'value', + input, + key: 'bar(baz)', + value: input['bar(baz)'], + }, + { + type: 'object', + origin: 'value', + input: input['bar(baz)'], + key: 'key', + value: '123', + }, + ], + }, + ], + } satisfies FailureDataset>); + }); + test('for invalid entries with abort early', () => { + const input = { 'foo(bar)': false, 'bar(baz)': '123', other: 'foo' }; + expect( + schema['~run']({ value: input }, { abortEarly: true }) + ).toStrictEqual({ + typed: false, + value: {}, + issues: [ + { + ...baseInfo, + kind: 'schema', + type: 'string', + input: false, + expected: 'string', + received: 'false', + path: [ + { + type: 'object', + origin: 'value', + input, + key: 'foo(bar)', + value: false, + }, + ], + abortEarly: true, + }, + ], + }); + }); + test('for wrong rest', () => { + const input = { 'foo(bar)': 'foo', other: 'foo' }; + expect(schema['~run']({ value: input }, {})).toStrictEqual({ + typed: false, + value: input, + issues: [ + { + ...baseInfo, + kind: 'schema', + type: 'object', + input: 'foo', + expected: 'Object', + received: '"foo"', + path: [ + { + type: 'object', + origin: 'value', + input, + key: 'other', + value: 'foo', + }, + ], + }, + ], + }); + }); + test('for wrong nested rest', () => { + const input = { other: { key: 'foo' } }; + expect(schema['~run']({ value: input }, {})).toStrictEqual({ + typed: false, + value: input, + issues: [ + { + ...baseInfo, + kind: 'schema', + type: 'number', + input: 'foo', + expected: 'number', + received: '"foo"', + path: [ + { + type: 'object', + origin: 'value', + input, + key: 'other', + value: input.other, + }, + { + type: 'object', + origin: 'value', + input: input.other, + key: 'key', + value: 'foo', + }, + ], + }, + ], + } satisfies FailureDataset>); + }); + }); +}); diff --git a/library/src/schemas/recordWithPatterns/recordWithPatterns.ts b/library/src/schemas/recordWithPatterns/recordWithPatterns.ts new file mode 100644 index 000000000..cb24699df --- /dev/null +++ b/library/src/schemas/recordWithPatterns/recordWithPatterns.ts @@ -0,0 +1,254 @@ +import type { + BaseIssue, + BaseSchema, + ErrorMessage, + InferInput, + InferIssue, + InferOutput, + ObjectPathItem, + OutputDataset, + Prettify, +} from '../../types/index.ts'; +import { + _addIssue, + _getStandardProps, + _isValidObjectKey, +} from '../../utils/index.ts'; +import type { RecordWithPatternsIssue } from './types.ts'; + +export type PatternTuple = readonly [ + key: BaseSchema>, + value: BaseSchema>, +]; + +export type PatternTuples = readonly [PatternTuple, ...PatternTuple[]]; + +export type InferPatternInput = { + [K in InferInput]?: InferInput; +}; + +export type InferPatternsInput = + TPatterns extends readonly [infer TPattern extends PatternTuple] + ? InferPatternInput + : TPatterns extends readonly [ + infer TPattern extends PatternTuple, + ...infer TRest extends PatternTuples, + ] + ? InferPatternInput & InferPatternsInput + : never; + +export type InferPatternIssue = InferIssue< + TPattern[number] +>; + +export type InferPatternsIssue = + InferPatternIssue; + +export type InferPatternOutput = { + [K in InferOutput]?: InferOutput; +}; + +export type InferPatternsOutput = + TPatterns extends readonly [infer TPattern extends PatternTuple] + ? InferPatternOutput + : TPatterns extends readonly [ + infer TPattern extends PatternTuple, + ...infer TRest extends PatternTuples, + ] + ? InferPatternOutput & InferPatternsOutput + : never; + +export interface RecordWithPatternsSchema< + TPatterns extends PatternTuples, + TRest extends BaseSchema>, + TMessage extends ErrorMessage | undefined, +> extends BaseSchema< + Prettify> & { + [key: string]: InferInput; + }, + Prettify> & { + [key: string]: InferOutput; + }, + RecordWithPatternsIssue | InferPatternsIssue | InferIssue + > { + /** + * The schema type. + */ + readonly type: 'record_with_patterns'; + /** + * The schema reference. + */ + readonly reference: typeof recordWithPatterns; + /** + * The expected property. + */ + readonly expects: 'Object'; + /** + * The patterns schema. + */ + readonly patterns: TPatterns; + /** + * The rest schema. + */ + readonly rest: TRest; + /** + * The error message. + */ + readonly message: TMessage; +} + +/** + * Creates a record schema that matches patterns. + * + * @param patterns Pairs of key and value schemas. + * @param rest Schema to use when no pattern matches. + * + * @returns A record schema. + */ +export function recordWithPatterns< + const TPatterns extends PatternTuples, + const TRest extends BaseSchema>, +>( + patterns: TPatterns, + rest: TRest +): RecordWithPatternsSchema; + +/** + * Creates a record schema that matches patterns. + * + * @param patterns Pairs of key and value schemas. + * @param rest Schema to use when no pattern matches. + * @param message The error message. + * + * @returns A record schema. + */ +export function recordWithPatterns< + const TPatterns extends PatternTuples, + const TRest extends BaseSchema>, + const TMessage extends ErrorMessage | undefined, +>( + patterns: TPatterns, + rest: TRest, + message: TMessage +): RecordWithPatternsSchema; + +// @__NO_SIDE_EFFECTS__ +export function recordWithPatterns( + patterns: PatternTuples, + rest: BaseSchema>, + message?: ErrorMessage +): RecordWithPatternsSchema< + PatternTuples, + BaseSchema>, + ErrorMessage | undefined +> { + return { + kind: 'schema', + type: 'record_with_patterns', + reference: recordWithPatterns, + expects: 'Object', + async: false, + patterns, + rest, + message, + get '~standard'() { + return _getStandardProps(this); + }, + '~run'(dataset, config) { + // Get input value from dataset + const input = dataset.value; + + // If root type is valid, check nested types + if (input && typeof input === 'object') { + // Set typed to `true` and value to empty object + // @ts-expect-error + dataset.typed = true; + dataset.value = {}; + + // Parse schema of each pattern + for (const key in input) { + // exclude specific keys for security reasons + if (!_isValidObjectKey(input, key)) continue; + + // Get pattern schema and new key + + let valueSchema: + | BaseSchema> + | undefined; + let newKey = key; + for (const [keySchema, valueSchema_] of patterns) { + const keyDataset = keySchema['~run']({ value: key }, config); + if (keyDataset.typed) { + valueSchema = valueSchema_; + newKey = keyDataset.value; + break; + } + } + + // if no pattern matches, use rest schema + if (!valueSchema) { + valueSchema = rest; + } + + // @ts-expect-error + const value = input[key]; + const valueDataset = valueSchema['~run']({ value }, config); + + // If there are issues, capture them + if (valueDataset.issues) { + // Create object path item + const pathItem: ObjectPathItem = { + type: 'object', + origin: 'value', + input: input as Record, + key, + value, + }; + + // Add modified entry dataset issues to issues + for (const issue of valueDataset.issues) { + if (issue.path) { + issue.path.unshift(pathItem); + } else { + // @ts-expect-error + issue.path = [pathItem]; + } + // @ts-expect-error + dataset.issues?.push(issue); + } + if (!dataset.issues) { + // @ts-expect-error + dataset.issues = valueDataset.issues; + } + + // If necessary, abort early + if (config.abortEarly) { + dataset.typed = false; + break; + } + } + + // If not typed, set typed to `false` + if (!valueDataset.typed) { + dataset.typed = false; + } + + // Add entry to dataset + // @ts-expect-error + dataset.value[newKey] = valueDataset.value; + } + // Otherwise, add object issue + } else { + _addIssue(this, 'type', dataset, config); + } + // Return output dataset + // @ts-expect-error + return dataset as OutputDataset< + InferPatternsOutput & { [key: string]: unknown }, + | RecordWithPatternsIssue + | InferPatternsIssue + | BaseIssue + >; + }, + }; +} diff --git a/library/src/schemas/recordWithPatterns/recordWithPatternsAsync.test-d.ts b/library/src/schemas/recordWithPatterns/recordWithPatternsAsync.test-d.ts new file mode 100644 index 000000000..04adf5bb7 --- /dev/null +++ b/library/src/schemas/recordWithPatterns/recordWithPatternsAsync.test-d.ts @@ -0,0 +1,135 @@ +import { describe, expectTypeOf, test } from 'vitest'; +import { transformAsync } from '../../actions/index.ts'; +import { pipeAsync } from '../../methods/index.ts'; +import type { + CustomIssue, + RecordWithPatternsIssue, + RecordWithPatternsSchemaAsync, + StringIssue, + StringSchema, +} from '../../schemas/index.ts'; +import { + customAsync, + recordWithPatternsAsync, + string, +} from '../../schemas/index.ts'; +import type { InferInput, InferIssue, InferOutput } from '../../types/index.ts'; + +const FooKeySchema = customAsync<`foo(${string})`>( + (input) => + typeof input === 'string' && input.startsWith('foo(') && input.endsWith(')') +); + +const BarKeySchema = pipeAsync( + customAsync<`bar(${string})`>( + (input) => + typeof input === 'string' && + input.startsWith('bar(') && + input.endsWith(')') + ), + transformAsync( + async (input) => input.toUpperCase() as Uppercase + ) +); + +describe('recordWithPatternsAsync', () => { + describe('should return schema object', () => { + test('without message', () => { + expectTypeOf( + recordWithPatternsAsync( + [ + [FooKeySchema, string()], + [BarKeySchema, string()], + ], + string() + ) + ).toEqualTypeOf< + RecordWithPatternsSchemaAsync< + readonly [ + readonly [typeof FooKeySchema, StringSchema], + readonly [typeof BarKeySchema, StringSchema], + ], + StringSchema, + undefined + > + >(); + }); + + test('with message', () => { + expectTypeOf( + recordWithPatternsAsync( + [ + [FooKeySchema, string()], + [BarKeySchema, string()], + ], + string(), + 'message' + ) + ).toEqualTypeOf< + RecordWithPatternsSchemaAsync< + readonly [ + readonly [typeof FooKeySchema, StringSchema], + readonly [typeof BarKeySchema, StringSchema], + ], + StringSchema, + 'message' + > + >(); + }); + }); + + describe('should return inferred type', () => { + test('of input', () => { + expectTypeOf< + InferInput< + RecordWithPatternsSchemaAsync< + readonly [ + readonly [typeof FooKeySchema, StringSchema], + readonly [typeof BarKeySchema, StringSchema], + ], + StringSchema, + undefined + > + > + >().toEqualTypeOf< + { + [key: `foo(${string})`]: string | undefined; + [key: `bar(${string})`]: string | undefined; + } & { [key: string]: string } + >(); + }); + test('of output', () => { + expectTypeOf< + InferOutput< + RecordWithPatternsSchemaAsync< + readonly [ + readonly [typeof FooKeySchema, StringSchema], + readonly [typeof BarKeySchema, StringSchema], + ], + StringSchema, + undefined + > + > + >().toEqualTypeOf< + { + [key: `foo(${string})`]: string | undefined; + [key: `BAR(${Uppercase})`]: string | undefined; + } & { [key: string]: string } + >(); + }); + test('of issue', () => { + expectTypeOf< + InferIssue< + RecordWithPatternsSchemaAsync< + readonly [ + readonly [typeof FooKeySchema, StringSchema], + readonly [typeof BarKeySchema, StringSchema], + ], + StringSchema, + undefined + > + > + >().toEqualTypeOf(); + }); + }); +}); diff --git a/library/src/schemas/recordWithPatterns/recordWithPatternsAsync.test.ts b/library/src/schemas/recordWithPatterns/recordWithPatternsAsync.test.ts new file mode 100644 index 000000000..12ca0eef8 --- /dev/null +++ b/library/src/schemas/recordWithPatterns/recordWithPatternsAsync.test.ts @@ -0,0 +1,353 @@ +import { describe, expect, test } from 'vitest'; +import { transformAsync } from '../../actions/index.ts'; +import { pipeAsync } from '../../methods/index.ts'; +import type { + RecordWithPatternsIssue, + RecordWithPatternsSchemaAsync, +} from '../../schemas/index.ts'; +import { + boolean, + customAsync, + never, + number, + objectAsync, + recordWithPatternsAsync, + string, +} from '../../schemas/index.ts'; +import { FailureDataset } from '../../types/dataset.ts'; +import { InferIssue } from '../../types/infer.ts'; +import { + expectNoSchemaIssueAsync, + expectSchemaIssueAsync, +} from '../../vitest/index.ts'; + +const FooKeySchema = customAsync<`foo(${string})`>( + async (input) => + typeof input === 'string' && input.startsWith('foo(') && input.endsWith(')') +); + +const BarKeySchema = pipeAsync( + customAsync<`bar(${string})`>( + async (input) => + typeof input === 'string' && + input.startsWith('bar(') && + input.endsWith(')') + ), + transformAsync( + async (input) => input.toUpperCase() as Uppercase + ) +); + +describe('recordWithPatternsAsync', () => { + describe('should return schema object', () => { + const patterns = [ + [FooKeySchema, string()], + [BarKeySchema, number()], + ] as const; + type Patterns = typeof patterns; + const rest = boolean(); + type Rest = typeof rest; + const baseSchema: Omit< + RecordWithPatternsSchemaAsync, + 'message' + > = { + kind: 'schema', + type: 'record_with_patterns', + reference: recordWithPatternsAsync, + expects: 'Object', + patterns, + rest, + async: true, + '~standard': { + version: 1, + vendor: 'valibot', + validate: expect.any(Function), + }, + '~run': expect.any(Function), + }; + test('without message', () => { + expect(recordWithPatternsAsync(patterns, rest)).toStrictEqual({ + ...baseSchema, + message: undefined, + }); + }); + + test('with string message', () => { + expect(recordWithPatternsAsync(patterns, rest, 'message')).toStrictEqual({ + ...baseSchema, + message: 'message', + }); + }); + + test('with function message', () => { + const message = () => 'message'; + expect(recordWithPatternsAsync(patterns, rest, message)).toStrictEqual({ + ...baseSchema, + message, + }); + }); + }); + + describe('should return dataset without issues', () => { + test('for empty object', async () => { + await expectNoSchemaIssueAsync( + recordWithPatternsAsync([[FooKeySchema, string()]], string()), + [{}] + ); + }); + test('for simple object', async () => { + expect( + await recordWithPatternsAsync( + [ + [FooKeySchema, string()], + [BarKeySchema, number()], + ], + boolean() + )['~run']( + { value: { 'foo(bar)': 'foo', 'bar(baz)': 123, other: true } }, + {} + ) + ).toEqual({ + typed: true, + value: { 'foo(bar)': 'foo', 'BAR(BAZ)': 123, other: true }, + }); + }); + }); + + describe('should return dataset with issues', () => { + const schema = recordWithPatternsAsync( + [[FooKeySchema, string()]], + never(), + 'message' + ); + const baseIssue: Omit = { + kind: 'schema', + type: 'record_with_patterns', + expected: 'Object', + message: 'message', + }; + + // for primitive types + + test('for bigints', async () => { + await expectSchemaIssueAsync(schema, baseIssue, [-1n, 0n, 123n]); + }); + + test('for booleans', async () => { + await expectSchemaIssueAsync(schema, baseIssue, [true, false]); + }); + + test('for null', async () => { + await expectSchemaIssueAsync(schema, baseIssue, [null]); + }); + + test('for numbers', async () => { + await expectSchemaIssueAsync(schema, baseIssue, [-1, 0, 123, 45.67]); + }); + + test('for strings', async () => { + await expectSchemaIssueAsync(schema, baseIssue, ['foo', 'bar', 'baz']); + }); + + test('for symbols', async () => { + await expectSchemaIssueAsync(schema, baseIssue, [ + Symbol('foo'), + Symbol('bar'), + Symbol('baz'), + ]); + }); + + // complex types + + // test('for arrays', async () => { + // await expectSchemaIssueAsync(schema, baseIssue, [[], ['value']]); + // }); + + test('for functions', async () => { + await expectSchemaIssueAsync(schema, baseIssue, [ + // eslint-disable-next-line @typescript-eslint/no-empty-function + () => {}, + // eslint-disable-next-line @typescript-eslint/no-empty-function + function () {}, + ]); + }); + }); + + describe('should return dataset without nested issues', () => { + test('for simple object', async () => { + await expectNoSchemaIssueAsync( + recordWithPatternsAsync([[FooKeySchema, string()]], boolean()), + // @ts-expect-error + [{ 'foo(bar)': 'foo', other: true }] + ); + }); + + test('for nested object', async () => { + await expectNoSchemaIssueAsync( + recordWithPatternsAsync( + [[FooKeySchema, objectAsync({ key: string() })]], + objectAsync({ key: number() }) + ), + // @ts-expect-error + [{ 'foo(bar)': { key: 'foo' }, other: { key: 123 } }] + ); + }); + }); + + describe('should return dataset with nested issues', () => { + const schema = recordWithPatternsAsync( + [ + [FooKeySchema, string()], + [BarKeySchema, objectAsync({ key: number() })], + ], + objectAsync({ key: number() }), + 'message' + ); + + const baseInfo = { + message: expect.any(String), + requirement: undefined, + issues: undefined, + lang: undefined, + abortEarly: undefined, + abortPipeEarly: undefined, + }; + + test('for invalid entries', async () => { + const input = { 'foo(bar)': false, other: 'foo' }; + expect(await schema['~run']({ value: input }, {})).toStrictEqual({ + typed: false, + value: input, + issues: [ + { + ...baseInfo, + kind: 'schema', + type: 'string', + input: false, + expected: 'string', + received: 'false', + path: [ + { + type: 'object', + origin: 'value', + input, + key: 'foo(bar)', + value: false, + }, + ], + }, + { + ...baseInfo, + kind: 'schema', + type: 'object', + input: 'foo', + expected: 'Object', + received: '"foo"', + path: [ + { + type: 'object', + origin: 'value', + input, + key: 'other', + value: 'foo', + }, + ], + }, + ], + } satisfies FailureDataset>); + }); + + test('for invalid nested entries', async () => { + const input = { 'bar(baz)': { key: '123' } }; + expect(await schema['~run']({ value: input }, {})).toStrictEqual({ + typed: false, + value: { 'BAR(BAZ)': { key: '123' } }, + issues: [ + { + ...baseInfo, + kind: 'schema', + type: 'number', + input: '123', + expected: 'number', + received: '"123"', + path: [ + { + type: 'object', + origin: 'value', + input, + key: 'bar(baz)', + value: input['bar(baz)'], + }, + { + type: 'object', + origin: 'value', + input: input['bar(baz)'], + key: 'key', + value: '123', + }, + ], + }, + ], + } satisfies FailureDataset>); + }); + test('for wrong rest', async () => { + const input = { 'foo(bar)': 'foo', other: 'foo' }; + expect(await schema['~run']({ value: input }, {})).toStrictEqual({ + typed: false, + value: input, + issues: [ + { + ...baseInfo, + kind: 'schema', + type: 'object', + input: 'foo', + expected: 'Object', + received: '"foo"', + path: [ + { + type: 'object', + origin: 'value', + input, + key: 'other', + value: 'foo', + }, + ], + }, + ], + }); + }); + test('for wrong nested rest', async () => { + const input = { other: { key: 'foo' } }; + expect(await schema['~run']({ value: input }, {})).toStrictEqual({ + typed: false, + value: input, + issues: [ + { + ...baseInfo, + kind: 'schema', + type: 'number', + input: 'foo', + expected: 'number', + received: '"foo"', + path: [ + { + type: 'object', + origin: 'value', + input, + key: 'other', + value: input.other, + }, + { + type: 'object', + origin: 'value', + input: input.other, + key: 'key', + value: 'foo', + }, + ], + }, + ], + } satisfies FailureDataset>); + }); + }); +}); diff --git a/library/src/schemas/recordWithPatterns/recordWithPatternsAsync.ts b/library/src/schemas/recordWithPatterns/recordWithPatternsAsync.ts new file mode 100644 index 000000000..10a3f33d9 --- /dev/null +++ b/library/src/schemas/recordWithPatterns/recordWithPatternsAsync.ts @@ -0,0 +1,275 @@ +import type { + BaseIssue, + BaseSchema, + BaseSchemaAsync, + ErrorMessage, + InferInput, + InferIssue, + InferOutput, + ObjectPathItem, + OutputDataset, + Prettify, +} from '../../types/index.ts'; +import { _addIssue, _getStandardProps } from '../../utils/index.ts'; +import type { recordWithPatterns } from './recordWithPatterns.ts'; +import type { RecordWithPatternsIssue } from './types.ts'; + +export type PatternTupleAsync = readonly [ + key: + | BaseSchema> + | BaseSchemaAsync>, + value: + | BaseSchema> + | BaseSchemaAsync>, +]; + +export type PatternTuplesAsync = readonly [ + PatternTupleAsync, + ...PatternTupleAsync[], +]; + +export type InferPatternInputAsync = { + [K in InferInput]?: InferInput; +}; + +export type InferPatternsInputAsync = + TPatterns extends readonly [infer TPattern extends PatternTupleAsync] + ? InferPatternInputAsync + : TPatterns extends readonly [ + infer TPattern extends PatternTupleAsync, + ...infer TRest extends PatternTuplesAsync, + ] + ? InferPatternInputAsync & InferPatternsInputAsync + : never; + +export type InferPatternIssueAsync = + InferIssue; + +export type InferPatternsIssueAsync = + InferPatternIssueAsync; + +export type InferPatternOutputAsync = { + [K in InferOutput]?: InferOutput; +}; + +export type InferPatternsOutputAsync = + TPatterns extends readonly [infer TPattern extends PatternTupleAsync] + ? InferPatternOutputAsync + : TPatterns extends readonly [ + infer TPattern extends PatternTupleAsync, + ...infer TRest extends PatternTuplesAsync, + ] + ? InferPatternOutputAsync & InferPatternsOutputAsync + : never; + +export interface RecordWithPatternsSchemaAsync< + TPatterns extends PatternTuplesAsync, + TRest extends + | BaseSchema> + | BaseSchemaAsync>, + TMessage extends ErrorMessage | undefined, +> extends BaseSchemaAsync< + Prettify> & { + [key: string]: InferInput; + }, + Prettify> & { + [key: string]: InferOutput; + }, + | RecordWithPatternsIssue + | InferPatternsIssueAsync + | InferIssue + > { + /** + * The schema type. + */ + readonly type: 'record_with_patterns'; + /** + * The schema reference. + */ + readonly reference: + | typeof recordWithPatterns + | typeof recordWithPatternsAsync; + /** + * The expected property. + */ + readonly expects: 'Object'; + /** + * The patterns schema. + */ + readonly patterns: TPatterns; + /** + * The rest schema. + */ + readonly rest: TRest; + /** + * The error message. + */ + readonly message: TMessage; +} + +/** + * Creates an object schema that matches patterns. + * + * @param patterns Pairs of key and value schemas. + * @param rest Schema to use when no pattern matches. + * + * @returns A object schema. + */ +export function recordWithPatternsAsync< + const TPatterns extends PatternTuplesAsync, + const TRest extends + | BaseSchema> + | BaseSchemaAsync>, +>( + patterns: TPatterns, + rest: TRest +): RecordWithPatternsSchemaAsync; + +/** + * Creates an object schema that matches patterns. + * + * @param patterns Pairs of key and value schemas. + * @param rest Schema to use when no pattern matches. + * @param message The error message. + * + * @returns A object schema. + */ +export function recordWithPatternsAsync< + const TPatterns extends PatternTuplesAsync, + const TRest extends + | BaseSchema> + | BaseSchemaAsync>, + const TMessage extends ErrorMessage | undefined, +>( + patterns: TPatterns, + rest: TRest, + message: TMessage +): RecordWithPatternsSchemaAsync; + +// @__NO_SIDE_EFFECTS__ +export function recordWithPatternsAsync( + patterns: PatternTuplesAsync, + rest: + | BaseSchema> + | BaseSchemaAsync>, + message?: ErrorMessage +): RecordWithPatternsSchemaAsync< + PatternTuplesAsync, + | BaseSchema> + | BaseSchemaAsync>, + ErrorMessage | undefined +> { + return { + kind: 'schema', + type: 'record_with_patterns', + reference: recordWithPatternsAsync, + expects: 'Object', + async: true, + patterns, + rest, + message, + get '~standard'() { + return _getStandardProps(this); + }, + async '~run'(dataset, config) { + // Get input value from dataset + const input = dataset.value; + + // If root type is valid, check nested types + if (input && typeof input === 'object') { + // Set typed to `true` and value to empty object + // @ts-expect-error + dataset.typed = true; + dataset.value = {}; + + // Parse schema of each pattern + const datasets = await Promise.all( + Object.entries(input).map(async ([key, value]) => { + // Get pattern schema and new key + let valueSchema: + | BaseSchema> + | BaseSchemaAsync> + | undefined; + let newKey = key; + for (const [keySchema, valueSchema_] of patterns) { + const keyDataset = await keySchema['~run']( + { value: key }, + config + ); + if (keyDataset.typed) { + valueSchema = valueSchema_; + newKey = keyDataset.value; + break; + } + } + + // If no pattern matches, use rest schema + if (!valueSchema) { + valueSchema = rest; + } + + const valueDataset = await valueSchema['~run']({ value }, config); + return [key, newKey, valueDataset] as const; + }) + ); + for (const [key, newKey, valueDataset] of datasets) { + // If there are issues, capture them + if (valueDataset.issues) { + // Create object path item + const pathItem: ObjectPathItem = { + type: 'object', + origin: 'value', + input: input as Record, + key, + value: valueDataset.value, + }; + + // Add modified entry dataset issues to issues + for (const issue of valueDataset.issues) { + if (issue.path) { + issue.path.unshift(pathItem); + } else { + // @ts-expect-error + issue.path = [pathItem]; + } + // @ts-expect-error + dataset.issues?.push(issue); + } + if (!dataset.issues) { + // @ts-expect-error + dataset.issues = valueDataset.issues; + } + + // If necessary, abort early + if (config.abortEarly) { + dataset.typed = false; + break; + } + } + + // If not typed, set typed to `false` + if (!valueDataset.typed) { + dataset.typed = false; + } + + // Add entry to dataset + // @ts-expect-error + dataset.value[newKey] = valueDataset.value; + } + // Otherwise, add object issue + } else { + _addIssue(this, 'type', dataset, config); + } + // Return output dataset + // @ts-expect-error + return dataset as OutputDataset< + InferPatternsOutputAsync & { + [key: string]: unknown; + }, + | RecordWithPatternsIssue + | InferPatternsIssueAsync + | BaseIssue + >; + }, + }; +} diff --git a/library/src/schemas/recordWithPatterns/types.ts b/library/src/schemas/recordWithPatterns/types.ts new file mode 100644 index 000000000..0735684b3 --- /dev/null +++ b/library/src/schemas/recordWithPatterns/types.ts @@ -0,0 +1,16 @@ +import type { BaseIssue } from '../../types/index.ts'; + +export interface RecordWithPatternsIssue extends BaseIssue { + /** + * The issue kind. + */ + readonly kind: 'schema'; + /** + * The issue type. + */ + readonly type: 'record_with_patterns'; + /** + * The expected property. + */ + readonly expected: 'Object' | `"${string}"`; +} diff --git a/website/src/components/Property.tsx b/website/src/components/Property.tsx index e175ae875..ff98081bb 100644 --- a/website/src/components/Property.tsx +++ b/website/src/components/Property.tsx @@ -53,6 +53,7 @@ type DefinitionData = type: 'tuple'; modifier?: string; items: DefinitionData[]; + itemLabels?: (string | undefined)[]; } | { type: 'function'; @@ -250,6 +251,12 @@ const Definition = component$(({ parent, data }) => ( {data.items.map((item, index) => ( {index > 0 && ', '} + {data.itemLabels?.[index] && ( + + {data.itemLabels[index]} + {': '} + + )} ))} diff --git a/website/src/routes/api/(actions)/brand/index.mdx b/website/src/routes/api/(actions)/brand/index.mdx index f615b53a5..092d7184f 100644 --- a/website/src/routes/api/(actions)/brand/index.mdx +++ b/website/src/routes/api/(actions)/brand/index.mdx @@ -95,6 +95,7 @@ The following APIs can be combined with `brand`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(actions)/check/index.mdx b/website/src/routes/api/(actions)/check/index.mdx index 7c6fa832a..4389f3401 100644 --- a/website/src/routes/api/(actions)/check/index.mdx +++ b/website/src/routes/api/(actions)/check/index.mdx @@ -97,6 +97,7 @@ The following APIs can be combined with `check`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(actions)/description/index.mdx b/website/src/routes/api/(actions)/description/index.mdx index 14de31e03..16e00b51f 100644 --- a/website/src/routes/api/(actions)/description/index.mdx +++ b/website/src/routes/api/(actions)/description/index.mdx @@ -94,6 +94,7 @@ The following APIs can be combined with `description`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(actions)/entries/index.mdx b/website/src/routes/api/(actions)/entries/index.mdx index f7148834c..192d71725 100644 --- a/website/src/routes/api/(actions)/entries/index.mdx +++ b/website/src/routes/api/(actions)/entries/index.mdx @@ -63,6 +63,7 @@ The following APIs can be combined with `entries`. 'object', 'objectWithRest', 'record', + 'recordWithPatterns', 'strictObject', 'variant', ]} diff --git a/website/src/routes/api/(actions)/maxEntries/index.mdx b/website/src/routes/api/(actions)/maxEntries/index.mdx index 2aa656564..117d28ff3 100644 --- a/website/src/routes/api/(actions)/maxEntries/index.mdx +++ b/website/src/routes/api/(actions)/maxEntries/index.mdx @@ -68,6 +68,7 @@ The following APIs can be combined with `maxEntries`. 'object', 'objectWithRest', 'record', + 'recordWithPatterns', 'strictObject', 'variant', ]} diff --git a/website/src/routes/api/(actions)/metadata/index.mdx b/website/src/routes/api/(actions)/metadata/index.mdx index f682be1b5..12291f4af 100644 --- a/website/src/routes/api/(actions)/metadata/index.mdx +++ b/website/src/routes/api/(actions)/metadata/index.mdx @@ -99,6 +99,7 @@ The following APIs can be combined with `metadata`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(actions)/minEntries/index.mdx b/website/src/routes/api/(actions)/minEntries/index.mdx index 043110d03..49f3652f7 100644 --- a/website/src/routes/api/(actions)/minEntries/index.mdx +++ b/website/src/routes/api/(actions)/minEntries/index.mdx @@ -68,6 +68,7 @@ The following APIs can be combined with `minEntries`. 'object', 'objectWithRest', 'record', + 'recordWithPatterns', 'strictObject', 'variant', ]} diff --git a/website/src/routes/api/(actions)/notEntries/index.mdx b/website/src/routes/api/(actions)/notEntries/index.mdx index e2cf990dc..d5159012a 100644 --- a/website/src/routes/api/(actions)/notEntries/index.mdx +++ b/website/src/routes/api/(actions)/notEntries/index.mdx @@ -66,6 +66,7 @@ The following APIs can be combined with `notEntries`. 'object', 'objectWithRest', 'record', + 'recordWithPatterns', 'strictObject', 'variant', ]} diff --git a/website/src/routes/api/(actions)/partialCheck/index.mdx b/website/src/routes/api/(actions)/partialCheck/index.mdx index 6537ad64c..c51c0278c 100644 --- a/website/src/routes/api/(actions)/partialCheck/index.mdx +++ b/website/src/routes/api/(actions)/partialCheck/index.mdx @@ -101,6 +101,7 @@ The following APIs can be combined with `partialCheck`. 'object', 'objectWithRest', 'record', + 'recordWithPatterns', 'strictObject', 'strictTuple', 'tuple', diff --git a/website/src/routes/api/(actions)/rawCheck/index.mdx b/website/src/routes/api/(actions)/rawCheck/index.mdx index 99c9afc0e..36164850e 100644 --- a/website/src/routes/api/(actions)/rawCheck/index.mdx +++ b/website/src/routes/api/(actions)/rawCheck/index.mdx @@ -120,6 +120,7 @@ The following APIs can be combined with `rawCheck`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(actions)/rawTransform/index.mdx b/website/src/routes/api/(actions)/rawTransform/index.mdx index 533b61e98..e179961ce 100644 --- a/website/src/routes/api/(actions)/rawTransform/index.mdx +++ b/website/src/routes/api/(actions)/rawTransform/index.mdx @@ -138,6 +138,7 @@ The following APIs can be combined with `rawTransform`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(actions)/readonly/index.mdx b/website/src/routes/api/(actions)/readonly/index.mdx index 71562bef2..63accf40d 100644 --- a/website/src/routes/api/(actions)/readonly/index.mdx +++ b/website/src/routes/api/(actions)/readonly/index.mdx @@ -90,6 +90,7 @@ The following APIs can be combined with `readonly`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(actions)/returns/index.mdx b/website/src/routes/api/(actions)/returns/index.mdx index a11d852a9..3edbfd8c3 100644 --- a/website/src/routes/api/(actions)/returns/index.mdx +++ b/website/src/routes/api/(actions)/returns/index.mdx @@ -91,6 +91,7 @@ The following APIs can be combined with `returns`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(actions)/title/index.mdx b/website/src/routes/api/(actions)/title/index.mdx index a0f8c89f6..aae78dcd1 100644 --- a/website/src/routes/api/(actions)/title/index.mdx +++ b/website/src/routes/api/(actions)/title/index.mdx @@ -94,6 +94,7 @@ The following APIs can be combined with `title`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(actions)/transform/index.mdx b/website/src/routes/api/(actions)/transform/index.mdx index e850e2e68..e4901bb45 100644 --- a/website/src/routes/api/(actions)/transform/index.mdx +++ b/website/src/routes/api/(actions)/transform/index.mdx @@ -106,6 +106,7 @@ The following APIs can be combined with `transform`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(async)/arrayAsync/index.mdx b/website/src/routes/api/(async)/arrayAsync/index.mdx index 139c0f2d7..29377e9bd 100644 --- a/website/src/routes/api/(async)/arrayAsync/index.mdx +++ b/website/src/routes/api/(async)/arrayAsync/index.mdx @@ -99,6 +99,7 @@ The following APIs can be combined with `arrayAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -177,6 +178,7 @@ The following APIs can be combined with `arrayAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/awaitAsync/index.mdx b/website/src/routes/api/(async)/awaitAsync/index.mdx index ba75105cb..4a154ab65 100644 --- a/website/src/routes/api/(async)/awaitAsync/index.mdx +++ b/website/src/routes/api/(async)/awaitAsync/index.mdx @@ -87,6 +87,7 @@ The following APIs can be combined with `awaitAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -125,6 +126,7 @@ The following APIs can be combined with `awaitAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'pipeAsync', diff --git a/website/src/routes/api/(async)/checkAsync/index.mdx b/website/src/routes/api/(async)/checkAsync/index.mdx index 4fcba1536..de70940df 100644 --- a/website/src/routes/api/(async)/checkAsync/index.mdx +++ b/website/src/routes/api/(async)/checkAsync/index.mdx @@ -100,6 +100,7 @@ The following APIs can be combined with `checkAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -139,6 +140,7 @@ The following APIs can be combined with `checkAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'pipeAsync', diff --git a/website/src/routes/api/(async)/customAsync/index.mdx b/website/src/routes/api/(async)/customAsync/index.mdx index 6ddc0a8ce..b54bf376a 100644 --- a/website/src/routes/api/(async)/customAsync/index.mdx +++ b/website/src/routes/api/(async)/customAsync/index.mdx @@ -90,6 +90,7 @@ The following APIs can be combined with `customAsync`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -238,6 +239,7 @@ The following APIs can be combined with `customAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/exactOptionalAsync/index.mdx b/website/src/routes/api/(async)/exactOptionalAsync/index.mdx index eb230349a..18074c11b 100644 --- a/website/src/routes/api/(async)/exactOptionalAsync/index.mdx +++ b/website/src/routes/api/(async)/exactOptionalAsync/index.mdx @@ -135,6 +135,7 @@ The following APIs can be combined with `exactOptionalAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -199,6 +200,7 @@ The following APIs can be combined with `exactOptionalAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/fallbackAsync/index.mdx b/website/src/routes/api/(async)/fallbackAsync/index.mdx index a39ecce79..c7b03c7f7 100644 --- a/website/src/routes/api/(async)/fallbackAsync/index.mdx +++ b/website/src/routes/api/(async)/fallbackAsync/index.mdx @@ -101,6 +101,7 @@ The following APIs can be combined with `fallbackAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -267,6 +268,7 @@ The following APIs can be combined with `fallbackAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/forwardAsync/index.mdx b/website/src/routes/api/(async)/forwardAsync/index.mdx index 0dfb34339..e81bc2193 100644 --- a/website/src/routes/api/(async)/forwardAsync/index.mdx +++ b/website/src/routes/api/(async)/forwardAsync/index.mdx @@ -83,6 +83,7 @@ The following APIs can be combined with `forwardAsync`. 'object', 'objectWithRest', 'record', + 'recordWithPatterns', 'strictObject', 'strictTuple', 'tuple', @@ -139,6 +140,7 @@ The following APIs can be combined with `forwardAsync`. 'looseObjectAsync', 'looseTupleAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'partialAsync', 'partialCheckAsync', diff --git a/website/src/routes/api/(async)/getDefaultsAsync/index.mdx b/website/src/routes/api/(async)/getDefaultsAsync/index.mdx index f8d8a2d93..69e6ade62 100644 --- a/website/src/routes/api/(async)/getDefaultsAsync/index.mdx +++ b/website/src/routes/api/(async)/getDefaultsAsync/index.mdx @@ -104,6 +104,7 @@ The following APIs can be combined with `getDefaultsAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -157,6 +158,7 @@ The following APIs can be combined with `getDefaultsAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'partialAsync', diff --git a/website/src/routes/api/(async)/getFallbacksAsync/index.mdx b/website/src/routes/api/(async)/getFallbacksAsync/index.mdx index 710d09e82..cfb6c55d5 100644 --- a/website/src/routes/api/(async)/getFallbacksAsync/index.mdx +++ b/website/src/routes/api/(async)/getFallbacksAsync/index.mdx @@ -102,6 +102,7 @@ The following APIs can be combined with `getFallbacksAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -155,6 +156,7 @@ The following APIs can be combined with `getFallbacksAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'partialAsync', diff --git a/website/src/routes/api/(async)/intersectAsync/index.mdx b/website/src/routes/api/(async)/intersectAsync/index.mdx index d74180f37..7d93ab77d 100644 --- a/website/src/routes/api/(async)/intersectAsync/index.mdx +++ b/website/src/routes/api/(async)/intersectAsync/index.mdx @@ -114,6 +114,7 @@ The following APIs can be combined with `intersectAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -269,6 +270,7 @@ The following APIs can be combined with `intersectAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/lazyAsync/index.mdx b/website/src/routes/api/(async)/lazyAsync/index.mdx index d49129226..921b94806 100644 --- a/website/src/routes/api/(async)/lazyAsync/index.mdx +++ b/website/src/routes/api/(async)/lazyAsync/index.mdx @@ -146,6 +146,7 @@ The following APIs can be combined with `lazyAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -301,6 +302,7 @@ The following APIs can be combined with `lazyAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/looseObjectAsync/index.mdx b/website/src/routes/api/(async)/looseObjectAsync/index.mdx index 40bf79671..a1e2e5544 100644 --- a/website/src/routes/api/(async)/looseObjectAsync/index.mdx +++ b/website/src/routes/api/(async)/looseObjectAsync/index.mdx @@ -104,6 +104,7 @@ The following APIs can be combined with `looseObjectAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -167,6 +168,7 @@ The following APIs can be combined with `looseObjectAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/looseTupleAsync/index.mdx b/website/src/routes/api/(async)/looseTupleAsync/index.mdx index 2f3e33d37..a27285e69 100644 --- a/website/src/routes/api/(async)/looseTupleAsync/index.mdx +++ b/website/src/routes/api/(async)/looseTupleAsync/index.mdx @@ -100,6 +100,7 @@ The following APIs can be combined with `looseTupleAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -178,6 +179,7 @@ The following APIs can be combined with `looseTupleAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/mapAsync/index.mdx b/website/src/routes/api/(async)/mapAsync/index.mdx index b01ff3b25..ae506ef21 100644 --- a/website/src/routes/api/(async)/mapAsync/index.mdx +++ b/website/src/routes/api/(async)/mapAsync/index.mdx @@ -98,6 +98,7 @@ The following APIs can be combined with `mapAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -163,6 +164,7 @@ The following APIs can be combined with `mapAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/nonNullableAsync/index.mdx b/website/src/routes/api/(async)/nonNullableAsync/index.mdx index ba3263f07..2b370e761 100644 --- a/website/src/routes/api/(async)/nonNullableAsync/index.mdx +++ b/website/src/routes/api/(async)/nonNullableAsync/index.mdx @@ -103,6 +103,7 @@ The following APIs can be combined with `nonNullableAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -166,6 +167,7 @@ The following APIs can be combined with `nonNullableAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/nonNullishAsync/index.mdx b/website/src/routes/api/(async)/nonNullishAsync/index.mdx index 9f2f3f6ec..911b7f203 100644 --- a/website/src/routes/api/(async)/nonNullishAsync/index.mdx +++ b/website/src/routes/api/(async)/nonNullishAsync/index.mdx @@ -99,6 +99,7 @@ The following APIs can be combined with `nonNullishAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -162,6 +163,7 @@ The following APIs can be combined with `nonNullishAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/nonOptionalAsync/index.mdx b/website/src/routes/api/(async)/nonOptionalAsync/index.mdx index 76320f8ff..ac1bd3c8e 100644 --- a/website/src/routes/api/(async)/nonOptionalAsync/index.mdx +++ b/website/src/routes/api/(async)/nonOptionalAsync/index.mdx @@ -109,6 +109,7 @@ The following APIs can be combined with `nonOptionalAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -172,6 +173,7 @@ The following APIs can be combined with `nonOptionalAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/nullableAsync/index.mdx b/website/src/routes/api/(async)/nullableAsync/index.mdx index ac5693e10..4ab7510aa 100644 --- a/website/src/routes/api/(async)/nullableAsync/index.mdx +++ b/website/src/routes/api/(async)/nullableAsync/index.mdx @@ -123,6 +123,7 @@ The following APIs can be combined with `nullableAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -186,6 +187,7 @@ The following APIs can be combined with `nullableAsync`. 'nonOptionalAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/nullishAsync/index.mdx b/website/src/routes/api/(async)/nullishAsync/index.mdx index ff5348513..da2d8cb11 100644 --- a/website/src/routes/api/(async)/nullishAsync/index.mdx +++ b/website/src/routes/api/(async)/nullishAsync/index.mdx @@ -156,6 +156,7 @@ The following APIs can be combined with `nullishAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -219,6 +220,7 @@ The following APIs can be combined with `nullishAsync`. 'nonOptionalAsync', 'nullableAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/objectAsync/index.mdx b/website/src/routes/api/(async)/objectAsync/index.mdx index e5f20de54..9db62fdc5 100644 --- a/website/src/routes/api/(async)/objectAsync/index.mdx +++ b/website/src/routes/api/(async)/objectAsync/index.mdx @@ -104,6 +104,7 @@ The following APIs can be combined with `objectAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -173,6 +174,7 @@ The following APIs can be combined with `objectAsync`. 'nonOptionalAsync', 'nullableAsync', 'nullishAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/objectWithRestAsync/index.mdx b/website/src/routes/api/(async)/objectWithRestAsync/index.mdx index 3b2097681..4d510e2c7 100644 --- a/website/src/routes/api/(async)/objectWithRestAsync/index.mdx +++ b/website/src/routes/api/(async)/objectWithRestAsync/index.mdx @@ -118,6 +118,7 @@ The following APIs can be combined with `objectWithRestAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -188,6 +189,7 @@ The following APIs can be combined with `objectWithRestAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'optionalAsync', 'parseAsync', 'parserAsync', diff --git a/website/src/routes/api/(async)/optionalAsync/index.mdx b/website/src/routes/api/(async)/optionalAsync/index.mdx index 67f56cc73..f406b51fe 100644 --- a/website/src/routes/api/(async)/optionalAsync/index.mdx +++ b/website/src/routes/api/(async)/optionalAsync/index.mdx @@ -156,6 +156,7 @@ The following APIs can be combined with `optionalAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -220,6 +221,7 @@ The following APIs can be combined with `optionalAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'parseAsync', 'parserAsync', diff --git a/website/src/routes/api/(async)/parseAsync/index.mdx b/website/src/routes/api/(async)/parseAsync/index.mdx index 7240a143c..47b79d987 100644 --- a/website/src/routes/api/(async)/parseAsync/index.mdx +++ b/website/src/routes/api/(async)/parseAsync/index.mdx @@ -101,6 +101,7 @@ The following APIs can be combined with `parseAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -159,6 +160,7 @@ The following APIs can be combined with `parseAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'partialAsync', diff --git a/website/src/routes/api/(async)/parserAsync/index.mdx b/website/src/routes/api/(async)/parserAsync/index.mdx index 50f5de653..55842a8e8 100644 --- a/website/src/routes/api/(async)/parserAsync/index.mdx +++ b/website/src/routes/api/(async)/parserAsync/index.mdx @@ -95,6 +95,7 @@ The following APIs can be combined with `parserAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -153,6 +154,7 @@ The following APIs can be combined with `parserAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'partialAsync', diff --git a/website/src/routes/api/(async)/partialAsync/index.mdx b/website/src/routes/api/(async)/partialAsync/index.mdx index 8136f00fa..f343caa87 100644 --- a/website/src/routes/api/(async)/partialAsync/index.mdx +++ b/website/src/routes/api/(async)/partialAsync/index.mdx @@ -101,6 +101,7 @@ The following APIs can be combined with `partialAsync`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -179,6 +180,7 @@ The following APIs can be combined with `partialAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/partialCheckAsync/index.mdx b/website/src/routes/api/(async)/partialCheckAsync/index.mdx index 15289e73b..cfe96c1da 100644 --- a/website/src/routes/api/(async)/partialCheckAsync/index.mdx +++ b/website/src/routes/api/(async)/partialCheckAsync/index.mdx @@ -103,6 +103,7 @@ The following APIs can be combined with `partialCheckAsync`. 'object', 'objectWithRest', 'record', + 'recordWithPatterns', 'strictObject', 'strictTuple', 'tuple', @@ -132,6 +133,7 @@ The following APIs can be combined with `partialCheckAsync`. 'nonNullishAsync', 'nonOptionalAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'pipeAsync', 'recordAsync', diff --git a/website/src/routes/api/(async)/pipeAsync/index.mdx b/website/src/routes/api/(async)/pipeAsync/index.mdx index 95f8b6fd0..727a60cfc 100644 --- a/website/src/routes/api/(async)/pipeAsync/index.mdx +++ b/website/src/routes/api/(async)/pipeAsync/index.mdx @@ -128,6 +128,7 @@ The following APIs can be combined with `pipeAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -308,6 +309,7 @@ The following APIs can be combined with `pipeAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/rawCheckAsync/index.mdx b/website/src/routes/api/(async)/rawCheckAsync/index.mdx index 608bdda95..5735ff2c1 100644 --- a/website/src/routes/api/(async)/rawCheckAsync/index.mdx +++ b/website/src/routes/api/(async)/rawCheckAsync/index.mdx @@ -126,6 +126,7 @@ The following APIs can be combined with `rawCheckAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -166,6 +167,7 @@ The following APIs can be combined with `rawCheckAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'pipeAsync', diff --git a/website/src/routes/api/(async)/rawTransformAsync/index.mdx b/website/src/routes/api/(async)/rawTransformAsync/index.mdx index 9a91a7d20..57ae6fcd3 100644 --- a/website/src/routes/api/(async)/rawTransformAsync/index.mdx +++ b/website/src/routes/api/(async)/rawTransformAsync/index.mdx @@ -126,6 +126,7 @@ The following APIs can be combined with `rawTransformAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -165,6 +166,7 @@ The following APIs can be combined with `rawTransformAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'pipeAsync', diff --git a/website/src/routes/api/(async)/recordAsync/index.mdx b/website/src/routes/api/(async)/recordAsync/index.mdx index 7d878ac68..6a1213669 100644 --- a/website/src/routes/api/(async)/recordAsync/index.mdx +++ b/website/src/routes/api/(async)/recordAsync/index.mdx @@ -105,6 +105,7 @@ The following APIs can be combined with `recordAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -172,6 +173,7 @@ The following APIs can be combined with `recordAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/recordWithPatternsAsync/index.mdx b/website/src/routes/api/(async)/recordWithPatternsAsync/index.mdx new file mode 100644 index 000000000..04842f412 --- /dev/null +++ b/website/src/routes/api/(async)/recordWithPatternsAsync/index.mdx @@ -0,0 +1,193 @@ +--- +title: recordWithPatternsAsync +description: Creates an object schema that matches patterns. +source: /schemas/recordWithPatterns/recordWithPatternsAsync.ts +contributors: + - EskiMojo14 +--- + +import { Link } from '@builder.io/qwik-city'; +import { ApiList, Property } from '~/components'; +import { properties } from './properties'; + +# recordWithPatternsAsync + +Creates an object schema that matches patterns. + +```ts +const RecordWithPatternsSchemaAsync = v.recordWithPatternsAsync< + TPatterns, + TRest, + TMessage +>(patterns, rest, message); +``` + +## Generics + +- `TPatterns` +- `TRest` +- `TMessage` + +## Parameters + +- `patterns` +- `rest` +- `message` + +## Returns + +- `Schema` + +## Explanation + +Tuples of key and value schemas are iterated through until a key schema matches, and the value schema is used to validate the value. If no key schema matches, the rest schema is used. + +## Examples + +The following examples show how `recordWithPatternsAsync` can be used. Please see the object guide for more examples and explanations. + +```ts +const RecordWithPatternsSchemaAsync = v.recordWithPatternsAsync( + [ + [v.pipeAsync(v.string(), v.startsWith('str-')), v.string()], + [v.pipeAsync(v.string(), v.startsWith('num-')), v.number()], + ], + v.boolean() +); +``` + +## Related + +The following APIs can be combined with `recordWithPatternsAsync`. + +### Schemas + + + +### Methods + + + +### Actions + + + +### Utils + + + +### Async + + diff --git a/website/src/routes/api/(async)/recordWithPatternsAsync/properties.ts b/website/src/routes/api/(async)/recordWithPatternsAsync/properties.ts new file mode 100644 index 000000000..5b253dfbf --- /dev/null +++ b/website/src/routes/api/(async)/recordWithPatternsAsync/properties.ts @@ -0,0 +1,110 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + TPatterns: { + modifier: 'extends', + type: { + type: 'custom', + name: 'PatternTuplesAsync', + href: '../PatternTuplesAsync/', + }, + }, + TRest: { + modifier: 'extends', + type: { + type: 'union', + options: [ + { + type: 'custom', + name: 'BaseSchema', + href: '../BaseSchema/', + generics: [ + 'unknown', + 'unknown', + { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + ], + }, + { + type: 'custom', + name: 'BaseSchemaAsync', + href: '../BaseSchemaAsync/', + generics: [ + 'unknown', + 'unknown', + { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + ], + }, + ], + }, + }, + TMessage: { + modifier: 'extends', + type: { + type: 'union', + options: [ + { + type: 'custom', + name: 'ErrorMessage', + href: '../ErrorMessage/', + generics: [ + { + type: 'custom', + name: 'RecordWithPatternsIssue', + href: '../RecordWithPatternsIssue/', + }, + ], + }, + 'undefined', + ], + }, + }, + patterns: { + type: { + type: 'custom', + name: 'TPatterns', + }, + }, + rest: { + type: { + type: 'custom', + name: 'TRest', + }, + }, + message: { + type: { + type: 'custom', + name: 'TMessage', + }, + }, + Schema: { + type: { + type: 'custom', + name: 'RecordWithPatternsSchemaAsync', + href: '../RecordWithPatternsSchemaAsync/', + generics: [ + { + type: 'custom', + name: 'TPatterns', + }, + { + type: 'custom', + name: 'TRest', + }, + { + type: 'custom', + name: 'TMessage', + }, + ], + }, + }, +}; diff --git a/website/src/routes/api/(async)/requiredAsync/index.mdx b/website/src/routes/api/(async)/requiredAsync/index.mdx index bc2f13651..067bd08c1 100644 --- a/website/src/routes/api/(async)/requiredAsync/index.mdx +++ b/website/src/routes/api/(async)/requiredAsync/index.mdx @@ -107,6 +107,7 @@ The following APIs can be combined with `requiredAsync`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -185,6 +186,7 @@ The following APIs can be combined with `requiredAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/returnsAsync/index.mdx b/website/src/routes/api/(async)/returnsAsync/index.mdx index e548892d7..de99ff8d5 100644 --- a/website/src/routes/api/(async)/returnsAsync/index.mdx +++ b/website/src/routes/api/(async)/returnsAsync/index.mdx @@ -105,6 +105,7 @@ The following APIs can be combined with `returnsAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -146,6 +147,7 @@ The following APIs can be combined with `returnsAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'pipeAsync', diff --git a/website/src/routes/api/(async)/safeParseAsync/index.mdx b/website/src/routes/api/(async)/safeParseAsync/index.mdx index 9c3bb6c38..beefc15ad 100644 --- a/website/src/routes/api/(async)/safeParseAsync/index.mdx +++ b/website/src/routes/api/(async)/safeParseAsync/index.mdx @@ -94,6 +94,7 @@ The following APIs can be combined with `safeParseAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -152,6 +153,7 @@ The following APIs can be combined with `safeParseAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'partialAsync', diff --git a/website/src/routes/api/(async)/safeParserAsync/index.mdx b/website/src/routes/api/(async)/safeParserAsync/index.mdx index d542867a7..100f49ba8 100644 --- a/website/src/routes/api/(async)/safeParserAsync/index.mdx +++ b/website/src/routes/api/(async)/safeParserAsync/index.mdx @@ -95,6 +95,7 @@ The following APIs can be combined with `safeParserAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -153,6 +154,7 @@ The following APIs can be combined with `safeParserAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'partialAsync', diff --git a/website/src/routes/api/(async)/setAsync/index.mdx b/website/src/routes/api/(async)/setAsync/index.mdx index 0efe0d984..7e928f76f 100644 --- a/website/src/routes/api/(async)/setAsync/index.mdx +++ b/website/src/routes/api/(async)/setAsync/index.mdx @@ -97,6 +97,7 @@ The following APIs can be combined with `setAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'strictObject', 'strictTuple', 'string', @@ -162,6 +163,7 @@ The following APIs can be combined with `setAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/strictObjectAsync/index.mdx b/website/src/routes/api/(async)/strictObjectAsync/index.mdx index e3e02f2c0..ee6c5c680 100644 --- a/website/src/routes/api/(async)/strictObjectAsync/index.mdx +++ b/website/src/routes/api/(async)/strictObjectAsync/index.mdx @@ -104,6 +104,7 @@ The following APIs can be combined with `strictObjectAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -174,6 +175,7 @@ The following APIs can be combined with `strictObjectAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/strictTupleAsync/index.mdx b/website/src/routes/api/(async)/strictTupleAsync/index.mdx index 44a7052bc..25d97006d 100644 --- a/website/src/routes/api/(async)/strictTupleAsync/index.mdx +++ b/website/src/routes/api/(async)/strictTupleAsync/index.mdx @@ -101,6 +101,7 @@ The following APIs can be combined with `strictTupleAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'string', @@ -179,6 +180,7 @@ The following APIs can be combined with `strictTupleAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/transformAsync/index.mdx b/website/src/routes/api/(async)/transformAsync/index.mdx index 764e6b252..de08b2d6d 100644 --- a/website/src/routes/api/(async)/transformAsync/index.mdx +++ b/website/src/routes/api/(async)/transformAsync/index.mdx @@ -93,6 +93,7 @@ The following APIs can be combined with `transformAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -132,6 +133,7 @@ The following APIs can be combined with `transformAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'pipeAsync', diff --git a/website/src/routes/api/(async)/tupleAsync/index.mdx b/website/src/routes/api/(async)/tupleAsync/index.mdx index 5eb015370..8e99c6646 100644 --- a/website/src/routes/api/(async)/tupleAsync/index.mdx +++ b/website/src/routes/api/(async)/tupleAsync/index.mdx @@ -101,6 +101,7 @@ The following APIs can be combined with `tupleAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -179,6 +180,7 @@ The following APIs can be combined with `tupleAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/tupleWithRestAsync/index.mdx b/website/src/routes/api/(async)/tupleWithRestAsync/index.mdx index 684c1e531..694ffe522 100644 --- a/website/src/routes/api/(async)/tupleWithRestAsync/index.mdx +++ b/website/src/routes/api/(async)/tupleWithRestAsync/index.mdx @@ -108,6 +108,7 @@ The following APIs can be combined with `tupleWithRestAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -186,6 +187,7 @@ The following APIs can be combined with `tupleWithRestAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/undefinedableAsync/index.mdx b/website/src/routes/api/(async)/undefinedableAsync/index.mdx index fc788613d..3fab15af1 100644 --- a/website/src/routes/api/(async)/undefinedableAsync/index.mdx +++ b/website/src/routes/api/(async)/undefinedableAsync/index.mdx @@ -158,6 +158,7 @@ The following APIs can be combined with `undefinedableAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -222,6 +223,7 @@ The following APIs can be combined with `undefinedableAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/unionAsync/index.mdx b/website/src/routes/api/(async)/unionAsync/index.mdx index 5febac5bc..ee49c0fb4 100644 --- a/website/src/routes/api/(async)/unionAsync/index.mdx +++ b/website/src/routes/api/(async)/unionAsync/index.mdx @@ -107,6 +107,7 @@ The following APIs can be combined with `unionAsync`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -262,6 +263,7 @@ The following APIs can be combined with `unionAsync`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(async)/variantAsync/index.mdx b/website/src/routes/api/(async)/variantAsync/index.mdx index a9a51b851..5983d1efa 100644 --- a/website/src/routes/api/(async)/variantAsync/index.mdx +++ b/website/src/routes/api/(async)/variantAsync/index.mdx @@ -161,6 +161,7 @@ The following APIs can be combined with `variantAsync`. 'getFallbacksAsync', 'looseObjectAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'parseAsync', 'parserAsync', diff --git a/website/src/routes/api/(methods)/assert/index.mdx b/website/src/routes/api/(methods)/assert/index.mdx index 573cf9035..0892b354f 100644 --- a/website/src/routes/api/(methods)/assert/index.mdx +++ b/website/src/routes/api/(methods)/assert/index.mdx @@ -86,6 +86,7 @@ The following APIs can be combined with `assert`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(methods)/config/index.mdx b/website/src/routes/api/(methods)/config/index.mdx index 1ac708cbf..0cf64c948 100644 --- a/website/src/routes/api/(methods)/config/index.mdx +++ b/website/src/routes/api/(methods)/config/index.mdx @@ -108,6 +108,7 @@ The following APIs can be combined with `config`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -282,6 +283,7 @@ The following APIs can be combined with `config`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'partialAsync', diff --git a/website/src/routes/api/(methods)/fallback/index.mdx b/website/src/routes/api/(methods)/fallback/index.mdx index ef3e6518e..beb431e5f 100644 --- a/website/src/routes/api/(methods)/fallback/index.mdx +++ b/website/src/routes/api/(methods)/fallback/index.mdx @@ -107,6 +107,7 @@ The following APIs can be combined with `fallback`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(methods)/forward/index.mdx b/website/src/routes/api/(methods)/forward/index.mdx index 5f49734af..715316178 100644 --- a/website/src/routes/api/(methods)/forward/index.mdx +++ b/website/src/routes/api/(methods)/forward/index.mdx @@ -86,6 +86,7 @@ The following APIs can be combined with `forward`. 'object', 'objectWithRest', 'record', + 'recordWithPatterns', 'strictObject', 'strictTuple', 'tuple', diff --git a/website/src/routes/api/(methods)/getDefault/index.mdx b/website/src/routes/api/(methods)/getDefault/index.mdx index 3130180e4..640eb6558 100644 --- a/website/src/routes/api/(methods)/getDefault/index.mdx +++ b/website/src/routes/api/(methods)/getDefault/index.mdx @@ -85,6 +85,7 @@ The following APIs can be combined with `getDefault`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -138,6 +139,7 @@ The following APIs can be combined with `getDefault`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'partialAsync', diff --git a/website/src/routes/api/(methods)/getDefaults/index.mdx b/website/src/routes/api/(methods)/getDefaults/index.mdx index 1ced7139b..bb6a43dd4 100644 --- a/website/src/routes/api/(methods)/getDefaults/index.mdx +++ b/website/src/routes/api/(methods)/getDefaults/index.mdx @@ -99,6 +99,7 @@ The following APIs can be combined with `getDefaults`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(methods)/getFallback/index.mdx b/website/src/routes/api/(methods)/getFallback/index.mdx index cdfca2a80..364b92684 100644 --- a/website/src/routes/api/(methods)/getFallback/index.mdx +++ b/website/src/routes/api/(methods)/getFallback/index.mdx @@ -85,6 +85,7 @@ The following APIs can be combined with `getFallback`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -138,6 +139,7 @@ The following APIs can be combined with `getFallback`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'partialAsync', diff --git a/website/src/routes/api/(methods)/getFallbacks/index.mdx b/website/src/routes/api/(methods)/getFallbacks/index.mdx index af83d95bc..0d55a76e8 100644 --- a/website/src/routes/api/(methods)/getFallbacks/index.mdx +++ b/website/src/routes/api/(methods)/getFallbacks/index.mdx @@ -99,6 +99,7 @@ The following APIs can be combined with `getFallbacks`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(methods)/is/index.mdx b/website/src/routes/api/(methods)/is/index.mdx index 581701422..41920d795 100644 --- a/website/src/routes/api/(methods)/is/index.mdx +++ b/website/src/routes/api/(methods)/is/index.mdx @@ -91,6 +91,7 @@ The following APIs can be combined with `is`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(methods)/keyof/index.mdx b/website/src/routes/api/(methods)/keyof/index.mdx index dfcd920ca..fe778b285 100644 --- a/website/src/routes/api/(methods)/keyof/index.mdx +++ b/website/src/routes/api/(methods)/keyof/index.mdx @@ -68,6 +68,7 @@ The following APIs can be combined with `keyof`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -139,6 +140,7 @@ The following APIs can be combined with `keyof`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'partialAsync', diff --git a/website/src/routes/api/(methods)/message/index.mdx b/website/src/routes/api/(methods)/message/index.mdx index 91e0e470d..8991c8c82 100644 --- a/website/src/routes/api/(methods)/message/index.mdx +++ b/website/src/routes/api/(methods)/message/index.mdx @@ -91,6 +91,7 @@ The following APIs can be combined with `message`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -266,6 +267,7 @@ The following APIs can be combined with `message`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'partialAsync', diff --git a/website/src/routes/api/(methods)/omit/index.mdx b/website/src/routes/api/(methods)/omit/index.mdx index dd581aade..380c3e9e4 100644 --- a/website/src/routes/api/(methods)/omit/index.mdx +++ b/website/src/routes/api/(methods)/omit/index.mdx @@ -83,6 +83,7 @@ The following APIs can be combined with `omit`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -165,6 +166,7 @@ The following APIs can be combined with `omit`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(methods)/parse/index.mdx b/website/src/routes/api/(methods)/parse/index.mdx index 9f63111cb..c4526236d 100644 --- a/website/src/routes/api/(methods)/parse/index.mdx +++ b/website/src/routes/api/(methods)/parse/index.mdx @@ -92,6 +92,7 @@ The following APIs can be combined with `parse`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(methods)/parser/index.mdx b/website/src/routes/api/(methods)/parser/index.mdx index cc82cb490..9ebfd0c96 100644 --- a/website/src/routes/api/(methods)/parser/index.mdx +++ b/website/src/routes/api/(methods)/parser/index.mdx @@ -88,6 +88,7 @@ The following APIs can be combined with `parser`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(methods)/partial/index.mdx b/website/src/routes/api/(methods)/partial/index.mdx index 7224dcd3c..5d8e2850b 100644 --- a/website/src/routes/api/(methods)/partial/index.mdx +++ b/website/src/routes/api/(methods)/partial/index.mdx @@ -96,6 +96,7 @@ The following APIs can be combined with `partial`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(methods)/pick/index.mdx b/website/src/routes/api/(methods)/pick/index.mdx index a6a0d851a..b9ef0796e 100644 --- a/website/src/routes/api/(methods)/pick/index.mdx +++ b/website/src/routes/api/(methods)/pick/index.mdx @@ -83,6 +83,7 @@ The following APIs can be combined with `pick`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', @@ -165,6 +166,7 @@ The following APIs can be combined with `pick`. 'nullableAsync', 'nullishAsync', 'objectAsync', + 'recordWithPatternsAsync', 'objectWithRestAsync', 'optionalAsync', 'parseAsync', diff --git a/website/src/routes/api/(methods)/pipe/index.mdx b/website/src/routes/api/(methods)/pipe/index.mdx index 1681d4a9c..35b340288 100644 --- a/website/src/routes/api/(methods)/pipe/index.mdx +++ b/website/src/routes/api/(methods)/pipe/index.mdx @@ -110,6 +110,7 @@ The following APIs can be combined with `pipe`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(methods)/required/index.mdx b/website/src/routes/api/(methods)/required/index.mdx index 1638b421a..41c694a46 100644 --- a/website/src/routes/api/(methods)/required/index.mdx +++ b/website/src/routes/api/(methods)/required/index.mdx @@ -105,6 +105,7 @@ The following APIs can be combined with `required`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(methods)/safeParse/index.mdx b/website/src/routes/api/(methods)/safeParse/index.mdx index 3d4c12769..a00a11217 100644 --- a/website/src/routes/api/(methods)/safeParse/index.mdx +++ b/website/src/routes/api/(methods)/safeParse/index.mdx @@ -87,6 +87,7 @@ The following APIs can be combined with `safeParse`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(methods)/safeParser/index.mdx b/website/src/routes/api/(methods)/safeParser/index.mdx index 4f217d5f1..c7b4b0e9b 100644 --- a/website/src/routes/api/(methods)/safeParser/index.mdx +++ b/website/src/routes/api/(methods)/safeParser/index.mdx @@ -88,6 +88,7 @@ The following APIs can be combined with `safeParser`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/any/index.mdx b/website/src/routes/api/(schemas)/any/index.mdx index 74a0a5da0..da6bedb7c 100644 --- a/website/src/routes/api/(schemas)/any/index.mdx +++ b/website/src/routes/api/(schemas)/any/index.mdx @@ -51,6 +51,7 @@ The following APIs can be combined with `any`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/array/index.mdx b/website/src/routes/api/(schemas)/array/index.mdx index 813374362..4731d3b2d 100644 --- a/website/src/routes/api/(schemas)/array/index.mdx +++ b/website/src/routes/api/(schemas)/array/index.mdx @@ -123,6 +123,7 @@ The following APIs can be combined with `array`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/bigint/index.mdx b/website/src/routes/api/(schemas)/bigint/index.mdx index d42751b35..f1e9463f1 100644 --- a/website/src/routes/api/(schemas)/bigint/index.mdx +++ b/website/src/routes/api/(schemas)/bigint/index.mdx @@ -78,6 +78,7 @@ The following APIs can be combined with `bigint`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/blob/index.mdx b/website/src/routes/api/(schemas)/blob/index.mdx index 13f0b8035..a1f1b5aac 100644 --- a/website/src/routes/api/(schemas)/blob/index.mdx +++ b/website/src/routes/api/(schemas)/blob/index.mdx @@ -75,6 +75,7 @@ The following APIs can be combined with `blob`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/boolean/index.mdx b/website/src/routes/api/(schemas)/boolean/index.mdx index 020c50836..bc938aa77 100644 --- a/website/src/routes/api/(schemas)/boolean/index.mdx +++ b/website/src/routes/api/(schemas)/boolean/index.mdx @@ -74,6 +74,7 @@ The following APIs can be combined with `boolean`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/custom/index.mdx b/website/src/routes/api/(schemas)/custom/index.mdx index 01da23739..d24fd957c 100644 --- a/website/src/routes/api/(schemas)/custom/index.mdx +++ b/website/src/routes/api/(schemas)/custom/index.mdx @@ -79,6 +79,7 @@ The following APIs can be combined with `custom`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/date/index.mdx b/website/src/routes/api/(schemas)/date/index.mdx index 2fc555be9..7f363e927 100644 --- a/website/src/routes/api/(schemas)/date/index.mdx +++ b/website/src/routes/api/(schemas)/date/index.mdx @@ -83,6 +83,7 @@ The following APIs can be combined with `date`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/enum/index.mdx b/website/src/routes/api/(schemas)/enum/index.mdx index 2183ced2f..371e243b6 100644 --- a/website/src/routes/api/(schemas)/enum/index.mdx +++ b/website/src/routes/api/(schemas)/enum/index.mdx @@ -76,6 +76,7 @@ The following APIs can be combined with `enum`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/exactOptional/index.mdx b/website/src/routes/api/(schemas)/exactOptional/index.mdx index 17fb696e6..cae2ca761 100644 --- a/website/src/routes/api/(schemas)/exactOptional/index.mdx +++ b/website/src/routes/api/(schemas)/exactOptional/index.mdx @@ -105,6 +105,7 @@ The following APIs can be combined with `exactOptional`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/file/index.mdx b/website/src/routes/api/(schemas)/file/index.mdx index 00fec2323..acfc0de55 100644 --- a/website/src/routes/api/(schemas)/file/index.mdx +++ b/website/src/routes/api/(schemas)/file/index.mdx @@ -75,6 +75,7 @@ The following APIs can be combined with `file`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/function/index.mdx b/website/src/routes/api/(schemas)/function/index.mdx index 73a8b11a2..45ac4b6c4 100644 --- a/website/src/routes/api/(schemas)/function/index.mdx +++ b/website/src/routes/api/(schemas)/function/index.mdx @@ -57,6 +57,7 @@ The following APIs can be combined with `function`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/instance/index.mdx b/website/src/routes/api/(schemas)/instance/index.mdx index e36572f55..535f47050 100644 --- a/website/src/routes/api/(schemas)/instance/index.mdx +++ b/website/src/routes/api/(schemas)/instance/index.mdx @@ -84,6 +84,7 @@ The following APIs can be combined with `instance`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/intersect/index.mdx b/website/src/routes/api/(schemas)/intersect/index.mdx index a1cc20c42..b8b4bf0a0 100644 --- a/website/src/routes/api/(schemas)/intersect/index.mdx +++ b/website/src/routes/api/(schemas)/intersect/index.mdx @@ -95,6 +95,7 @@ The following APIs can be combined with `intersect`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/lazy/index.mdx b/website/src/routes/api/(schemas)/lazy/index.mdx index 8843c18a5..5b08843a2 100644 --- a/website/src/routes/api/(schemas)/lazy/index.mdx +++ b/website/src/routes/api/(schemas)/lazy/index.mdx @@ -158,6 +158,7 @@ The following APIs can be combined with `lazy`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/literal/index.mdx b/website/src/routes/api/(schemas)/literal/index.mdx index c5f52a84e..8a556edf3 100644 --- a/website/src/routes/api/(schemas)/literal/index.mdx +++ b/website/src/routes/api/(schemas)/literal/index.mdx @@ -87,6 +87,7 @@ The following APIs can be combined with `literal`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/looseObject/index.mdx b/website/src/routes/api/(schemas)/looseObject/index.mdx index 614963eb6..d5952e161 100644 --- a/website/src/routes/api/(schemas)/looseObject/index.mdx +++ b/website/src/routes/api/(schemas)/looseObject/index.mdx @@ -134,6 +134,7 @@ The following APIs can be combined with `looseObject`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/looseTuple/index.mdx b/website/src/routes/api/(schemas)/looseTuple/index.mdx index b1bc2d624..e31497634 100644 --- a/website/src/routes/api/(schemas)/looseTuple/index.mdx +++ b/website/src/routes/api/(schemas)/looseTuple/index.mdx @@ -90,6 +90,7 @@ The following APIs can be combined with `looseTuple`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/map/index.mdx b/website/src/routes/api/(schemas)/map/index.mdx index 5e3a98818..74f8cb04f 100644 --- a/website/src/routes/api/(schemas)/map/index.mdx +++ b/website/src/routes/api/(schemas)/map/index.mdx @@ -97,6 +97,7 @@ The following APIs can be combined with `map`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/nan/index.mdx b/website/src/routes/api/(schemas)/nan/index.mdx index efad1f3fa..3bf8f6e2c 100644 --- a/website/src/routes/api/(schemas)/nan/index.mdx +++ b/website/src/routes/api/(schemas)/nan/index.mdx @@ -57,6 +57,7 @@ The following APIs can be combined with `nan`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/never/index.mdx b/website/src/routes/api/(schemas)/never/index.mdx index fdd9661f7..91ddd76ab 100644 --- a/website/src/routes/api/(schemas)/never/index.mdx +++ b/website/src/routes/api/(schemas)/never/index.mdx @@ -57,6 +57,7 @@ The following APIs can be combined with `never`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/nonNullable/index.mdx b/website/src/routes/api/(schemas)/nonNullable/index.mdx index ae1c7e3aa..b4de0c4e2 100644 --- a/website/src/routes/api/(schemas)/nonNullable/index.mdx +++ b/website/src/routes/api/(schemas)/nonNullable/index.mdx @@ -99,6 +99,7 @@ The following APIs can be combined with `nonNullable`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/nonNullish/index.mdx b/website/src/routes/api/(schemas)/nonNullish/index.mdx index 5229a8dfa..c6e4a82cc 100644 --- a/website/src/routes/api/(schemas)/nonNullish/index.mdx +++ b/website/src/routes/api/(schemas)/nonNullish/index.mdx @@ -99,6 +99,7 @@ The following APIs can be combined with `nonNullish`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/nonOptional/index.mdx b/website/src/routes/api/(schemas)/nonOptional/index.mdx index 4d1afd4ec..4b73affb1 100644 --- a/website/src/routes/api/(schemas)/nonOptional/index.mdx +++ b/website/src/routes/api/(schemas)/nonOptional/index.mdx @@ -99,6 +99,7 @@ The following APIs can be combined with `nonOptional`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/null/index.mdx b/website/src/routes/api/(schemas)/null/index.mdx index c57c7fbe8..9351bb64a 100644 --- a/website/src/routes/api/(schemas)/null/index.mdx +++ b/website/src/routes/api/(schemas)/null/index.mdx @@ -57,6 +57,7 @@ The following APIs can be combined with `null`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/nullable/index.mdx b/website/src/routes/api/(schemas)/nullable/index.mdx index 61483af08..1a801f0fa 100644 --- a/website/src/routes/api/(schemas)/nullable/index.mdx +++ b/website/src/routes/api/(schemas)/nullable/index.mdx @@ -120,6 +120,7 @@ The following APIs can be combined with `nullable`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/nullish/index.mdx b/website/src/routes/api/(schemas)/nullish/index.mdx index 8d6a03f29..a3293d12e 100644 --- a/website/src/routes/api/(schemas)/nullish/index.mdx +++ b/website/src/routes/api/(schemas)/nullish/index.mdx @@ -120,6 +120,7 @@ The following APIs can be combined with `nullish`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/number/index.mdx b/website/src/routes/api/(schemas)/number/index.mdx index 4fdedf188..312617aa9 100644 --- a/website/src/routes/api/(schemas)/number/index.mdx +++ b/website/src/routes/api/(schemas)/number/index.mdx @@ -86,6 +86,7 @@ The following APIs can be combined with `number`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/object/index.mdx b/website/src/routes/api/(schemas)/object/index.mdx index 5136b014e..301cb0fa0 100644 --- a/website/src/routes/api/(schemas)/object/index.mdx +++ b/website/src/routes/api/(schemas)/object/index.mdx @@ -134,6 +134,7 @@ The following APIs can be combined with `object`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/objectWithRest/index.mdx b/website/src/routes/api/(schemas)/objectWithRest/index.mdx index d0a2ab58e..b7eb8ca43 100644 --- a/website/src/routes/api/(schemas)/objectWithRest/index.mdx +++ b/website/src/routes/api/(schemas)/objectWithRest/index.mdx @@ -152,6 +152,7 @@ The following APIs can be combined with `objectWithRest`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/optional/index.mdx b/website/src/routes/api/(schemas)/optional/index.mdx index f6c2258d9..d4c1ed1dd 100644 --- a/website/src/routes/api/(schemas)/optional/index.mdx +++ b/website/src/routes/api/(schemas)/optional/index.mdx @@ -120,6 +120,7 @@ The following APIs can be combined with `optional`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/picklist/index.mdx b/website/src/routes/api/(schemas)/picklist/index.mdx index 9c3ff73cc..376662e31 100644 --- a/website/src/routes/api/(schemas)/picklist/index.mdx +++ b/website/src/routes/api/(schemas)/picklist/index.mdx @@ -93,6 +93,7 @@ The following APIs can be combined with `picklist`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/promise/index.mdx b/website/src/routes/api/(schemas)/promise/index.mdx index 31ca29320..a2a1fd2a8 100644 --- a/website/src/routes/api/(schemas)/promise/index.mdx +++ b/website/src/routes/api/(schemas)/promise/index.mdx @@ -73,6 +73,7 @@ The following APIs can be combined with `promise`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/recordWithPatterns/index.mdx b/website/src/routes/api/(schemas)/recordWithPatterns/index.mdx new file mode 100644 index 000000000..840629d9d --- /dev/null +++ b/website/src/routes/api/(schemas)/recordWithPatterns/index.mdx @@ -0,0 +1,167 @@ +--- +title: recordWithPatterns +description: Creates a record schema that matches patterns. +source: /schemas/recordWithPatterns/recordWithPatterns.ts +contributors: + - EskiMojo14 +--- + +import { Link } from '@builder.io/qwik-city'; +import { ApiList, Property } from '~/components'; +import { properties } from './properties'; + +# recordWithPatterns + +Creates a record schema that matches patterns. + +```ts +const RecordWithPatternsSchema = v.recordWithPatterns< + TPatterns, + TRest, + TMessage +>(patterns, rest, message); +``` + +## Generics + +- `TPatterns` +- `TRest` +- `TMessage` + +## Parameters + +- `patterns` +- `rest` +- `message` + +## Returns + +- `Schema` + +## Explanation + +Tuples of key and value schemas are iterated through until a key schema matches, and the value schema is used to validate the value. If no key schema matches, the rest schema is used. + +## Examples + +The following examples show how `recordWithPatterns` can be used. Please see the object guide for more examples and explanations. + +```ts +const RecordWithPatternsSchema = v.recordWithPatterns( + [ + [v.pipe(v.string(), v.startsWith('str-')), v.string()], + [v.pipe(v.string(), v.startsWith('num-')), v.number()], + ], + v.boolean() +); +``` + +## Related + +The following APIs can be combined with `recordWithPatterns`. + +### Schemas + + + +### Methods + + + +### Actions + + + +### Utils + + diff --git a/website/src/routes/api/(schemas)/recordWithPatterns/properties.ts b/website/src/routes/api/(schemas)/recordWithPatterns/properties.ts new file mode 100644 index 000000000..8ec7f8838 --- /dev/null +++ b/website/src/routes/api/(schemas)/recordWithPatterns/properties.ts @@ -0,0 +1,90 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + TPatterns: { + modifier: 'extends', + type: { + type: 'custom', + name: 'PatternTuples', + href: '../PatternTuples/', + }, + }, + TRest: { + modifier: 'extends', + type: { + type: 'custom', + name: 'BaseSchema', + href: '../BaseSchema/', + generics: [ + 'unknown', + 'unknown', + { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + ], + }, + }, + TMessage: { + modifier: 'extends', + type: { + type: 'union', + options: [ + { + type: 'custom', + name: 'ErrorMessage', + href: '../ErrorMessage/', + generics: [ + { + type: 'custom', + name: 'RecordWithPatternsIssue', + href: '../RecordWithPatternsIssue/', + }, + ], + }, + 'undefined', + ], + }, + }, + patterns: { + type: { + type: 'custom', + name: 'TPatterns', + }, + }, + rest: { + type: { + type: 'custom', + name: 'TRest', + }, + }, + message: { + type: { + type: 'custom', + name: 'TMessage', + }, + }, + Schema: { + type: { + type: 'custom', + name: 'RecordWithPatternsSchema', + href: '../RecordWithPatternsSchema/', + generics: [ + { + type: 'custom', + name: 'TPatterns', + }, + { + type: 'custom', + name: 'TRest', + }, + { + type: 'custom', + name: 'TMessage', + }, + ], + }, + }, +}; diff --git a/website/src/routes/api/(schemas)/set/index.mdx b/website/src/routes/api/(schemas)/set/index.mdx index 7c412eb5a..42f3b98ba 100644 --- a/website/src/routes/api/(schemas)/set/index.mdx +++ b/website/src/routes/api/(schemas)/set/index.mdx @@ -96,6 +96,7 @@ The following APIs can be combined with `set`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'strictObject', 'strictTuple', 'string', diff --git a/website/src/routes/api/(schemas)/strictObject/index.mdx b/website/src/routes/api/(schemas)/strictObject/index.mdx index 7f2eac7ff..a5b96c5da 100644 --- a/website/src/routes/api/(schemas)/strictObject/index.mdx +++ b/website/src/routes/api/(schemas)/strictObject/index.mdx @@ -135,6 +135,7 @@ The following APIs can be combined with `strictObject`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictTuple', 'string', diff --git a/website/src/routes/api/(schemas)/strictTuple/index.mdx b/website/src/routes/api/(schemas)/strictTuple/index.mdx index 65ca97f74..f8fa812c3 100644 --- a/website/src/routes/api/(schemas)/strictTuple/index.mdx +++ b/website/src/routes/api/(schemas)/strictTuple/index.mdx @@ -91,6 +91,7 @@ The following APIs can be combined with `strictTuple`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'string', diff --git a/website/src/routes/api/(schemas)/string/index.mdx b/website/src/routes/api/(schemas)/string/index.mdx index e335716f7..5478a84f5 100644 --- a/website/src/routes/api/(schemas)/string/index.mdx +++ b/website/src/routes/api/(schemas)/string/index.mdx @@ -104,6 +104,7 @@ The following APIs can be combined with `string`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/symbol/index.mdx b/website/src/routes/api/(schemas)/symbol/index.mdx index 9661419b7..3bb80afd2 100644 --- a/website/src/routes/api/(schemas)/symbol/index.mdx +++ b/website/src/routes/api/(schemas)/symbol/index.mdx @@ -70,6 +70,7 @@ The following APIs can be combined with `symbol`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/tuple/index.mdx b/website/src/routes/api/(schemas)/tuple/index.mdx index efe7205e6..2f04f16b3 100644 --- a/website/src/routes/api/(schemas)/tuple/index.mdx +++ b/website/src/routes/api/(schemas)/tuple/index.mdx @@ -91,6 +91,7 @@ The following APIs can be combined with `tuple`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/tupleWithRest/index.mdx b/website/src/routes/api/(schemas)/tupleWithRest/index.mdx index 99048f639..04692bca9 100644 --- a/website/src/routes/api/(schemas)/tupleWithRest/index.mdx +++ b/website/src/routes/api/(schemas)/tupleWithRest/index.mdx @@ -94,6 +94,7 @@ The following APIs can be combined with `tupleWithRest`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/undefined/index.mdx b/website/src/routes/api/(schemas)/undefined/index.mdx index 6bb2ba4f3..2370eb391 100644 --- a/website/src/routes/api/(schemas)/undefined/index.mdx +++ b/website/src/routes/api/(schemas)/undefined/index.mdx @@ -57,6 +57,7 @@ The following APIs can be combined with `undefined`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/undefinedable/index.mdx b/website/src/routes/api/(schemas)/undefinedable/index.mdx index e96210ed8..23a1a8028 100644 --- a/website/src/routes/api/(schemas)/undefinedable/index.mdx +++ b/website/src/routes/api/(schemas)/undefinedable/index.mdx @@ -124,6 +124,7 @@ The following APIs can be combined with `undefinedable`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/union/index.mdx b/website/src/routes/api/(schemas)/union/index.mdx index 365234239..63458900b 100644 --- a/website/src/routes/api/(schemas)/union/index.mdx +++ b/website/src/routes/api/(schemas)/union/index.mdx @@ -112,6 +112,7 @@ The following APIs can be combined with `union`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/unknown/index.mdx b/website/src/routes/api/(schemas)/unknown/index.mdx index 40d6ba470..559604c05 100644 --- a/website/src/routes/api/(schemas)/unknown/index.mdx +++ b/website/src/routes/api/(schemas)/unknown/index.mdx @@ -52,6 +52,7 @@ The following APIs can be combined with `unknown`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(schemas)/void/index.mdx b/website/src/routes/api/(schemas)/void/index.mdx index b282bc615..d0bf80cd4 100644 --- a/website/src/routes/api/(schemas)/void/index.mdx +++ b/website/src/routes/api/(schemas)/void/index.mdx @@ -57,6 +57,7 @@ The following APIs can be combined with `void`. 'objectWithRest', 'optional', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/(types)/PatternTuple/index.mdx b/website/src/routes/api/(types)/PatternTuple/index.mdx new file mode 100644 index 000000000..4836dc15f --- /dev/null +++ b/website/src/routes/api/(types)/PatternTuple/index.mdx @@ -0,0 +1,17 @@ +--- +title: PatternTuple +description: Pattern tuple type. +contributors: + - EskiMojo14 +--- + +import { Property } from '~/components'; +import { properties } from './properties'; + +# PatternTuple + +Pattern tuple type. + +## Definition + +- `PatternTuple` diff --git a/website/src/routes/api/(types)/PatternTuple/properties.ts b/website/src/routes/api/(types)/PatternTuple/properties.ts new file mode 100644 index 000000000..834085b53 --- /dev/null +++ b/website/src/routes/api/(types)/PatternTuple/properties.ts @@ -0,0 +1,43 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + PatternTuple: { + type: { + type: 'tuple', + modifier: 'readonly', + itemLabels: ['key', 'value'], + items: [ + { + type: 'custom', + name: 'BaseSchema', + href: '../BaseSchema/', + generics: [ + 'unknown', + 'unknown', + { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + ], + }, + { + type: 'custom', + name: 'BaseSchema', + href: '../BaseSchema/', + generics: [ + 'unknown', + 'unknown', + { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + ], + }, + ], + }, + }, +}; diff --git a/website/src/routes/api/(types)/PatternTupleAsync/index.mdx b/website/src/routes/api/(types)/PatternTupleAsync/index.mdx new file mode 100644 index 000000000..aeed468c6 --- /dev/null +++ b/website/src/routes/api/(types)/PatternTupleAsync/index.mdx @@ -0,0 +1,17 @@ +--- +title: PatternTupleAsync +description: Pattern tuple async type. +contributors: + - EskiMojo14 +--- + +import { Property } from '~/components'; +import { properties } from './properties'; + +# PatternTupleAsync + +Pattern tuple async type. + +## Definition + +- `PatternTupleAsync` diff --git a/website/src/routes/api/(types)/PatternTupleAsync/properties.ts b/website/src/routes/api/(types)/PatternTupleAsync/properties.ts new file mode 100644 index 000000000..9432e2769 --- /dev/null +++ b/website/src/routes/api/(types)/PatternTupleAsync/properties.ts @@ -0,0 +1,83 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + PatternTupleAsync: { + type: { + type: 'tuple', + modifier: 'readonly', + itemLabels: ['key', 'value'], + items: [ + { + type: 'union', + options: [ + { + type: 'custom', + name: 'BaseSchema', + href: '../BaseSchema/', + generics: [ + 'string', + 'string', + { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + ], + }, + { + type: 'custom', + name: 'BaseSchemaAsync', + href: '../BaseSchemaAsync/', + generics: [ + 'string', + 'string', + { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + ], + }, + ], + }, + { + type: 'union', + options: [ + { + type: 'custom', + name: 'BaseSchema', + href: '../BaseSchema/', + generics: [ + 'unknown', + 'unknown', + { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + ], + }, + { + type: 'custom', + name: 'BaseSchemaAsync', + href: '../BaseSchemaAsync/', + generics: [ + 'unknown', + 'unknown', + { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + ], + }, + ], + }, + ], + }, + }, +}; diff --git a/website/src/routes/api/(types)/PatternTuples/index.mdx b/website/src/routes/api/(types)/PatternTuples/index.mdx new file mode 100644 index 000000000..d820cdd36 --- /dev/null +++ b/website/src/routes/api/(types)/PatternTuples/index.mdx @@ -0,0 +1,17 @@ +--- +title: PatternTuples +description: Pattern tuples type. +contributors: + - EskiMojo14 +--- + +import { Property } from '~/components'; +import { properties } from './properties'; + +# PatternTuples + +Pattern tuples type. + +## Definition + +- `PatternTuples` diff --git a/website/src/routes/api/(types)/PatternTuples/properties.ts b/website/src/routes/api/(types)/PatternTuples/properties.ts new file mode 100644 index 000000000..c5ee21419 --- /dev/null +++ b/website/src/routes/api/(types)/PatternTuples/properties.ts @@ -0,0 +1,22 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + PatternTuples: { + type: { + type: 'tuple', + modifier: 'readonly', + items: [ + { type: 'custom', name: 'PatternTuple', href: '../PatternTuple/' }, + { + type: 'array', + spread: true, + item: { + type: 'custom', + name: 'PatternTuple', + href: '../PatternTuple/', + }, + }, + ], + }, + }, +}; diff --git a/website/src/routes/api/(types)/PatternTuplesAsync/index.mdx b/website/src/routes/api/(types)/PatternTuplesAsync/index.mdx new file mode 100644 index 000000000..322ac3dd7 --- /dev/null +++ b/website/src/routes/api/(types)/PatternTuplesAsync/index.mdx @@ -0,0 +1,17 @@ +--- +title: PatternTuplesAsync +description: Pattern tuples async type. +contributors: + - EskiMojo14 +--- + +import { Property } from '~/components'; +import { properties } from './properties'; + +# PatternTuplesAsync + +Pattern tuples async type. + +## Definition + +- `PatternTuplesAsync` diff --git a/website/src/routes/api/(types)/PatternTuplesAsync/properties.ts b/website/src/routes/api/(types)/PatternTuplesAsync/properties.ts new file mode 100644 index 000000000..64d088b92 --- /dev/null +++ b/website/src/routes/api/(types)/PatternTuplesAsync/properties.ts @@ -0,0 +1,26 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + PatternTuplesAsync: { + type: { + type: 'tuple', + modifier: 'readonly', + items: [ + { + type: 'custom', + name: 'PatternTupleAsync', + href: '../PatternTupleAsync/', + }, + { + type: 'array', + spread: true, + item: { + type: 'custom', + name: 'PatternTupleAsync', + href: '../PatternTupleAsync/', + }, + }, + ], + }, + }, +}; diff --git a/website/src/routes/api/(types)/RecordWithPatternsIssue/index.mdx b/website/src/routes/api/(types)/RecordWithPatternsIssue/index.mdx new file mode 100644 index 000000000..b1f524de1 --- /dev/null +++ b/website/src/routes/api/(types)/RecordWithPatternsIssue/index.mdx @@ -0,0 +1,20 @@ +--- +title: RecordWithPatternsIssue +description: Record with patterns issue interface. +contributors: + - EskiMojo14 +--- + +import { Property } from '~/components'; +import { properties } from './properties'; + +# RecordWithPatternsIssue + +Record with patterns issue interface. + +## Definition + +- `RecordWithPatternsIssue` + - `kind` + - `type` + - `expected` diff --git a/website/src/routes/api/(types)/RecordWithPatternsIssue/properties.ts b/website/src/routes/api/(types)/RecordWithPatternsIssue/properties.ts new file mode 100644 index 000000000..513c87736 --- /dev/null +++ b/website/src/routes/api/(types)/RecordWithPatternsIssue/properties.ts @@ -0,0 +1,50 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + BaseIssue: { + modifier: 'extends', + type: { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + }, + kind: { + type: { + type: 'string', + value: 'schema', + }, + }, + type: { + type: { + type: 'string', + value: 'record_with_patterns', + }, + }, + expected: { + type: { + type: 'union', + options: [ + { + type: 'string', + value: 'Object', + }, + { + type: 'template', + parts: [ + { + type: 'string', + value: '"', + }, + 'string', + { + type: 'string', + value: '"', + }, + ], + }, + ], + }, + }, +}; diff --git a/website/src/routes/api/(types)/RecordWithPatternsSchema/index.mdx b/website/src/routes/api/(types)/RecordWithPatternsSchema/index.mdx new file mode 100644 index 000000000..f2d4c3e6c --- /dev/null +++ b/website/src/routes/api/(types)/RecordWithPatternsSchema/index.mdx @@ -0,0 +1,29 @@ +--- +title: RecordWithPatternsSchema +description: Record with patterns schema interface. +contributors: + - EskiMojo14 +--- + +import { Property } from '~/components'; +import { properties } from './properties'; + +# RecordWithPatternsSchema + +Record with patterns schema interface. + +## Generics + +- `TPatterns` +- `TRest` +- `TMessage` + +## Definition + +- `RecordWithPatternsSchema` + - `type` + - `reference` + - `expects` + - `patterns` + - `rest` + - `message` diff --git a/website/src/routes/api/(types)/RecordWithPatternsSchema/properties.ts b/website/src/routes/api/(types)/RecordWithPatternsSchema/properties.ts new file mode 100644 index 000000000..afe711802 --- /dev/null +++ b/website/src/routes/api/(types)/RecordWithPatternsSchema/properties.ts @@ -0,0 +1,69 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + TPatterns: { + modifier: 'extends', + type: { + type: 'custom', + name: 'PatternTuples', + href: '../PatternTuples/', + }, + }, + TRest: { + modifier: 'extends', + type: { + type: 'custom', + name: 'BaseSchema', + href: '../BaseSchema/', + generics: [ + 'unknown', + 'unknown', + { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + ], + }, + }, + TMessage: { + modifier: 'extends', + type: { + type: 'union', + options: [ + { + type: 'custom', + name: 'ErrorMessage', + href: '../ErrorMessage/', + generics: [ + { + type: 'custom', + name: 'RecordWithPatternsIssue', + href: '../RecordWithPatternsIssue/', + }, + ], + }, + 'undefined', + ], + }, + }, + patterns: { + type: { + type: 'custom', + name: 'TPatterns', + }, + }, + rest: { + type: { + type: 'custom', + name: 'TRest', + }, + }, + message: { + type: { + type: 'custom', + name: 'TMessage', + }, + }, +}; diff --git a/website/src/routes/api/(types)/RecordWithPatternsSchemaAsync/index.mdx b/website/src/routes/api/(types)/RecordWithPatternsSchemaAsync/index.mdx new file mode 100644 index 000000000..85a090e23 --- /dev/null +++ b/website/src/routes/api/(types)/RecordWithPatternsSchemaAsync/index.mdx @@ -0,0 +1,29 @@ +--- +title: RecordWithPatternsSchemaAsync +description: Record with patterns schema async interface. +contributors: + - EskiMojo14 +--- + +import { Property } from '~/components'; +import { properties } from './properties'; + +# RecordWithPatternsSchemaAsync + +Record with patterns schema async interface. + +## Generics + +- `TPatterns` +- `TRest` +- `TMessage` + +## Definition + +- `RecordWithPatternsSchemaAsync` + - `type` + - `reference` + - `expects` + - `patterns` + - `rest` + - `message` diff --git a/website/src/routes/api/(types)/RecordWithPatternsSchemaAsync/properties.ts b/website/src/routes/api/(types)/RecordWithPatternsSchemaAsync/properties.ts new file mode 100644 index 000000000..dac34b403 --- /dev/null +++ b/website/src/routes/api/(types)/RecordWithPatternsSchemaAsync/properties.ts @@ -0,0 +1,89 @@ +import type { PropertyProps } from '~/components'; + +export const properties: Record = { + TPatterns: { + modifier: 'extends', + type: { + type: 'custom', + name: 'PatternTuplesAsync', + href: '../PatternTuplesAsync/', + }, + }, + TRest: { + modifier: 'extends', + type: { + type: 'union', + options: [ + { + type: 'custom', + name: 'BaseSchema', + href: '../BaseSchema/', + generics: [ + 'unknown', + 'unknown', + { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + ], + }, + { + type: 'custom', + name: 'BaseSchemaAsync', + href: '../BaseSchemaAsync/', + generics: [ + 'unknown', + 'unknown', + { + type: 'custom', + name: 'BaseIssue', + href: '../BaseIssue/', + generics: ['unknown'], + }, + ], + }, + ], + }, + }, + TMessage: { + modifier: 'extends', + type: { + type: 'union', + options: [ + { + type: 'custom', + name: 'ErrorMessage', + href: '../ErrorMessage/', + generics: [ + { + type: 'custom', + name: 'RecordWithPatternsIssue', + href: '../RecordWithPatternsIssue/', + }, + ], + }, + 'undefined', + ], + }, + }, + patterns: { + type: { + type: 'custom', + name: 'TPatterns', + }, + }, + rest: { + type: { + type: 'custom', + name: 'TRest', + }, + }, + message: { + type: { + type: 'custom', + name: 'TMessage', + }, + }, +}; diff --git a/website/src/routes/api/(utils)/entriesFromList/index.mdx b/website/src/routes/api/(utils)/entriesFromList/index.mdx index df7e108ea..3757ffbdf 100644 --- a/website/src/routes/api/(utils)/entriesFromList/index.mdx +++ b/website/src/routes/api/(utils)/entriesFromList/index.mdx @@ -81,6 +81,7 @@ The following APIs can be combined with `entriesFromList`. 'picklist', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple', diff --git a/website/src/routes/api/menu.md b/website/src/routes/api/menu.md index 6e428cefa..bf80aefc8 100644 --- a/website/src/routes/api/menu.md +++ b/website/src/routes/api/menu.md @@ -35,6 +35,7 @@ - [picklist](/api/picklist/) - [promise](/api/promise/) - [record](/api/record/) +- [recordWithPatterns](/api/recordWithPatterns/) - [set](/api/set/) - [strictObject](/api/strictObject/) - [strictTuple](/api/strictTuple/) @@ -240,6 +241,7 @@ - [rawCheckAsync](/api/rawCheckAsync/) - [rawTransformAsync](/api/rawTransformAsync/) - [recordAsync](/api/recordAsync/) +- [recordWithPatternsAsync](/api/recordWithPatternsAsync/) - [requiredAsync](/api/requiredAsync/) - [returnsAsync](/api/returnsAsync/) - [safeParseAsync](/api/safeParseAsync/) @@ -571,6 +573,10 @@ - [PartialCheckIssue](/api/PartialCheckIssue/) - [PartialDataset](/api/PartialDataset/) - [PartialInput](/api/PartialInput/) +- [PatternTuple](/api/PatternTuple/) +- [PatternTupleAsync](/api/PatternTupleAsync/) +- [PatternTuples](/api/PatternTuples/) +- [PatternTuplesAsync](/api/PatternTuplesAsync/) - [PicklistOptions](/api/PicklistOptions/) - [PicklistIssue](/api/PicklistIssue/) - [PicklistSchema](/api/PicklistSchema/) @@ -590,6 +596,9 @@ - [RecordIssue](/api/RecordIssue/) - [RecordSchema](/api/RecordSchema/) - [RecordSchemaAsync](/api/RecordSchemaAsync/) +- [RecordWithPatternsIssue](/api/RecordWithPatternsIssue/) +- [RecordWithPatternsSchema](/api/RecordWithPatternsSchema/) +- [RecordWithPatternsSchemaAsync](/api/RecordWithPatternsSchemaAsync/) - [ReduceItemsAction](/api/ReduceItemsAction/) - [RegexAction](/api/RegexAction/) - [RegexIssue](/api/RegexIssue/) diff --git a/website/src/routes/guides/(main-concepts)/schemas/index.mdx b/website/src/routes/guides/(main-concepts)/schemas/index.mdx index 0a25fc54f..79599942f 100644 --- a/website/src/routes/guides/(main-concepts)/schemas/index.mdx +++ b/website/src/routes/guides/(main-concepts)/schemas/index.mdx @@ -69,6 +69,7 @@ Among complex values, Valibot supports objects, records, arrays, tuples, and sev 'objectWithRest', 'promise', 'record', + 'recordWithPatterns', 'set', 'strictObject', 'strictTuple',