@uniflowed/validator 0.0.0-alpha.4 → 0.0.0-alpha.6

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.
package/namespace.js ADDED
@@ -0,0 +1,229 @@
1
+ // @flow
2
+ //
3
+ // `@uniflowed/validator/namespace`: every builder under one name.
4
+ //
5
+ // import { v } from "@uniflowed/validator";
6
+ // const Account = v.object({ email: v.pipe(v.string(), v.email()) });
7
+ //
8
+ // The named exports are the primary surface. This is the convenience alias,
9
+ // for the many schemas that mention a dozen builders and would otherwise open
10
+ // with a dozen-line import, and for readers coming from Valibot who already
11
+ // write `v.` in front of everything.
12
+ //
13
+ // # Why it is a module of its own
14
+ //
15
+ // Because it is the one module that has to import all of them, and a package
16
+ // whose entry point did that would make every application carry every check.
17
+ // Here it is reached through a single named re-export from `index.js`, which a
18
+ // bundler drops when nothing reads `v`; a project that imports
19
+ // `@uniflowed/validator/primitive` directly never resolves this file at all.
20
+ //
21
+ // # Why it is typed with `typeof`
22
+ //
23
+ // So the two surfaces cannot drift. Each field's type is the exported
24
+ // function's own, which means adding a builder and forgetting to list it here
25
+ // is a missing property rather than a silently different signature, and
26
+ // renaming one is an error at this file rather than a surprise at a call site.
27
+
28
+ import {
29
+ email,
30
+ endsWith,
31
+ includes,
32
+ integer,
33
+ isoDate,
34
+ length,
35
+ max,
36
+ maxItems,
37
+ maxLength,
38
+ min,
39
+ minItems,
40
+ minLength,
41
+ multipleOf,
42
+ nonEmpty,
43
+ regex,
44
+ startsWith,
45
+ toLowerCase,
46
+ toUpperCase,
47
+ trim,
48
+ url,
49
+ uuid,
50
+ } from "./action.js";
51
+ import { array, map, record, set, tuple } from "./collection.js";
52
+ import { flatten } from "./issue.js";
53
+ import { toJsonSchema } from "./json-schema.js";
54
+ import { lazy, lazyAsync } from "./lazy.js";
55
+ import { looseObject, object, partial, strictObject } from "./object.js";
56
+ import { fallback, nullable, nullish, optional, withDefault } from "./optional.js";
57
+ import {
58
+ is,
59
+ parse,
60
+ parseAsync,
61
+ parser,
62
+ safeParse,
63
+ safeParseAsync,
64
+ useValidation,
65
+ } from "./parse.js";
66
+ import { brand, check, checkAsync, pipe, refine, transform, transformAsync } from "./pipe.js";
67
+ import {
68
+ bigint,
69
+ boolean,
70
+ custom,
71
+ date,
72
+ enum_,
73
+ instance,
74
+ literal,
75
+ never,
76
+ null_,
77
+ number,
78
+ string,
79
+ undefined_,
80
+ unknown,
81
+ } from "./primitive.js";
82
+ import { describe, isAsync } from "./schema.js";
83
+ import { intersect, union, variant } from "./union.js";
84
+
85
+ export const v: {
86
+ readonly string: typeof string,
87
+ readonly number: typeof number,
88
+ readonly bigint: typeof bigint,
89
+ readonly boolean: typeof boolean,
90
+ readonly unknown: typeof unknown,
91
+ readonly never: typeof never,
92
+ readonly null: typeof null_,
93
+ readonly undefined: typeof undefined_,
94
+ readonly literal: typeof literal,
95
+ readonly enum: typeof enum_,
96
+ readonly date: typeof date,
97
+ readonly instance: typeof instance,
98
+ readonly custom: typeof custom,
99
+ readonly object: typeof object,
100
+ readonly strictObject: typeof strictObject,
101
+ readonly looseObject: typeof looseObject,
102
+ readonly partial: typeof partial,
103
+ readonly array: typeof array,
104
+ readonly tuple: typeof tuple,
105
+ readonly record: typeof record,
106
+ readonly map: typeof map,
107
+ readonly set: typeof set,
108
+ readonly union: typeof union,
109
+ readonly variant: typeof variant,
110
+ readonly intersect: typeof intersect,
111
+ readonly optional: typeof optional,
112
+ readonly nullable: typeof nullable,
113
+ readonly nullish: typeof nullish,
114
+ readonly withDefault: typeof withDefault,
115
+ readonly fallback: typeof fallback,
116
+ readonly lazy: typeof lazy,
117
+ readonly lazyAsync: typeof lazyAsync,
118
+ readonly pipe: typeof pipe,
119
+ readonly check: typeof check,
120
+ readonly checkAsync: typeof checkAsync,
121
+ readonly transform: typeof transform,
122
+ readonly transformAsync: typeof transformAsync,
123
+ readonly brand: typeof brand,
124
+ readonly refine: typeof refine,
125
+ readonly minLength: typeof minLength,
126
+ readonly maxLength: typeof maxLength,
127
+ readonly length: typeof length,
128
+ readonly nonEmpty: typeof nonEmpty,
129
+ readonly startsWith: typeof startsWith,
130
+ readonly endsWith: typeof endsWith,
131
+ readonly includes: typeof includes,
132
+ readonly regex: typeof regex,
133
+ readonly email: typeof email,
134
+ readonly url: typeof url,
135
+ readonly uuid: typeof uuid,
136
+ readonly isoDate: typeof isoDate,
137
+ readonly trim: typeof trim,
138
+ readonly toLowerCase: typeof toLowerCase,
139
+ readonly toUpperCase: typeof toUpperCase,
140
+ readonly min: typeof min,
141
+ readonly max: typeof max,
142
+ readonly integer: typeof integer,
143
+ readonly multipleOf: typeof multipleOf,
144
+ readonly minItems: typeof minItems,
145
+ readonly maxItems: typeof maxItems,
146
+ readonly parse: typeof parse,
147
+ readonly safeParse: typeof safeParse,
148
+ readonly parseAsync: typeof parseAsync,
149
+ readonly safeParseAsync: typeof safeParseAsync,
150
+ readonly is: typeof is,
151
+ readonly parser: typeof parser,
152
+ readonly useValidation: typeof useValidation,
153
+ readonly describe: typeof describe,
154
+ readonly isAsync: typeof isAsync,
155
+ readonly flatten: typeof flatten,
156
+ readonly toJsonSchema: typeof toJsonSchema,
157
+ } = {
158
+ string,
159
+ number,
160
+ bigint,
161
+ boolean,
162
+ unknown,
163
+ never,
164
+ null: null_,
165
+ undefined: undefined_,
166
+ literal,
167
+ enum: enum_,
168
+ date,
169
+ instance,
170
+ custom,
171
+ object,
172
+ strictObject,
173
+ looseObject,
174
+ partial,
175
+ array,
176
+ tuple,
177
+ record,
178
+ map,
179
+ set,
180
+ union,
181
+ variant,
182
+ intersect,
183
+ optional,
184
+ nullable,
185
+ nullish,
186
+ withDefault,
187
+ fallback,
188
+ lazy,
189
+ lazyAsync,
190
+ pipe,
191
+ check,
192
+ checkAsync,
193
+ transform,
194
+ transformAsync,
195
+ brand,
196
+ refine,
197
+ minLength,
198
+ maxLength,
199
+ length,
200
+ nonEmpty,
201
+ startsWith,
202
+ endsWith,
203
+ includes,
204
+ regex,
205
+ email,
206
+ url,
207
+ uuid,
208
+ isoDate,
209
+ trim,
210
+ toLowerCase,
211
+ toUpperCase,
212
+ min,
213
+ max,
214
+ integer,
215
+ multipleOf,
216
+ minItems,
217
+ maxItems,
218
+ parse,
219
+ safeParse,
220
+ parseAsync,
221
+ safeParseAsync,
222
+ is,
223
+ parser,
224
+ useValidation,
225
+ describe,
226
+ isAsync,
227
+ flatten,
228
+ toJsonSchema,
229
+ };
package/object.js ADDED
@@ -0,0 +1,241 @@
1
+ // @flow
2
+ //
3
+ // `@uniflowed/validator/object`: an object whose keys are known when the
4
+ // schema is written.
5
+ //
6
+ // Three of them, and the only difference is what happens to a key the shape
7
+ // does not name:
8
+ //
9
+ // - [`object`] drops it. The right default for reading somebody else's
10
+ // payload, where a new field appearing upstream is not your emergency.
11
+ // - [`strictObject`] rejects it. The right answer for a configuration file or
12
+ // an internal API, where an unrecognised key is almost always a typo the
13
+ // user would rather hear about than have ignored.
14
+ // - [`looseObject`] keeps it. For a boundary that has to forward what it did
15
+ // not understand — a webhook that is re-signed, a document that round-trips
16
+ // through a form and must come back whole.
17
+ //
18
+ // One walk serves all three, because "which keys does the shape name" is the
19
+ // same question in each and only the fourth line of the answer differs.
20
+ //
21
+ // # Why these take a shape and not a schema
22
+ //
23
+ // `partial({ name: string(), age: number() })`, not `partial(User)`. A schema
24
+ // here is a closure and a description, not a reified list of fields, so there
25
+ // is nothing on a built schema for `partial` to take apart — and adding one
26
+ // would mean every object schema carried its shape for the benefit of the
27
+ // callers that reshape it. Naming the shape once and passing it to both is the
28
+ // same amount of typing and keeps the built schema the size of its job:
29
+ //
30
+ // const account = { name: string(), age: number() };
31
+ // const Account = object(account);
32
+ // const Draft = partial(account);
33
+ //
34
+ // Valibot's `pick`, `omit` and `required` are absent for the same reason, and
35
+ // because over a shape they are object literal manipulation the language
36
+ // already has: `object({ name: account.name })` is `pick`.
37
+ //
38
+ // # Reading and writing
39
+ //
40
+ // Every read of an untrusted key goes through `plain-object.js`, and so does
41
+ // every write. `object.js` never touches `source[key]` or `out[key] = …`
42
+ // directly, and the reason is written down there.
43
+
44
+ import type { Shape, ShapeInput, ShapeOutput } from "./infer.js";
45
+ import type { Issue, PathBuffer } from "./issue.js";
46
+ import { issue } from "./issue.js";
47
+ import { isPlainObject, ownKeys, ownValue, plainRecord, put } from "./plain-object.js";
48
+ import type { Description, Result, Schema } from "./schema.js";
49
+ import {
50
+ collectAsync,
51
+ describe,
52
+ fail,
53
+ isAsync,
54
+ makeAsyncSchema,
55
+ makeSchema,
56
+ mergeIssues,
57
+ ok,
58
+ runAt,
59
+ } from "./schema.js";
60
+ import { optional } from "./optional.js";
61
+
62
+ /** What an object schema does with a key its shape does not name. */
63
+ type UnknownKeys = "strip" | "reject" | "keep";
64
+
65
+ /**
66
+ * Pairs of `[key, schema]`, resolved once when the schema is built.
67
+ *
68
+ * `Object.keys(shape)` on every parse re-reads the same descriptors for the
69
+ * life of the process. The shape cannot change after construction, so the walk
70
+ * belongs at construction.
71
+ */
72
+ function shapeEntries(shape: Shape): $ReadOnlyArray<[string, Schema<mixed, mixed>]> {
73
+ return Object.keys(shape).map((key) => [key, shape[key]]);
74
+ }
75
+
76
+ /** Issues for every own key the shape does not name. Empty unless rejecting. */
77
+ function unknownKeyIssues(
78
+ source: { readonly [string]: mixed, ... },
79
+ named: Set<string>,
80
+ path: PathBuffer,
81
+ ): Array<Issue> {
82
+ const issues: Array<Issue> = [];
83
+ for (const key of ownKeys(source)) {
84
+ if (!named.has(key)) {
85
+ path.push(key);
86
+ issues.push(issue("unknown_key", `unexpected key ${key}`, path));
87
+ path.pop();
88
+ }
89
+ }
90
+ return issues;
91
+ }
92
+
93
+ /** Copy every own key the shape does not name into the output, unchecked. */
94
+ function keepUnknownKeys(
95
+ source: { readonly [string]: mixed, ... },
96
+ named: Set<string>,
97
+ out: { [string]: mixed, ... },
98
+ ): void {
99
+ for (const key of ownKeys(source)) {
100
+ if (!named.has(key)) {
101
+ put(out, key, ownValue(source, key));
102
+ }
103
+ }
104
+ }
105
+
106
+ /**
107
+ * The one object parser.
108
+ *
109
+ * `TOutput` and `TInput` are supplied by the three exported spellings; nothing
110
+ * at run time depends on them, which is why one implementation can serve an
111
+ * exact result, a `Partial` one and an inexact one alike.
112
+ */
113
+ function buildObject<TOutput, TInput>(
114
+ shape: Shape,
115
+ unknownKeys: UnknownKeys,
116
+ ): Schema<TOutput, TInput> {
117
+ const entries = shapeEntries(shape);
118
+ const named = new Set(entries.map(([key]) => key));
119
+ const description = (): Description => ({
120
+ kind: "object",
121
+ entries: entries.map(([key, schema]) => [key, describe(schema)]),
122
+ unknownKeys,
123
+ });
124
+
125
+ function assemble(
126
+ source: { readonly [string]: mixed, ... },
127
+ out: { [string]: mixed, ... },
128
+ found: Array<Issue>,
129
+ path: PathBuffer,
130
+ ): Result<TOutput> {
131
+ const issues =
132
+ unknownKeys === "reject" ? found.concat(unknownKeyIssues(source, named, path)) : found;
133
+ if (issues.length > 0) {
134
+ return { ok: false, issues };
135
+ }
136
+ if (unknownKeys === "keep") {
137
+ keepUnknownKeys(source, named, out);
138
+ }
139
+ // $FlowFixMe[incompatible-type] every retained key was produced by the shape.
140
+ return ok(out as TOutput);
141
+ }
142
+
143
+ if (entries.some(([, schema]) => isAsync(schema))) {
144
+ return makeAsyncSchema(async (value, path) => {
145
+ if (!isPlainObject(value)) {
146
+ return fail("type", "expected object", path);
147
+ }
148
+ const source = plainRecord(value);
149
+ const collected = await collectAsync(
150
+ entries.map(([key, schema]) => ({ keys: [key], schema, value: ownValue(source, key) })),
151
+ path,
152
+ );
153
+ const out: { [string]: mixed, ... } = {};
154
+ const found: Array<Issue> = [];
155
+ match (collected) {
156
+ {ok: true, values: const values} => {
157
+ entries.forEach(([key], index) => {
158
+ put(out, key, values[index]);
159
+ });
160
+ }
161
+ {ok: false, issues: const collectedIssues} => {
162
+ for (const entry of collectedIssues) {
163
+ found.push(entry);
164
+ }
165
+ }
166
+ }
167
+ return assemble(source, out, found, path);
168
+ }, description);
169
+ }
170
+
171
+ return makeSchema((value, path) => {
172
+ if (!isPlainObject(value)) {
173
+ return fail("type", "expected object", path);
174
+ }
175
+ const source = plainRecord(value);
176
+ const out: { [string]: mixed, ... } = {};
177
+ const found: Array<Issue> = [];
178
+ for (const [key, schema] of entries) {
179
+ const result = runAt(schema, ownValue(source, key), path, key);
180
+ if (result.ok) {
181
+ put(out, key, result.value);
182
+ } else {
183
+ mergeIssues(found, result);
184
+ }
185
+ }
186
+ return assemble(source, out, found, path);
187
+ }, description);
188
+ }
189
+
190
+ /** An object with exactly the shape's keys; anything else is dropped. */
191
+ export function object<TShape extends Shape>(
192
+ shape: TShape,
193
+ ): Schema<ShapeOutput<TShape>, ShapeInput<TShape>> {
194
+ return buildObject(shape, "strip");
195
+ }
196
+
197
+ /**
198
+ * An object that rejects keys the shape does not name.
199
+ *
200
+ * The unknown-key scan runs whether or not the fields parsed. Returning early
201
+ * on a field failure meant `{ name: 1, extra: true }` reported the wrong type
202
+ * of `name` and said nothing about `extra`, so fixing the first error revealed
203
+ * the second — which is the whole reason this validator collects issues
204
+ * instead of stopping at one.
205
+ */
206
+ export function strictObject<TShape extends Shape>(
207
+ shape: TShape,
208
+ ): Schema<ShapeOutput<TShape>, ShapeInput<TShape>> {
209
+ return buildObject(shape, "reject");
210
+ }
211
+
212
+ /**
213
+ * An object that keeps the keys the shape does not name.
214
+ *
215
+ * The extra keys are in the parsed value and not in its type: they are
216
+ * `mixed`, because nothing validated them. The result type is inexact, which
217
+ * is Flow saying exactly that.
218
+ */
219
+ export function looseObject<TShape extends Shape>(
220
+ shape: TShape,
221
+ ): Schema<{ ...ShapeOutput<TShape>, ... }, { ...ShapeInput<TShape>, ... }> {
222
+ return buildObject(shape, "keep");
223
+ }
224
+
225
+ /**
226
+ * Every field of `shape`, each allowed to be missing.
227
+ *
228
+ * A key that was absent is present in the result holding `undefined`, rather
229
+ * than absent from it. One shape for the parsed value means a consumer reads
230
+ * `draft.name` without asking whether the key exists, and `Partial` says the
231
+ * same thing to the checker.
232
+ */
233
+ export function partial<TShape extends Shape>(
234
+ shape: TShape,
235
+ ): Schema<Partial<ShapeOutput<TShape>>, Partial<ShapeInput<TShape>>> {
236
+ const partialShape: { [string]: Schema<mixed, mixed>, ... } = {};
237
+ for (const key of Object.keys(shape)) {
238
+ put(partialShape, key, optional(shape[key]));
239
+ }
240
+ return buildObject(partialShape, "strip");
241
+ }
package/optional.js ADDED
@@ -0,0 +1,132 @@
1
+ // @flow
2
+ //
3
+ // `@uniflowed/validator/optional`: a value that might not be there.
4
+ //
5
+ // Four wrappers and one rule each, and they are together because the question
6
+ // they answer is one question — what counts as "not there", and what should
7
+ // the parse produce when it happens.
8
+ //
9
+ // optional(string()) // undefined is fine, and stays undefined
10
+ // nullable(string()) // null is fine, and stays null
11
+ // nullish(string()) // either is fine
12
+ // withDefault(string(), "") // undefined becomes ""
13
+ // fallback(number(), 8080) // *anything* that fails becomes 8080
14
+ //
15
+ // `undefined` and `null` are kept apart on purpose. A missing key and a key
16
+ // explicitly set to null mean different things in every wire format uf reads —
17
+ // a PATCH body, a GraphQL response, a form that cleared a field — and a
18
+ // validator that folded them together would hand the application a value it
19
+ // could no longer tell apart. `nullish` is there for the boundary that really
20
+ // does not care.
21
+ //
22
+ // # Where the input type stops matching the output type
23
+ //
24
+ // [`withDefault`] and [`fallback`] are the two schemas whose `InferInput` is
25
+ // genuinely wider than their `InferOutput`: a default's input may be missing
26
+ // and its output never is, and a fallback accepts literally anything. That is
27
+ // not a quirk of the typing, it is what those two are for, and it is the case
28
+ // `InferInput` exists to describe.
29
+
30
+ import type { Description, Result, Schema } from "./schema.js";
31
+ import { describe, isAsync, makeAsyncSchema, makeSchema, ok, run, runAsync } from "./schema.js";
32
+
33
+ /**
34
+ * Build a wrapper that answers for some inputs itself and delegates the rest.
35
+ *
36
+ * `shortcut` returns a result to use as-is, or null to mean "ask the inner
37
+ * schema". Every wrapper in this module is that shape, and writing it once is
38
+ * also what keeps the asynchronous variants from being four more copies of the
39
+ * same three lines.
40
+ */
41
+ function wrap<TOutput, TInput>(
42
+ inner: Schema<TOutput, mixed>,
43
+ shortcut: (value: mixed) => null | Result<TOutput>,
44
+ description: () => Description,
45
+ ): Schema<TOutput, TInput> {
46
+ if (isAsync(inner)) {
47
+ return makeAsyncSchema((value, path) => {
48
+ const answered = shortcut(value);
49
+ return answered == null ? runAsync(inner, value, path) : Promise.resolve(answered);
50
+ }, description);
51
+ }
52
+ return makeSchema((value, path) => {
53
+ const answered = shortcut(value);
54
+ return answered == null ? run(inner, value, path) : answered;
55
+ }, description);
56
+ }
57
+
58
+ /** `undefined` passes through; anything else goes to `schema`. */
59
+ export function optional<TOutput, TInput>(
60
+ schema: Schema<TOutput, TInput>,
61
+ ): Schema<void | TOutput, void | TInput> {
62
+ return wrap(
63
+ schema,
64
+ (value) => (value === undefined ? ok(undefined) : null),
65
+ () => ({ kind: "optional", inner: describe(schema) }),
66
+ );
67
+ }
68
+
69
+ /** `null` passes through; anything else goes to `schema`. */
70
+ export function nullable<TOutput, TInput>(
71
+ schema: Schema<TOutput, TInput>,
72
+ ): Schema<null | TOutput, null | TInput> {
73
+ return wrap(
74
+ schema,
75
+ (value) => (value === null ? ok(null) : null),
76
+ () => ({ kind: "nullable", inner: describe(schema) }),
77
+ );
78
+ }
79
+
80
+ /** Either `null` or `undefined` passes through, unchanged. */
81
+ export function nullish<TOutput, TInput>(
82
+ schema: Schema<TOutput, TInput>,
83
+ ): Schema<null | void | TOutput, null | void | TInput> {
84
+ return wrap(
85
+ schema,
86
+ (value) => (value == null ? ok(value === null ? null : undefined) : null),
87
+ () => ({ kind: "nullish", inner: describe(schema) }),
88
+ );
89
+ }
90
+
91
+ /**
92
+ * `undefined` becomes `value`; anything else goes to `schema`.
93
+ *
94
+ * The default is not validated. It is a value the program wrote, in the
95
+ * program's own types, and running it back through the parser would only be a
96
+ * chance for the two to disagree.
97
+ */
98
+ export function withDefault<TOutput, TInput>(
99
+ schema: Schema<TOutput, TInput>,
100
+ value: TOutput,
101
+ ): Schema<TOutput, void | TInput> {
102
+ return wrap(
103
+ schema,
104
+ (input) => (input === undefined ? ok(value) : null),
105
+ () => ({ kind: "default", inner: describe(schema) }),
106
+ );
107
+ }
108
+
109
+ /**
110
+ * A schema that never fails, substituting `value` when the inner one does.
111
+ *
112
+ * For the boundary where a bad field should not sink the whole payload — a
113
+ * cached response, a user preference — and where the alternative is a
114
+ * `safeParse` and a hand-written `if` at every call site. Its input type is
115
+ * `mixed`, because that is the truth: it accepts everything.
116
+ */
117
+ export function fallback<TOutput>(
118
+ schema: Schema<TOutput, mixed>,
119
+ value: TOutput,
120
+ ): Schema<TOutput, mixed> {
121
+ const description = (): Description => ({ kind: "fallback", inner: describe(schema) });
122
+ if (isAsync(schema)) {
123
+ return makeAsyncSchema(async (input, path) => {
124
+ const result = await runAsync(schema, input, path);
125
+ return result.ok ? result : ok(value);
126
+ }, description);
127
+ }
128
+ return makeSchema((input, path) => {
129
+ const result = run(schema, input, path);
130
+ return result.ok ? result : ok(value);
131
+ }, description);
132
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@uniflowed/validator",
3
- "version": "0.0.0-alpha.4",
4
- "description": "Flow implementation for @uniflowed/validator, part of the Unified Toolchain for Flow.",
3
+ "version": "0.0.0-alpha.6",
4
+ "description": "Schemas that parse rather than assert: typed inference, issue paths and JSON Schema export, part of the Unified Toolchain for Flow.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "sideEffects": false,
@@ -11,9 +11,24 @@
11
11
  "directory": "packages/validator"
12
12
  },
13
13
  "exports": {
14
- ".": "./index.js"
14
+ ".": "./index.js",
15
+ "./action": "./action.js",
16
+ "./collection": "./collection.js",
17
+ "./infer": "./infer.js",
18
+ "./issue": "./issue.js",
19
+ "./json-schema": "./json-schema.js",
20
+ "./lazy": "./lazy.js",
21
+ "./namespace": "./namespace.js",
22
+ "./object": "./object.js",
23
+ "./optional": "./optional.js",
24
+ "./parse": "./parse.js",
25
+ "./pipe": "./pipe.js",
26
+ "./plain-object": "./plain-object.js",
27
+ "./primitive": "./primitive.js",
28
+ "./schema": "./schema.js",
29
+ "./union": "./union.js"
15
30
  },
16
31
  "files": [
17
- "index.js"
32
+ "*.js"
18
33
  ]
19
34
  }