@railway-ts/pipelines 0.1.0 → 0.1.2
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/README.md +50 -0
- package/dist/index.cjs +65 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +64 -1
- package/dist/index.mjs.map +1 -1
- package/dist/schema/index.cjs +65 -0
- package/dist/schema/index.cjs.map +1 -1
- package/dist/schema/index.d.cts +64 -2
- package/dist/schema/index.d.ts +64 -2
- package/dist/schema/index.mjs +64 -1
- package/dist/schema/index.mjs.map +1 -1
- package/package.json +2 -4
- package/examples/complete-pipelines/async-launch.ts +0 -128
- package/examples/complete-pipelines/async.ts +0 -119
- package/examples/complete-pipelines/hill-clohessy-wiltshire.ts +0 -218
- package/examples/complete-pipelines/hohmann-transfer.ts +0 -159
- package/examples/composition/advanced-composition.ts +0 -32
- package/examples/composition/curry-basics.ts +0 -24
- package/examples/composition/tupled-basics.ts +0 -26
- package/examples/index.ts +0 -47
- package/examples/interop/interop-examples.ts +0 -110
- package/examples/option/option-examples.ts +0 -63
- package/examples/result/result-examples.ts +0 -110
- package/examples/schema/basic.ts +0 -78
- package/examples/schema/union.ts +0 -301
package/README.md
CHANGED
|
@@ -469,6 +469,55 @@ type Shape = InferSchemaType<typeof shapeSchema>;
|
|
|
469
469
|
// { type: 'circle', radius: number } | { type: 'rectangle', width: number, height: number }
|
|
470
470
|
```
|
|
471
471
|
|
|
472
|
+
#### Tuple Validators
|
|
473
|
+
|
|
474
|
+
Validate fixed-length arrays with type-safe element validation.
|
|
475
|
+
|
|
476
|
+
```typescript
|
|
477
|
+
import { tuple, tupleOf, chain, number, string, boolean, min, max, integer } from '@railway-ts/pipelines/schema';
|
|
478
|
+
|
|
479
|
+
// Heterogeneous tuple - different types per position
|
|
480
|
+
const userRecord = tuple([
|
|
481
|
+
string(), // position 0: string
|
|
482
|
+
chain(number(), integer(), min(0)), // position 1: non-negative integer
|
|
483
|
+
boolean(), // position 2: boolean
|
|
484
|
+
]);
|
|
485
|
+
|
|
486
|
+
type UserRecord = InferSchemaType<typeof userRecord>;
|
|
487
|
+
// [string, number, boolean]
|
|
488
|
+
|
|
489
|
+
validate(['user123', 25, true], userRecord); // ok(['user123', 25, true])
|
|
490
|
+
validate(['user123', -5, true], userRecord); // err - age must be >= 0
|
|
491
|
+
|
|
492
|
+
// Homogeneous tuple - same type repeated N times
|
|
493
|
+
const vector3 = tupleOf(number(), 3); // exactly 3 numbers
|
|
494
|
+
|
|
495
|
+
type Vector3 = InferSchemaType<typeof vector3>;
|
|
496
|
+
// [number, number, number]
|
|
497
|
+
|
|
498
|
+
validate([1.5, 2.3, 3.7], vector3); // ok([1.5, 2.3, 3.7])
|
|
499
|
+
validate([1, 2], vector3); // err - expected length 3, got 2
|
|
500
|
+
|
|
501
|
+
// With constraints
|
|
502
|
+
const rgbColor = tupleOf(
|
|
503
|
+
chain(number(), integer(), min(0), max(255)),
|
|
504
|
+
3
|
|
505
|
+
);
|
|
506
|
+
|
|
507
|
+
validate([255, 128, 64], rgbColor); // ok([255, 128, 64])
|
|
508
|
+
validate([255, 300, 0], rgbColor); // err - 300 exceeds max of 255
|
|
509
|
+
|
|
510
|
+
// Geographic coordinates [latitude, longitude]
|
|
511
|
+
const coordinate = tuple([
|
|
512
|
+
chain(number(), min(-90), max(90)), // latitude
|
|
513
|
+
chain(number(), min(-180), max(180)), // longitude
|
|
514
|
+
]);
|
|
515
|
+
|
|
516
|
+
validate([37.7749, -122.4194], coordinate); // ok - San Francisco
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
**Use cases:** Coordinates, RGB colors, version numbers, matrix rows, vectors, any fixed-length structured data.
|
|
520
|
+
|
|
472
521
|
#### Complete Schema Example
|
|
473
522
|
|
|
474
523
|
```typescript
|
|
@@ -761,6 +810,7 @@ Working examples organized by category:
|
|
|
761
810
|
- **Schema**: [`examples/schema/`](examples/schema/)
|
|
762
811
|
- [`basic.ts`](examples/schema/basic.ts) - Basic validators
|
|
763
812
|
- [`union.ts`](examples/schema/union.ts) - Union types
|
|
813
|
+
- [`tuple.ts`](examples/schema/tuple.ts) - Tuple validation
|
|
764
814
|
- **Composition**: [`examples/composition/`](examples/composition/)
|
|
765
815
|
- [`advanced-composition.ts`](examples/composition/advanced-composition.ts)
|
|
766
816
|
- [`curry-basics.ts`](examples/composition/curry-basics.ts)
|
package/dist/index.cjs
CHANGED
|
@@ -534,6 +534,69 @@ function stringEnum(allowedValues, message = `Value must be one of: ${allowedVal
|
|
|
534
534
|
});
|
|
535
535
|
}
|
|
536
536
|
|
|
537
|
+
// src/schema/tuple.ts
|
|
538
|
+
function tuple(validators) {
|
|
539
|
+
return (value, parentPath = []) => {
|
|
540
|
+
if (!Array.isArray(value)) {
|
|
541
|
+
return err([{ path: parentPath, message: "Expected an array" }]);
|
|
542
|
+
}
|
|
543
|
+
if (value.length !== validators.length) {
|
|
544
|
+
return err([
|
|
545
|
+
{
|
|
546
|
+
path: parentPath,
|
|
547
|
+
message: `Expected tuple of length ${validators.length}, got ${value.length}`
|
|
548
|
+
}
|
|
549
|
+
]);
|
|
550
|
+
}
|
|
551
|
+
const allErrors = [];
|
|
552
|
+
const validatedItems = [];
|
|
553
|
+
for (const [i, validator] of validators.entries()) {
|
|
554
|
+
const itemPath = [...parentPath, i.toString()];
|
|
555
|
+
const item = value.at(i);
|
|
556
|
+
const result = validator(item, itemPath);
|
|
557
|
+
if (isOk(result)) {
|
|
558
|
+
validatedItems.push(result.value);
|
|
559
|
+
} else {
|
|
560
|
+
allErrors.push(...result.error);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
if (allErrors.length > 0) {
|
|
564
|
+
return err(allErrors);
|
|
565
|
+
}
|
|
566
|
+
return ok(validatedItems);
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
function tupleOf(elementValidator, length) {
|
|
570
|
+
return (value, parentPath = []) => {
|
|
571
|
+
if (!Array.isArray(value)) {
|
|
572
|
+
return err([{ path: parentPath, message: "Expected an array" }]);
|
|
573
|
+
}
|
|
574
|
+
if (value.length !== length) {
|
|
575
|
+
return err([
|
|
576
|
+
{
|
|
577
|
+
path: parentPath,
|
|
578
|
+
message: `Expected tuple of length ${length}, got ${value.length}`
|
|
579
|
+
}
|
|
580
|
+
]);
|
|
581
|
+
}
|
|
582
|
+
const allErrors = [];
|
|
583
|
+
const validatedItems = [];
|
|
584
|
+
for (const [i, item] of value.entries()) {
|
|
585
|
+
const itemPath = [...parentPath, i.toString()];
|
|
586
|
+
const result = elementValidator(item, itemPath);
|
|
587
|
+
if (isOk(result)) {
|
|
588
|
+
validatedItems.push(result.value);
|
|
589
|
+
} else {
|
|
590
|
+
allErrors.push(...result.error);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
if (allErrors.length > 0) {
|
|
594
|
+
return err(allErrors);
|
|
595
|
+
}
|
|
596
|
+
return ok(validatedItems);
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
|
|
537
600
|
// src/schema/number.ts
|
|
538
601
|
function number(message = "Must be a number") {
|
|
539
602
|
return (value, path = []) => {
|
|
@@ -1056,6 +1119,8 @@ exports.tapResult = tap;
|
|
|
1056
1119
|
exports.toPromise = toPromise;
|
|
1057
1120
|
exports.todayOrFuture = todayOrFuture;
|
|
1058
1121
|
exports.transform = transform;
|
|
1122
|
+
exports.tuple = tuple;
|
|
1123
|
+
exports.tupleOf = tupleOf;
|
|
1059
1124
|
exports.tupled = tupled;
|
|
1060
1125
|
exports.uncurry = uncurry;
|
|
1061
1126
|
exports.union = union;
|