@ultimat3/schema 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +100 -0
  3. package/package.json +33 -0
  4. package/src/builder.d.ts +62 -0
  5. package/src/builder.d.ts.map +1 -0
  6. package/src/builder.js +93 -0
  7. package/src/builder.js.map +1 -0
  8. package/src/builder.ts +173 -0
  9. package/src/coerce.d.ts +15 -0
  10. package/src/coerce.d.ts.map +1 -0
  11. package/src/coerce.js +123 -0
  12. package/src/coerce.js.map +1 -0
  13. package/src/coerce.ts +125 -0
  14. package/src/errors.d.ts +62 -0
  15. package/src/errors.d.ts.map +1 -0
  16. package/src/errors.js +85 -0
  17. package/src/errors.js.map +1 -0
  18. package/src/errors.ts +140 -0
  19. package/src/index.d.ts +19 -0
  20. package/src/index.d.ts.map +1 -0
  21. package/src/index.js +11 -0
  22. package/src/index.js.map +1 -0
  23. package/src/index.ts +102 -0
  24. package/src/json-schema.d.ts +37 -0
  25. package/src/json-schema.d.ts.map +1 -0
  26. package/src/json-schema.js +108 -0
  27. package/src/json-schema.js.map +1 -0
  28. package/src/json-schema.ts +149 -0
  29. package/src/node.d.ts +32 -0
  30. package/src/node.d.ts.map +1 -0
  31. package/src/node.js +24 -0
  32. package/src/node.js.map +1 -0
  33. package/src/node.ts +75 -0
  34. package/src/provider.d.ts +32 -0
  35. package/src/provider.d.ts.map +1 -0
  36. package/src/provider.js +49 -0
  37. package/src/provider.js.map +1 -0
  38. package/src/provider.ts +67 -0
  39. package/src/standard.d.ts +44 -0
  40. package/src/standard.d.ts.map +1 -0
  41. package/src/standard.js +71 -0
  42. package/src/standard.js.map +1 -0
  43. package/src/standard.ts +160 -0
  44. package/src/t.d.ts +6 -0
  45. package/src/t.d.ts.map +1 -0
  46. package/src/t.js +79 -0
  47. package/src/t.js.map +1 -0
  48. package/src/t.ts +101 -0
  49. package/src/validators.d.ts +63 -0
  50. package/src/validators.d.ts.map +1 -0
  51. package/src/validators.js +271 -0
  52. package/src/validators.js.map +1 -0
  53. package/src/validators.ts +389 -0
