valleyed 4.5.3 → 4.5.5

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/CHANGELOG.md CHANGED
@@ -2,6 +2,28 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [4.5.5](https://github.com/kevinand11/valleyed/compare/v4.5.4...v4.5.5) (2025-06-24)
6
+
7
+
8
+ ### Features
9
+
10
+ * update docs ([6339332](https://github.com/kevinand11/valleyed/commit/63393320051354ae111e1f6692a68c66cbe75894))
11
+
12
+ ### [4.5.4](https://github.com/kevinand11/valleyed/compare/v4.5.3...v4.5.4) (2025-06-24)
13
+
14
+
15
+ ### Features
16
+
17
+ * add pipe deps into context ([88f5463](https://github.com/kevinand11/valleyed/commit/88f5463a80b9f6bb94bceaa6d3533f9a17d9ec9b))
18
+ * meta api ([9e260e5](https://github.com/kevinand11/valleyed/commit/9e260e52966b198d1393b9202ff5ac9f9a539995))
19
+ * store both next and last for performance ([87ebb6b](https://github.com/kevinand11/valleyed/commit/87ebb6b1e103865c249e727964d596448e84d2f3))
20
+ * use new apis assert, validate, context and schema ([2bd63ce](https://github.com/kevinand11/valleyed/commit/2bd63ce0d7aa3e62483299634e99790bc63ab9bc))
21
+
22
+
23
+ ### Bug Fixes
24
+
25
+ * use linked list instead of reversed ([7e3fc25](https://github.com/kevinand11/valleyed/commit/7e3fc25afc0fd6facfe151265756a735a6dc78ac))
26
+
5
27
  ### [4.5.3](https://github.com/kevinand11/valleyed/compare/v4.5.2...v4.5.3) (2025-06-24)
6
28
 
7
29
  ### [4.5.2](https://github.com/kevinand11/valleyed/compare/v4.5.1...v4.5.2) (2025-06-24)
package/README.md CHANGED
@@ -1,15 +1,17 @@
1
1
  # Valleyed
2
2
 
3
- Valleyed is a powerful, type-safe, and lightweight validation library for TypeScript and JavaScript. It provides a fluent, chainable API to build complex validation pipelines with ease, inspired by libraries like Zod, but with a focus on simplicity and extensibility.
3
+ Valleyed is a powerful, type-safe, and lightweight validation library for TypeScript and JavaScript. It provides a fluent, chainable API to build complex validation pipelines with ease, inspired by libraries like superstruct, zod, etc but with a focus on simplicity, extensibility, and a functional approach.
4
4
 
5
5
  ## ✨ Features
6
6
 
7
- - **Type-Safe**: Full TypeScript support, infer types directly from your schemas.
7
+ - **Type-Safe**: Full TypeScript support with first-class type inference. Infer types directly from your schemas.
8
8
  - **Lightweight**: Small bundle size with zero dependencies.
9
- - **Chainable API**: Build complex validations by chaining methods.
10
- - **Extensible**: Easily add your own custom validation logic.
11
- - **Standard Schema Compatible**: Generate JSON Schemas from your validation pipes.
9
+ - **Functional & Chainable API**: Build complex validation pipelines by creating and composing pipes.
10
+ - **Extensible**: Easily add your own custom validation logic by creating new pipes.
11
+ - **JSON Schema Generation**: Automatically generate JSON Schemas from your validation pipes.
12
+ - **Standard Schema Compatible**: Implements the [Standard Schema v1](https://github.com/standard-schema/standard-schema) specification for interoperability.
12
13
  - **Isomorphic**: Works in both Node.js and browser environments.
14
+ - **Utilities**: Includes a set of useful utilities for data manipulation, like a deep diffing utility and geohash functions.
13
15
 
14
16
  ## 📦 Installation
15
17
 
@@ -30,7 +32,7 @@ Here's a quick example to get you started with Valleyed:
30
32
  ```typescript
31
33
  import { v } from 'valleyed';
32
34
 
33
- // 1. Define a schema for your data
35
+ // 1. Define a schema (a "pipe") for your data
34
36
  const userSchema = v.object({
35
37
  name: v.string().pipe(v.min(3)),
36
38
  email: v.string().pipe(v.email()),
@@ -43,8 +45,8 @@ const userData = {
43
45
  email: 'john.doe@example.com',
44
46
  };
45
47
 
46
- // 3. Validate the data
47
- const validationResult = userSchema.validate(userData);
48
+ // 3. Validate the data using v.validate()
49
+ const validationResult = v.validate(userSchema, userData);
48
50
 
49
51
  if (validationResult.valid) {
50
52
  // Type-safe access to the validated data
@@ -54,15 +56,62 @@ if (validationResult.valid) {
54
56
  console.error('Validation failed:', validationResult.error.toString());
55
57
  }
56
58
 
57
- // 4. You can also parse directly, which throws on error
59
+ // 4. You can also parse directly with v.assert(), which throws on error
58
60
  try {
59
- const user = userSchema.parse(userData);
61
+ const user = v.assert(userSchema, userData);
60
62
  console.log('Parsed user:', user);
61
63
  } catch (error) {
62
64
  console.error(error);
63
65
  }
64
66
  ```
65
67
 
68
+ ## 📚 Core Concepts
69
+
70
+ ### Pipes
71
+
72
+ The fundamental building block in Valleyed is the **pipe**. A pipe is a function that takes an input, validates or transforms it, and returns the output. Pipes can be chained together to create a validation pipeline.
73
+
74
+ You can create a base pipe (like `v.string()`) and then chain more validation rules or transformations using the `.pipe()` method.
75
+
76
+ ```typescript
77
+ const usernamePipe = v.string()
78
+ .pipe(v.asTrimmed()) // Transformer: trims whitespace
79
+ .pipe(v.min(3)) // Validator: minimum 3 characters
80
+ .pipe(v.asLowercased()); // Transformer: converts to lowercase
81
+ ```
82
+
83
+ ### Execution Functions
84
+
85
+ Once you have a pipe, you use one of the top-level execution functions to run it:
86
+
87
+ - `v.assert(pipe, input)`: Parses the input using the pipe. If validation is successful, it returns the (potentially transformed) output. If it fails, it throws a `PipeError`.
88
+ - `v.validate(pipe, input)`: Safely validates the input. It returns an object: `{ valid: true, value: ... }` on success, or `{ valid: false, error: ... }` on failure. It never throws.
89
+ - `v.schema(pipe)`: Generates a JSON Schema from the validation pipe.
90
+ - `v.meta(pipe, metadata)`: Attaches metadata (like `title`, `description`, `examples`) to a pipe, which will be included in the generated JSON Schema.
91
+
92
+ ```typescript
93
+ const username = v.assert(usernamePipe, ' JohnDoe '); // 'johndoe'
94
+
95
+ const result = v.validate(usernamePipe, 'JD');
96
+ if (!result.valid) {
97
+ console.log(result.error.messages);
98
+ // [{ message: 'must contain 3 or more characters', path: '' }]
99
+ }
100
+ ```
101
+
102
+ ### Type Inference
103
+
104
+ Valleyed automatically infers TypeScript types from your schemas. You can use `v.PipeInput<T>` and `v.PipeOutput<T>` to extract the input and output types of a pipe.
105
+
106
+ ```typescript
107
+ import { v, PipeInput, PipeOutput } from 'valleyed';
108
+
109
+ const userSchema = v.object({ /* ... */ });
110
+
111
+ type UserInput = PipeInput<typeof userSchema>; // The type of the data before validation
112
+ type UserOutput = PipeOutput<typeof userSchema>; // The type of the data after validation
113
+ ```
114
+
66
115
  ## 📚 API Reference
67
116
 
68
117
  Valleyed exports a single object `v` which contains all the validation functions.
@@ -79,13 +128,13 @@ These are the basic building blocks for any schema.
79
128
  | `v.null()` | Checks if the input is `null`. |
80
129
  | `v.undefined()` | Checks if the input is `undefined`. |
81
130
  | `v.any()` | Allows any value, essentially a pass-through. |
82
- | `v.instanceOf()` | Checks if the input is an instance of a given class. |
131
+ | `v.instanceOf(class)` | Checks if the input is an instance of a given class. |
83
132
 
84
133
  ```typescript
85
134
  // Example:
86
- v.string().validate('hello').valid; // true
87
- v.number().validate(123).valid; // true
88
- v.instanceOf(Date).validate(new Date()).valid; // true
135
+ v.validate(v.string(), 'hello').valid; // true
136
+ v.validate(v.number(), 123).valid; // true
137
+ v.validate(v.instanceOf(Date), new Date()).valid; // true
89
138
  ```
90
139
 
91
140
  ### Core Validators
@@ -106,9 +155,9 @@ These validators can be piped from any other validator to add more constraints.
106
155
  ```typescript
107
156
  // Example:
108
157
  const schema = v.string().pipe(v.min(5), v.in(['hello', 'world']));
109
- schema.validate('hello').valid; // true
110
- schema.validate('hi').valid; // false (fails min(5))
111
- schema.validate('testing').valid; // false (fails in([...]))
158
+ v.validate(schema, 'hello').valid; // true
159
+ v.validate(schema, 'hi').valid; // false (fails min(5))
160
+ v.validate(schema, 'testing').valid; // false (fails in([...]))
112
161
  ```
113
162
 
114
163
  ### String Validators
@@ -129,10 +178,10 @@ Specific validators and transformers for strings.
129
178
 
130
179
  ```typescript
131
180
  // Example:
132
- v.string().pipe(v.email()).validate('test@example.com').valid; // true
181
+ v.validate(v.string().pipe(v.email()), 'test@example.com').valid; // true
133
182
 
134
183
  const trimmedLower = v.string().pipe(v.asTrimmed(), v.asLowercased());
135
- trimmedLower.parse(' HeLLo '); // 'hello'
184
+ v.assert(trimmedLower, ' HeLLo '); // 'hello'
136
185
  ```
137
186
 
138
187
  ### Number Validators
@@ -151,8 +200,8 @@ Specific validators and transformers for numbers.
151
200
  ```typescript
152
201
  // Example:
153
202
  const ageSchema = v.number().pipe(v.int(), v.gte(18));
154
- ageSchema.validate(25).valid; // true
155
- ageSchema.validate(17.5).valid; // false
203
+ v.validate(ageSchema, 25).valid; // true
204
+ v.validate(ageSchema, 17.5).valid; // false
156
205
  ```
157
206
 
158
207
  ### Array Validators
@@ -168,10 +217,10 @@ Validators for handling arrays.
168
217
  ```typescript
169
218
  // Example:
170
219
  const tagsSchema = v.array(v.string().pipe(v.min(2)));
171
- tagsSchema.validate(['food', 'travel']).valid; // true
220
+ v.validate(tagsSchema, ['food', 'travel']).valid; // true
172
221
 
173
222
  const pointSchema = v.tuple([v.number(), v.number()]);
174
- pointSchema.validate([10, 20]).valid; // true
223
+ v.validate(pointSchema, [10, 20]).valid; // true
175
224
  ```
176
225
 
177
226
  ### Object Validators
@@ -184,7 +233,6 @@ Validators for handling objects.
184
233
  | `v.record(keySchema, valSchema)`| Validates objects with dynamic keys (like dictionaries or records). |
185
234
  | `v.objectPick(schema, keys)` | Creates a new object schema by picking specified keys from an existing one. |
186
235
  | `v.objectOmit(schema, keys)` | Creates a new object schema by omitting specified keys from an existing one. |
187
- | `v.objectExtends(schema, pipes)`| Extends an object schema with new properties. |
188
236
  | `v.asMap()` | **Transformer**: Converts a record-like object into a `Map`. |
189
237
 
190
238
  ```typescript
@@ -192,7 +240,7 @@ Validators for handling objects.
192
240
  const userSchema = v.object({ name: v.string(), age: v.number() });
193
241
 
194
242
  const publicUserSchema = v.objectOmit(userSchema, ['age']);
195
- publicUserSchema.validate({ name: 'John' }).valid; // true
243
+ v.validate(publicUserSchema, { name: 'John' }).valid; // true
196
244
  ```
197
245
 
198
246
  ### Optional & Default Values
@@ -205,7 +253,7 @@ Functions for handling optional values and providing defaults.
205
253
  | `v.nullable(schema)` | Allows the value to be `null`. |
206
254
  | `v.nullish(schema)` | Allows the value to be `null` or `undefined`. |
207
255
  | `v.defaults(schema, val)` | Provides a default value if the input is `undefined`. |
208
- | `v.defaultsOnFail(schema, val)`| Provides a default value if the initial validation fails. |
256
+ | `v.catch(schema, val)`| Provides a fallback value if the initial validation fails. |
209
257
  | `v.conditional(schema, fn)` | Makes a field optional based on a dynamic boolean condition. |
210
258
 
211
259
  ```typescript
@@ -216,7 +264,7 @@ const schema = v.object({
216
264
  role: v.defaults(v.string(), 'user'),
217
265
  });
218
266
 
219
- schema.parse({ name: 'John' });
267
+ v.assert(schema, { name: 'John' });
220
268
  // { name: 'John', role: 'user' }
221
269
  ```
222
270
 
@@ -239,8 +287,8 @@ const shapeSchema = v.discriminate(v => v.type, {
239
287
  square: v.object({ type: v.is('square'), side: v.number() }),
240
288
  });
241
289
 
242
- shapeSchema.validate({ type: 'circle', radius: 10 }).valid; // true
243
- shapeSchema.validate({ type: 'square', side: 5 }).valid; // true
290
+ v.validate(shapeSchema, { type: 'circle', radius: 10 }).valid; // true
291
+ v.validate(shapeSchema, { type: 'square', side: 5 }).valid; // true
244
292
  ```
245
293
 
246
294
  ### Date & Time Validators
@@ -278,8 +326,8 @@ Validators for file-like objects (e.g., from a file upload). These validators ex
278
326
  ```typescript
279
327
  // Example:
280
328
  const imageSchema = v.file().pipe(v.image(), v.fileType(['image/jpeg', 'image/png']));
281
- imageSchema.validate({ type: 'image/png' }).valid; // true
282
- imageSchema.validate({ type: 'image/gif' }).valid; // false
329
+ v.validate(imageSchema, { type: 'image/png' }).valid; // true
330
+ v.validate(imageSchema, { type: 'image/gif' }).valid; // false
283
331
  ```
284
332
 
285
333
  ### Coercion
@@ -296,8 +344,57 @@ These pipes attempt to convert the input to a specific type before validating it
296
344
  ```typescript
297
345
  // Example:
298
346
  const schema = v.coerceNumber().pipe(v.int());
299
- schema.parse('123'); // 123
300
- schema.validate('123.45').valid; // false (fails int())
347
+ v.assert(schema, '123'); // 123
348
+ v.validate(schema, '123.45').valid; // false (fails int())
349
+ ```
350
+
351
+ ## 🛠️ Utilities
352
+
353
+ Valleyed also exports a few standalone utilities.
354
+
355
+ ### DataClass
356
+
357
+ A simple base class for creating data-centric classes with `toJSON` and custom inspection support.
358
+
359
+ ```typescript
360
+ import { DataClass } from 'valleyed';
361
+
362
+ class User extends DataClass<{ name: string; email: string }> {
363
+ constructor(data: { name: string; email: string }) {
364
+ super(data);
365
+ }
366
+ }
367
+
368
+ const user = new User({ name: 'John', email: 'john@example.com' });
369
+ console.log(user.name); // 'John'
370
+ console.log(user.toJSON()); // { name: 'John', email: 'email' }
371
+ ```
372
+
373
+ ### Geohash
374
+
375
+ Utilities for encoding and decoding geohashes.
376
+
377
+ ```typescript
378
+ import { geohash } from 'valleyed';
379
+
380
+ const hash = geohash.encode([40.7128, -74.0060]); // 'dr5regw3pg'
381
+ const [lat, lon] = geohash.decode(hash); // [40.7128, -74.0060]
382
+ const neighbors = geohash.neighbors(hash);
383
+ ```
384
+
385
+ ### Differ
386
+
387
+ A utility for deep-diffing, checking equality, and merging objects.
388
+
389
+ ```typescript
390
+ import { differ } from 'valleyed';
391
+
392
+ const obj1 = { a: 1, b: { c: 2 } };
393
+ const obj2 = { a: 1, b: { c: 3 } };
394
+
395
+ differ.equal(obj1, obj2); // false
396
+ differ.diff(obj1, obj2); // ['b.c']
397
+ differ.merge(obj1, { b: { d: 4 } }); // { a: 1, b: { c: 2, d: 4 } }
301
398
  ```
302
399
 
303
400
  ## 🤝 Contributing
@@ -1,4 +1,4 @@
1
1
  import { PipeInput, type Pipe, type PipeOutput } from './base';
2
- export declare const array: <T extends Pipe<any, any, any>>(pipeSchema: T) => Pipe<PipeInput<T>[], PipeOutput<T>[], any>;
3
- export declare const tuple: <T extends ReadonlyArray<Pipe<any, any, any>>>(pipes: readonly [...T]) => Pipe<{ [K in keyof T]: PipeInput<T[K]>; }, { [K_1 in keyof T]: PipeOutput<T[K_1]>; }, any>;
2
+ export declare const array: <T extends Pipe<any, any, any>>(pipeSchema: T, err?: string) => Pipe<PipeInput<T>[], PipeOutput<T>[], any>;
3
+ export declare const tuple: <T extends ReadonlyArray<Pipe<any, any, any>>>(pipes: readonly [...T], err?: string) => Pipe<{ [K in keyof T]: PipeInput<T[K]>; }, { [K_1 in keyof T]: PipeOutput<T[K_1]>; }, any>;
4
4
  export declare const asSet: <T>(keyFn?: (i: T) => PropertyKey) => Pipe<T[], T[], any>;
package/lib/api/arrays.js CHANGED
@@ -1,11 +1,11 @@
1
- import { pipe, PipeError } from './base';
2
- export const array = (pipeSchema) => pipe((input) => {
1
+ import { pipe, PipeError, schema, validate } from './base';
2
+ export const array = (pipeSchema, err = 'is not an array') => pipe((input) => {
3
3
  if (!Array.isArray(input))
4
- throw PipeError.root('is not an array', input);
4
+ throw PipeError.root(err, input);
5
5
  if (input.length === 0)
6
6
  return input;
7
7
  const res = input.map((i, idx) => {
8
- const validity = pipeSchema.validate(i);
8
+ const validity = validate(pipeSchema, i);
9
9
  if (!validity.valid)
10
10
  return PipeError.path(idx, validity.error, i);
11
11
  return validity.value;
@@ -13,18 +13,16 @@ export const array = (pipeSchema) => pipe((input) => {
13
13
  if (res.some((r) => r instanceof PipeError))
14
14
  throw PipeError.rootFrom(res.filter((r) => r instanceof PipeError), input);
15
15
  return res;
16
- }, { schema: () => ({ type: 'array', items: pipeSchema.toJsonSchema() }) });
17
- export const tuple = (pipes) => pipe((input) => {
16
+ }, { schema: () => ({ type: 'array', items: schema(pipeSchema) }) });
17
+ export const tuple = (pipes, err = 'is not an array') => pipe((input) => {
18
18
  if (!Array.isArray(input))
19
- throw PipeError.root('is not an array', input);
20
- if (pipes.length !== input.length)
21
- throw PipeError.root(`expected ${pipes.length} but got ${input.length} items`, input);
22
- if (input.length === 0)
19
+ throw PipeError.root(err, input);
20
+ if (pipes.length === 0)
23
21
  return input;
24
- const res = input.map((i, idx) => {
25
- const validitity = pipes[idx].validate(i);
22
+ const res = pipes.map((pipe, idx) => {
23
+ const validitity = validate(pipe, input[idx]);
26
24
  if ('error' in validitity)
27
- return PipeError.path(idx, validitity.error, i);
25
+ return PipeError.path(idx, validitity.error, input[idx]);
28
26
  return validitity.value;
29
27
  });
30
28
  if (res.some((r) => r instanceof PipeError))
@@ -33,7 +31,7 @@ export const tuple = (pipes) => pipe((input) => {
33
31
  }, {
34
32
  schema: () => ({
35
33
  type: 'array',
36
- items: pipes.map((pipe) => pipe.toJsonSchema()),
34
+ items: pipes.map((pipe) => schema(pipe)),
37
35
  minItems: pipes.length,
38
36
  maxItems: pipes.length,
39
37
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"arrays.js","sourceRoot":"","sources":["../../src/api/arrays.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"arrays.js","sourceRoot":"","sources":["../../src/api/arrays.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,23 @@
1
- import { PipeFn, Context, JsonSchemaBuilder, Pipe } from './types';
1
+ import { PipeError } from './errors';
2
+ import { PipeFn, Context, JsonSchemaBuilder, PipeMeta, Pipe, PipeOutput, PipeContext } from './types';
3
+ import { JsonSchema } from '../../utils/types';
4
+ export declare function walk<T>(pipe: Pipe<any, any, any>, init: T, nodeFn: (cur: Pipe<any, any, any>, acc: T) => T): T;
5
+ export declare function context<T extends Pipe<any, any, any>>(pipe: T): Context<PipeContext<T>>;
6
+ export declare function assert<T extends Pipe<any, any, any>>(pipe: T, input: unknown): PipeOutput<T>;
7
+ export declare function validate<T extends Pipe<any, any, any>>(pipe: T, input: unknown): {
8
+ value: PipeOutput<T>;
9
+ valid: true;
10
+ } | {
11
+ error: PipeError;
12
+ valid: false;
13
+ };
14
+ export declare function schema<T extends Pipe<any, any, any>>(pipe: T, schema?: JsonSchema): JsonSchema;
15
+ export declare function meta<T extends Pipe<any, any, any>>(p: T, meta: PipeMeta): T;
2
16
  export declare function pipe<I, O, C>(func: PipeFn<I, O, C>, config?: {
3
17
  context?: () => Context<C>;
4
- schema?: () => JsonSchemaBuilder;
18
+ schema?: (context: Context<C>) => JsonSchemaBuilder;
5
19
  }): Pipe<I, O, C>;
6
- export declare function makeBranchPipe<P extends Pipe<any, any, any>, I, O, C>(branch: P, fn: PipeFn<I, O, C>, config: {
20
+ export declare function branch<P extends Pipe<any, any, any>, I, O, C>(branch: P, fn: PipeFn<I, O, C>, config: {
7
21
  context: (context: Context<C>) => Context<C>;
8
- schema: (schema: JsonSchemaBuilder) => JsonSchemaBuilder;
22
+ schema: (schema: JsonSchemaBuilder, context: Context<C>) => JsonSchemaBuilder;
9
23
  }): Pipe<I, O, C>;
@@ -1,58 +1,68 @@
1
1
  import { PipeError } from './errors';
2
+ export function walk(pipe, init, nodeFn) {
3
+ let acc = init;
4
+ while (pipe) {
5
+ acc = nodeFn(pipe, acc);
6
+ pipe = pipe.next;
7
+ }
8
+ return acc;
9
+ }
10
+ export function context(pipe) {
11
+ return walk(pipe, {}, (p, acc) => ({ ...acc, ...p.context() }));
12
+ }
13
+ export function assert(pipe, input) {
14
+ try {
15
+ const cont = context(pipe);
16
+ return walk(pipe, input, (p, acc) => p.fn(acc, cont));
17
+ }
18
+ catch (error) {
19
+ if (error instanceof PipeError) {
20
+ if (error.stopped)
21
+ return error.value;
22
+ throw error;
23
+ }
24
+ throw PipeError.root(error instanceof Error ? error.message : `${error}`, input, error);
25
+ }
26
+ }
27
+ export function validate(pipe, input) {
28
+ try {
29
+ const value = assert(pipe, input);
30
+ return { value, valid: true };
31
+ }
32
+ catch (error) {
33
+ if (error instanceof PipeError)
34
+ return { error, valid: false };
35
+ throw PipeError.root(error instanceof Error ? error.message : `${error}`, input, error);
36
+ }
37
+ }
38
+ export function schema(pipe, schema = {}) {
39
+ const cont = context(pipe);
40
+ return walk(pipe, schema, (p, acc) => ({ ...acc, ...p.schema(cont) }));
41
+ }
42
+ export function meta(p, meta) {
43
+ return p.pipe(pipe((i) => i, { schema: () => meta }));
44
+ }
2
45
  export function pipe(func, config = {}) {
3
- let meta = {};
4
- const node = {
46
+ const piper = {
5
47
  fn: func,
6
48
  context: () => config.context?.() ?? {},
7
- schema: () => ({ ...config.schema?.(), ...meta }),
8
- };
9
- const piper = {
10
- prev: undefined,
11
- node,
12
- pipe: (...entries) => entries.reduce((acc, cur) => {
13
- const p = typeof cur === 'function' ? pipe(cur, config) : cur;
14
- p.prev = acc;
15
- return p;
16
- }, piper),
17
- parse: (input) => {
18
- try {
19
- const { nodes, context } = gather(piper);
20
- return nodes.reduce((acc, cur) => cur.fn(acc, context), input);
21
- }
22
- catch (error) {
23
- if (error instanceof PipeError) {
24
- if (error.stopped)
25
- return error.value;
26
- throw error;
27
- }
28
- throw PipeError.root(error instanceof Error ? error.message : `${error}`, input, error);
29
- }
30
- },
31
- validate: (input) => {
32
- try {
33
- const value = piper.parse(input);
34
- return { value, valid: true };
49
+ schema: (context) => config.schema?.(context) ?? {},
50
+ pipe: (...entries) => {
51
+ for (const cur of entries) {
52
+ const p = typeof cur === 'function' ? pipe(cur, config) : cur;
53
+ if (!piper.next)
54
+ piper.next = p;
55
+ if (piper.last)
56
+ piper.last.next = p;
57
+ piper.last = p.last ?? p;
35
58
  }
36
- catch (error) {
37
- if (error instanceof PipeError)
38
- return { error, valid: false };
39
- throw error;
40
- }
41
- },
42
- context: () => gather(piper).context,
43
- meta: (schema) => {
44
- meta = { ...meta, ...schema };
45
59
  return piper;
46
60
  },
47
- toJsonSchema: (schema = {}) => {
48
- const { nodes } = gather(piper);
49
- return nodes.reduce((acc, cur) => ({ ...acc, ...cur.schema() }), schema);
50
- },
51
61
  '~standard': {
52
62
  version: 1,
53
63
  vendor: 'valleyed',
54
64
  validate(value) {
55
- const validity = piper.validate(value);
65
+ const validity = validate(piper, value);
56
66
  if (validity.valid)
57
67
  return { value: validity.value };
58
68
  return {
@@ -66,21 +76,11 @@ export function pipe(func, config = {}) {
66
76
  };
67
77
  return piper;
68
78
  }
69
- function gather(pipe) {
70
- const pipes = [pipe.node];
71
- while (pipe.prev) {
72
- pipes.push(pipe.prev.node);
73
- pipe = pipe.prev;
74
- }
75
- const nodes = pipes.reverse();
76
- const context = nodes.reduce((acc, cur) => ({ ...acc, ...cur.context() }), {});
77
- return { nodes, context };
78
- }
79
- export function makeBranchPipe(branch, fn, config) {
79
+ export function branch(branch, fn, config) {
80
80
  return pipe(fn, {
81
81
  ...config,
82
- context: () => config.context(branch.context()),
83
- schema: () => ({ ...config.schema(branch.toJsonSchema()) }),
82
+ context: () => config.context(context(branch)),
83
+ schema: (context) => ({ ...config.schema(schema(branch), context) }),
84
84
  });
85
85
  }
86
86
  //# sourceMappingURL=pipes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipes.js","sourceRoot":"","sources":["../../../src/api/base/pipes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pipes.js","sourceRoot":"","sources":["../../../src/api/base/pipes.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,27 @@
1
1
  import { StandardSchemaV1 } from '@standard-schema/spec';
2
- import { PipeError } from './errors';
3
- import { JsonSchema } from '../../utils/types';
4
- export type PipeFn<I, O = I, C = any> = (input: I, context: Context<C>) => O;
2
+ import { ValueFunction } from '../../utils/functions';
3
+ import { IsInTypeList, JsonSchema } from '../../utils/types';
4
+ import type { Timeable } from '../times';
5
+ export type PipeFn<I, O, C> = (input: I, context: Context<C>) => O;
5
6
  export type PipeInput<T> = T extends Pipe<infer I, any, any> ? I : never;
6
7
  export type PipeOutput<T> = T extends Pipe<any, infer O, any> ? O : never;
7
8
  export type PipeContext<T> = T extends Pipe<any, any, infer C> ? C : never;
8
- export type Context<C> = C & {
9
+ export type Context<C> = (IsInTypeList<C, [any, unknown, never]> extends true ? {} : C) & Readonly<{
9
10
  optional?: boolean;
10
- objectPipes?: Record<string, Pipe<any, any, any>>;
11
- };
11
+ objectKeys?: string[];
12
+ eq?: ValueFunction<unknown>;
13
+ ne?: ValueFunction<unknown>;
14
+ in?: ValueFunction<Readonly<unknown[]>>;
15
+ nin?: ValueFunction<Readonly<unknown[]>>;
16
+ has?: ValueFunction<number>;
17
+ min?: ValueFunction<number>;
18
+ max?: ValueFunction<number>;
19
+ fileTypes?: ValueFunction<string | string[]>;
20
+ defaults?: ValueFunction<unknown>;
21
+ catch?: ValueFunction<unknown>;
22
+ after?: ValueFunction<Timeable>;
23
+ before?: ValueFunction<Timeable>;
24
+ }>;
12
25
  export type PipeMeta = Pick<JsonSchema, '$refId' | 'title' | 'description' | 'examples' | 'default'>;
13
26
  export type JsonSchemaBuilder = JsonSchema;
14
27
  export type Entry<I, O, C> = Pipe<I, O, C> | PipeFn<I, O, C>;
@@ -25,24 +38,11 @@ type PipeChain<I, O, C> = {
25
38
  <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(fn1: Entry<O, T1, C>, fn2: Entry<T1, T2, C>, f3: Entry<T2, T3, C>, f4: Entry<T3, T4, C>, f5: Entry<T4, T5, C>, f6: Entry<T5, T6, C>, f7: Entry<T6, T7, C>, f8: Entry<T7, T8, C>, f9: Entry<T8, T9, C>, f10: Entry<T9, T10, C>): Pipe<I, T10, C>;
26
39
  };
27
40
  export interface Pipe<I, O, C> extends StandardSchemaV1<I, O> {
28
- readonly node: PipeNode;
29
- prev?: Pipe<any, any, any>;
30
- pipe: PipeChain<I, O, C>;
31
- parse(input: unknown): O;
32
- validate(input: unknown): {
33
- value: O;
34
- valid: true;
35
- } | {
36
- error: PipeError;
37
- valid: false;
38
- };
39
- context(): Context<C>;
40
- meta(schema: PipeMeta): Pipe<I, O, C>;
41
- toJsonSchema(schema?: JsonSchema): JsonSchema;
41
+ readonly fn: PipeFn<I, O, C>;
42
+ readonly context: () => Context<C>;
43
+ readonly schema: (context: Context<C>) => JsonSchema;
44
+ readonly pipe: PipeChain<I, O, C>;
45
+ next?: Pipe<any, any, any>;
46
+ last?: Pipe<any, any, any>;
42
47
  }
43
- export type PipeNode = {
44
- fn: PipeFn<any, any, any>;
45
- context: () => Context<any>;
46
- schema: () => JsonSchema;
47
- };
48
48
  export {};