@@ -0,0 +1,71 @@
1
+ // Single responsibility: the Standard Schema v1 interface plus library-agnostic helpers.
2
+ // This is the swap point: every Ultimate primitive accepts any conforming schema, so ArkType,
3
+ // Zod and Valibot are all first-class without a line of adapter code.
4
+ import { SchemaUnsupportedError, ValidationFailedError } from './errors';
5
+ /** `['items', 0, 'price']` -> `items[0].price` */
6
+ export function formatPath(path) {
7
+ if (path === undefined || path.length === 0)
8
+ return '';
9
+ let out = '';
10
+ for (const segment of path) {
11
+ const key = typeof segment === 'object' ? segment.key : segment;
12
+ if (typeof key === 'number') {
13
+ out += `[${key}]`;
14
+ }
15
+ else {
16
+ out += out === '' ? String(key) : `.${String(key)}`;
17
+ }
18
+ }
19
+ return out;
20
+ }
21
+ /** Normalise any conforming library's issues into Ultimate's path-annotated shape. */
22
+ export function toValidationIssues(issues) {
23
+ return issues.map((issue) => ({
24
+ path: formatPath(issue.path),
25
+ expected: issue.message,
26
+ received: '',
27
+ message: issue.message,
28
+ }));
29
+ }
30
+ function assertSync(result, vendor) {
31
+ if (result instanceof Promise) {
32
+ throw new SchemaUnsupportedError({
33
+ cause: `${vendor} validated asynchronously in a synchronous call site`,
34
+ fix: 'call validateAsync()/parseAsync() instead of validate()/parse()',
35
+ meta: { vendor },
36
+ });
37
+ }
38
+ return result;
39
+ }
40
+ /** Validate against ANY conforming schema. Never throws on invalid input. */
41
+ export function validate(schema, value) {
42
+ const props = schema['~standard'];
43
+ return assertSync(props.validate(value), props.vendor);
44
+ }
45
+ export async function validateAsync(schema, value) {
46
+ const result = await schema['~standard'].validate(value);
47
+ return result;
48
+ }
49
+ /** Validate or throw `X_VALIDATION_FAILED` with a path-annotated issue list. */
50
+ export function parse(schema, value, root = 'value') {
51
+ const result = validate(schema, value);
52
+ if (result.issues === undefined)
53
+ return result.value;
54
+ throw new ValidationFailedError(toValidationIssues(result.issues), root);
55
+ }
56
+ export async function parseAsync(schema, value, root = 'value') {
57
+ const result = await validateAsync(schema, value);
58
+ if (result.issues === undefined)
59
+ return result.value;
60
+ throw new ValidationFailedError(toValidationIssues(result.issues), root);
61
+ }
62
+ export function isStandardSchema(value) {
63
+ if (typeof value !== 'object' || value === null || !('~standard' in value))
64
+ return false;
65
+ const props = value['~standard'];
66
+ return (typeof props === 'object' &&
67
+ props !== null &&
68
+ props.version === 1 &&
69
+ typeof props.validate === 'function');
70
+ }
71
+ //# sourceMappingURL=standard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"standard.js","sourceRoot":"","sources":["standard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,160 @@
1
+ // Single responsibility: the Standard Schema v1 interface plus library-agnostic helpers.
2
+ // This is the swap point: every Ultimate primitive accepts any conforming schema, so ArkType,
3
+ // Zod and Valibot are all first-class without a line of adapter code.
4
+
5
+ import { SchemaUnsupportedError, ValidationFailedError, type ValidationIssue } from './errors';
6
+
7
+ export interface StandardSchemaV1<Input = unknown, Output = Input> {
8
+ readonly '~standard': StandardSchemaProps<Input, Output>;
9
+ }
10
+
11
+ export interface StandardSchemaProps<Input, Output> {
12
+ readonly version: 1;
13
+ /** Library name, e.g. `ultimate`, `arktype`, `zod`. */
14
+ readonly vendor: string;
15
+ readonly validate: (value: unknown) => StandardResult<Output> | Promise<StandardResult<Output>>;
16
+ readonly types?: StandardTypes<Input, Output> | undefined;
17
+ }
18
+
19
+ export interface StandardTypes<Input, Output> {
20
+ readonly input: Input;
21
+ readonly output: Output;
22
+ }
23
+
24
+ export interface StandardSuccessResult<Output> {
25
+ readonly value: Output;
26
+ readonly issues?: undefined;
27
+ }
28
+
29
+ export interface StandardFailureResult {
30
+ readonly issues: readonly StandardIssue[];
31
+ }
32
+
33
+ export type StandardResult<Output> = StandardSuccessResult<Output> | StandardFailureResult;
34
+
35
+ export interface StandardPathSegment {
36
+ readonly key: PropertyKey;
37
+ }
38
+
39
+ export interface StandardIssue {
40
+ readonly message: string;
41
+ readonly path?: readonly (PropertyKey | StandardPathSegment)[] | undefined;
42
+ }
43
+
44
+ export type InferInput<S extends StandardSchemaV1> = NonNullable<S['~standard']['types']>['input'];
45
+
46
+ export type InferOutput<S extends StandardSchemaV1> = NonNullable<
47
+ S['~standard']['types']
48
+ >['output'];
49
+
50
+ /** `['items', 0, 'price']` -> `items[0].price` */
51
+ export function formatPath(
52
+ path: readonly (PropertyKey | StandardPathSegment)[] | undefined,
53
+ ): string {
54
+ if (path === undefined || path.length === 0) return '';
55
+ let out = '';
56
+ for (const segment of path) {
57
+ const key = typeof segment === 'object' ? segment.key : segment;
58
+ if (typeof key === 'number') {
59
+ out += `[${key}]`;
60
+ } else {
61
+ out += out === '' ? String(key) : `.${String(key)}`;
62
+ }
63
+ }
64
+ return out;
65
+ }
66
+
67
+ /**
68
+ * Any issue list this package or its consumers produce, whatever shape the path takes —
69
+ * a `StandardIssue`'s segment array, or an already-flattened dotted string.
70
+ */
71
+ export interface FormattableIssue {
72
+ readonly message: string;
73
+ readonly path?: string | readonly (PropertyKey | StandardPathSegment)[] | undefined;
74
+ }
75
+
76
+ /**
77
+ * The one issue-to-text renderer for the whole framework: `x_validation_failed`,
78
+ * MCP arg errors and action input/output errors all read the same `path: message`
79
+ * line so a human or an agent parses one format everywhere. Callers join or index
80
+ * the array however their surface needs it.
81
+ */
82
+ export function formatIssues(issues: readonly FormattableIssue[]): readonly string[] {
83
+ return issues.map((issue) => {
84
+ const path = typeof issue.path === 'string' ? issue.path : formatPath(issue.path);
85
+ return path === '' ? issue.message : `${path}: ${issue.message}`;
86
+ });
87
+ }
88
+
89
+ /** Normalise any conforming library's issues into Ultimate's path-annotated shape. */
90
+ export function toValidationIssues(issues: readonly StandardIssue[]): readonly ValidationIssue[] {
91
+ return issues.map((issue) => ({
92
+ path: formatPath(issue.path),
93
+ expected: issue.message,
94
+ received: '',
95
+ message: issue.message,
96
+ }));
97
+ }
98
+
99
+ function assertSync<Output>(
100
+ result: StandardResult<Output> | Promise<StandardResult<Output>>,
101
+ vendor: string,
102
+ ): StandardResult<Output> {
103
+ if (result instanceof Promise) {
104
+ throw new SchemaUnsupportedError({
105
+ cause: `${vendor} validated asynchronously in a synchronous call site`,
106
+ fix: 'call validateAsync()/parseAsync() instead of validate()/parse()',
107
+ meta: { vendor },
108
+ });
109
+ }
110
+ return result;
111
+ }
112
+
113
+ /** Validate against ANY conforming schema. Never throws on invalid input. */
114
+ export function validate<S extends StandardSchemaV1>(
115
+ schema: S,
116
+ value: unknown,
117
+ ): StandardResult<InferOutput<S>> {
118
+ const props = schema['~standard'];
119
+ return assertSync(props.validate(value), props.vendor) as StandardResult<InferOutput<S>>;
120
+ }
121
+
122
+ export async function validateAsync<S extends StandardSchemaV1>(
123
+ schema: S,
124
+ value: unknown,
125
+ ): Promise<StandardResult<InferOutput<S>>> {
126
+ const result = await schema['~standard'].validate(value);
127
+ return result as StandardResult<InferOutput<S>>;
128
+ }
129
+
130
+ /** Validate or throw `X_VALIDATION_FAILED` with a path-annotated issue list. */
131
+ export function parse<S extends StandardSchemaV1>(
132
+ schema: S,
133
+ value: unknown,
134
+ root = 'value',
135
+ ): InferOutput<S> {
136
+ const result = validate(schema, value);
137
+ if (result.issues === undefined) return result.value;
138
+ throw new ValidationFailedError(toValidationIssues(result.issues), root);
139
+ }
140
+
141
+ export async function parseAsync<S extends StandardSchemaV1>(
142
+ schema: S,
143
+ value: unknown,
144
+ root = 'value',
145
+ ): Promise<InferOutput<S>> {
146
+ const result = await validateAsync(schema, value);
147
+ if (result.issues === undefined) return result.value;
148
+ throw new ValidationFailedError(toValidationIssues(result.issues), root);
149
+ }
150
+
151
+ export function isStandardSchema(value: unknown): value is StandardSchemaV1 {
152
+ if (typeof value !== 'object' || value === null || !('~standard' in value)) return false;
153
+ const props = (value as { '~standard': unknown })['~standard'];
154
+ return (
155
+ typeof props === 'object' &&
156
+ props !== null &&
157
+ (props as { version?: unknown }).version === 1 &&
158
+ typeof (props as { validate?: unknown }).validate === 'function'
159
+ );
160
+ }
package/src/t.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import type { InferOutput, StandardSchemaV1 } from './standard';
2
+ import type { TNamespace } from './validators';
3
+ export declare const t: TNamespace;
4
+ /** `type PublishInput = Infer<typeof publishInput>` */
5
+ export type Infer<S extends StandardSchemaV1> = InferOutput<S>;
6
+ //# sourceMappingURL=t.d.ts.map
package/src/t.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"t.d.ts","sourceRoot":"","sources":["t.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAc,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,KAAK,EAKV,UAAU,EACX,MAAM,cAAc,CAAC;AAMtB,eAAO,MAAM,CAAC,EAAE,UA8Ef,CAAC;AAEF,uDAAuD;AACvD,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,gBAAgB,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC"}
package/src/t.js ADDED
@@ -0,0 +1,79 @@
1
+ // Single responsibility: the blessed `t` namespace. One import, one way to declare a schema.
2
+ // Every member delegates to the active provider, so `configureSchemaProvider()` takes effect
3
+ // even for modules that captured `t` at import time.
4
+ import { schemaProvider } from './provider';
5
+ function provider() {
6
+ return schemaProvider().t;
7
+ }
8
+ export const t = {
9
+ get string() {
10
+ return provider().string;
11
+ },
12
+ get number() {
13
+ return provider().number;
14
+ },
15
+ get boolean() {
16
+ return provider().boolean;
17
+ },
18
+ get uuid() {
19
+ return provider().uuid;
20
+ },
21
+ get email() {
22
+ return provider().email;
23
+ },
24
+ get url() {
25
+ return provider().url;
26
+ },
27
+ get date() {
28
+ return provider().date;
29
+ },
30
+ get money() {
31
+ return provider().money;
32
+ },
33
+ get timezone() {
34
+ return provider().timezone;
35
+ },
36
+ get locale() {
37
+ return provider().locale;
38
+ },
39
+ get slug() {
40
+ return provider().slug;
41
+ },
42
+ get cursor() {
43
+ return provider().cursor;
44
+ },
45
+ object(shape) {
46
+ return provider().object(shape);
47
+ },
48
+ array(items) {
49
+ return provider().array(items);
50
+ },
51
+ enum(values) {
52
+ return provider().enum(values);
53
+ },
54
+ /**
55
+ * Variadic form of `enum`, and the blessed spelling: it spreads a `const` tuple of codes
56
+ * straight from the domain package (`t.enumerated(...PLAN_CODES)`) and avoids the reserved
57
+ * word at the call site.
58
+ */
59
+ enumerated(...values) {
60
+ return provider().enum(values);
61
+ },
62
+ literal(value) {
63
+ return provider().literal(value);
64
+ },
65
+ union(...members) {
66
+ return provider().union(...members);
67
+ },
68
+ record(values) {
69
+ return provider().record(values);
70
+ },
71
+ /** `t.nullable(t.url)` — the column may hold null, which is not the same as being absent. */
72
+ nullable(schema) {
73
+ return schema.nullable();
74
+ },
75
+ optional(schema) {
76
+ return provider().optional(schema);
77
+ },
78
+ };
79
+ //# sourceMappingURL=t.js.map
package/src/t.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"t.js","sourceRoot":"","sources":["t.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,6FAA6F;AAC7F,qDAAqD;AAGrD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAU5C,SAAS,QAAQ;IACf,OAAO,cAAc,EAAE,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,MAAM,CAAC,GAAe;IAC3B,IAAI,MAAM;QACR,OAAO,QAAQ,EAAE,CAAC,MAAM,CAAC;IAC3B,CAAC;IACD,IAAI,MAAM;QACR,OAAO,QAAQ,EAAE,CAAC,MAAM,CAAC;IAC3B,CAAC;IACD,IAAI,OAAO;QACT,OAAO,QAAQ,EAAE,CAAC,OAAO,CAAC;IAC5B,CAAC;IACD,IAAI,IAAI;QACN,OAAO,QAAQ,EAAE,CAAC,IAAI,CAAC;IACzB,CAAC;IACD,IAAI,KAAK;QACP,OAAO,QAAQ,EAAE,CAAC,KAAK,CAAC;IAC1B,CAAC;IACD,IAAI,GAAG;QACL,OAAO,QAAQ,EAAE,CAAC,GAAG,CAAC;IACxB,CAAC;IACD,IAAI,IAAI;QACN,OAAO,QAAQ,EAAE,CAAC,IAAI,CAAC;IACzB,CAAC;IACD,IAAI,KAAK;QACP,OAAO,QAAQ,EAAE,CAAC,KAAK,CAAC;IAC1B,CAAC;IACD,IAAI,QAAQ;QACV,OAAO,QAAQ,EAAE,CAAC,QAAQ,CAAC;IAC7B,CAAC;IACD,IAAI,MAAM;QACR,OAAO,QAAQ,EAAE,CAAC,MAAM,CAAC;IAC3B,CAAC;IACD,IAAI,IAAI;QACN,OAAO,QAAQ,EAAE,CAAC,IAAI,CAAC;IACzB,CAAC;IACD,IAAI,MAAM;QACR,OAAO,QAAQ,EAAE,CAAC,MAAM,CAAC;IAC3B,CAAC;IACD,MAAM,CAAkB,KAAQ;QAC9B,OAAO,QAAQ,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IACD,KAAK,CAAsB,KAAQ;QACjC,OAAO,QAAQ,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,CAAiD,MAAS;QAC5D,OAAO,QAAQ,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IACD;;;;OAIG;IACH,UAAU,CACR,GAAG,MAAS;QAEZ,OAAO,QAAQ,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,CAA4C,KAAQ;QACzD,OAAO,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IACD,KAAK,CACH,GAAG,OAAU;QAEb,OAAO,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,MAAM,CACJ,MAAS;QAET,OAAO,QAAQ,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IACD,6FAA6F;IAC7F,QAAQ,CAAsB,MAAS;QACrC,OAAO,MAAM,CAAC,QAAQ,EAAyD,CAAC;IAClF,CAAC;IACD,QAAQ,CACN,MAAS;QAET,OAAO,QAAQ,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;CACF,CAAC"}
package/src/t.ts ADDED
@@ -0,0 +1,101 @@
1
+ // Single responsibility: the blessed `t` namespace. One import, one way to declare a schema.
2
+ // Every member delegates to the active provider, so `configureSchemaProvider()` takes effect
3
+ // even for modules that captured `t` at import time.
4
+
5
+ import type { AnySchema, Schema, Shape } from './builder';
6
+ import { schemaProvider } from './provider';
7
+ import type { InferInput, InferOutput, StandardSchemaV1 } from './standard';
8
+ import type {
9
+ MoneyValue,
10
+ NumberSchema,
11
+ ObjectSchema,
12
+ StringSchema,
13
+ TNamespace,
14
+ } from './validators';
15
+
16
+ function provider(): TNamespace {
17
+ return schemaProvider().t;
18
+ }
19
+
20
+ export const t: TNamespace = {
21
+ get string(): StringSchema {
22
+ return provider().string;
23
+ },
24
+ get number(): NumberSchema {
25
+ return provider().number;
26
+ },
27
+ get boolean(): Schema<boolean, boolean> {
28
+ return provider().boolean;
29
+ },
30
+ get uuid(): StringSchema {
31
+ return provider().uuid;
32
+ },
33
+ get email(): StringSchema {
34
+ return provider().email;
35
+ },
36
+ get url(): StringSchema {
37
+ return provider().url;
38
+ },
39
+ get date(): Schema<Date | string | number, Date> {
40
+ return provider().date;
41
+ },
42
+ get money(): Schema<MoneyValue, MoneyValue> {
43
+ return provider().money;
44
+ },
45
+ get timezone(): StringSchema {
46
+ return provider().timezone;
47
+ },
48
+ get locale(): StringSchema {
49
+ return provider().locale;
50
+ },
51
+ get slug(): StringSchema {
52
+ return provider().slug;
53
+ },
54
+ get cursor(): StringSchema {
55
+ return provider().cursor;
56
+ },
57
+ object<S extends Shape>(shape: S): ObjectSchema<S> {
58
+ return provider().object(shape);
59
+ },
60
+ array<S extends AnySchema>(items: S): Schema<readonly InferInput<S>[], InferOutput<S>[]> {
61
+ return provider().array(items);
62
+ },
63
+ enum<const V extends readonly [string, ...string[]]>(values: V): Schema<V[number], V[number]> {
64
+ return provider().enum(values);
65
+ },
66
+ /**
67
+ * Variadic form of `enum`, and the blessed spelling: it spreads a `const` tuple of codes
68
+ * straight from the domain package (`t.enumerated(...PLAN_CODES)`) and avoids the reserved
69
+ * word at the call site.
70
+ */
71
+ enumerated<const V extends readonly [string, ...string[]]>(
72
+ ...values: V
73
+ ): Schema<V[number], V[number]> {
74
+ return provider().enum(values);
75
+ },
76
+ literal<const V extends string | number | boolean>(value: V): Schema<V, V> {
77
+ return provider().literal(value);
78
+ },
79
+ union<S extends readonly [AnySchema, ...AnySchema[]]>(
80
+ ...members: S
81
+ ): Schema<InferInput<S[number]>, InferOutput<S[number]>> {
82
+ return provider().union(...members);
83
+ },
84
+ record<S extends AnySchema>(
85
+ values: S,
86
+ ): Schema<Readonly<Record<string, InferInput<S>>>, Record<string, InferOutput<S>>> {
87
+ return provider().record(values);
88
+ },
89
+ /** `t.nullable(t.url)` — the column may hold null, which is not the same as being absent. */
90
+ nullable<S extends AnySchema>(schema: S): Schema<InferInput<S> | null, InferOutput<S> | null> {
91
+ return schema.nullable() as Schema<InferInput<S> | null, InferOutput<S> | null>;
92
+ },
93
+ optional<S extends AnySchema>(
94
+ schema: S,
95
+ ): Schema<InferInput<S> | undefined, InferOutput<S> | undefined> {
96
+ return provider().optional(schema);
97
+ },
98
+ };
99
+
100
+ /** `type PublishInput = Infer<typeof publishInput>` */
101
+ export type Infer<S extends StandardSchemaV1> = InferOutput<S>;
@@ -0,0 +1,63 @@
1
+ import { type AnySchema, type Schema, type Shape, type ShapeInput, type ShapeOutput } from './builder';
2
+ import type { InferInput, InferOutput } from './standard';
3
+ /** Structurally identical to `Money` in `@ultimat3/money`. Never a float. */
4
+ export interface MoneyValue {
5
+ readonly minor: number;
6
+ readonly currency: string;
7
+ }
8
+ export interface StringSchema extends Schema<string, string> {
9
+ min(length: number): StringSchema;
10
+ max(length: number): StringSchema;
11
+ pattern(regex: RegExp): StringSchema;
12
+ }
13
+ export interface NumberSchema extends Schema<number, number> {
14
+ min(value: number): NumberSchema;
15
+ max(value: number): NumberSchema;
16
+ int(): NumberSchema;
17
+ }
18
+ export interface ObjectSchema<S extends Shape> extends Schema<ShapeInput<S>, ShapeOutput<S>> {
19
+ readonly shape: S;
20
+ extend<E extends Shape>(extra: E): ObjectSchema<Simplified<S & E>>;
21
+ pick<K extends keyof S & string>(...keys: readonly K[]): ObjectSchema<Pick<S, K>>;
22
+ omit<K extends keyof S & string>(...keys: readonly K[]): ObjectSchema<Omit<S, K>>;
23
+ }
24
+ type Simplified<S> = {
25
+ [K in keyof S]: S[K];
26
+ } & {};
27
+ export declare function objectSchema<S extends Shape>(shape: S): ObjectSchema<S>;
28
+ export declare function arraySchema<S extends AnySchema>(items: S): Schema<readonly InferInput<S>[], InferOutput<S>[]>;
29
+ export declare function enumSchema<const V extends readonly [string, ...string[]]>(values: V): Schema<V[number], V[number]>;
30
+ export declare function literalSchema<const V extends string | number | boolean>(value: V): Schema<V, V>;
31
+ export declare function unionSchema<S extends readonly [AnySchema, ...AnySchema[]]>(...members: S): Schema<InferInput<S[number]>, InferOutput<S[number]>>;
32
+ export declare function recordSchema<S extends AnySchema>(values: S): Schema<Readonly<Record<string, InferInput<S>>>, Record<string, InferOutput<S>>>;
33
+ export declare function nullableSchema<S extends AnySchema>(schema: S): Schema<InferInput<S> | null, InferOutput<S> | null>;
34
+ export declare function optionalSchema<S extends AnySchema>(schema: S): Schema<InferInput<S> | undefined, InferOutput<S> | undefined>;
35
+ /** The shape a schema provider must implement to back `t`. */
36
+ export interface TNamespace {
37
+ readonly string: StringSchema;
38
+ readonly number: NumberSchema;
39
+ readonly boolean: Schema<boolean, boolean>;
40
+ readonly uuid: StringSchema;
41
+ readonly email: StringSchema;
42
+ readonly url: StringSchema;
43
+ readonly date: Schema<Date | string | number, Date>;
44
+ readonly money: Schema<MoneyValue, MoneyValue>;
45
+ readonly timezone: StringSchema;
46
+ readonly locale: StringSchema;
47
+ readonly slug: StringSchema;
48
+ readonly cursor: StringSchema;
49
+ object<S extends Shape>(shape: S): ObjectSchema<S>;
50
+ array<S extends AnySchema>(items: S): Schema<readonly InferInput<S>[], InferOutput<S>[]>;
51
+ enum<const V extends readonly [string, ...string[]]>(values: V): Schema<V[number], V[number]>;
52
+ /** Variadic `enum`; the blessed spelling at call sites. */
53
+ enumerated<const V extends readonly [string, ...string[]]>(...values: V): Schema<V[number], V[number]>;
54
+ literal<const V extends string | number | boolean>(value: V): Schema<V, V>;
55
+ union<S extends readonly [AnySchema, ...AnySchema[]]>(...members: S): Schema<InferInput<S[number]>, InferOutput<S[number]>>;
56
+ record<S extends AnySchema>(values: S): Schema<Readonly<Record<string, InferInput<S>>>, Record<string, InferOutput<S>>>;
57
+ /** Null is a value the column holds; `optional` is the caller omitting the field. */
58
+ nullable<S extends AnySchema>(schema: S): Schema<InferInput<S> | null, InferOutput<S> | null>;
59
+ optional<S extends AnySchema>(schema: S): Schema<InferInput<S> | undefined, InferOutput<S> | undefined>;
60
+ }
61
+ export declare const builtinT: TNamespace;
62
+ export {};
63
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["validators.ts"],"names":[],"mappings":"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"}