@railway-ts/pipelines 0.1.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 (47) hide show
  1. package/README.md +811 -0
  2. package/dist/composition/index.cjs +72 -0
  3. package/dist/composition/index.cjs.map +1 -0
  4. package/dist/composition/index.d.cts +286 -0
  5. package/dist/composition/index.d.ts +286 -0
  6. package/dist/composition/index.mjs +65 -0
  7. package/dist/composition/index.mjs.map +1 -0
  8. package/dist/index-BdfKTZ7O.d.cts +799 -0
  9. package/dist/index-BdfKTZ7O.d.ts +799 -0
  10. package/dist/index.cjs +1074 -0
  11. package/dist/index.cjs.map +1 -0
  12. package/dist/index.d.cts +3 -0
  13. package/dist/index.d.ts +3 -0
  14. package/dist/index.mjs +969 -0
  15. package/dist/index.mjs.map +1 -0
  16. package/dist/option/index.cjs +111 -0
  17. package/dist/option/index.cjs.map +1 -0
  18. package/dist/option/index.d.cts +1 -0
  19. package/dist/option/index.d.ts +1 -0
  20. package/dist/option/index.mjs +93 -0
  21. package/dist/option/index.mjs.map +1 -0
  22. package/dist/result/index.cjs +178 -0
  23. package/dist/result/index.cjs.map +1 -0
  24. package/dist/result/index.d.cts +1 -0
  25. package/dist/result/index.d.ts +1 -0
  26. package/dist/result/index.mjs +152 -0
  27. package/dist/result/index.mjs.map +1 -0
  28. package/dist/schema/index.cjs +794 -0
  29. package/dist/schema/index.cjs.map +1 -0
  30. package/dist/schema/index.d.cts +1867 -0
  31. package/dist/schema/index.d.ts +1867 -0
  32. package/dist/schema/index.mjs +735 -0
  33. package/dist/schema/index.mjs.map +1 -0
  34. package/examples/complete-pipelines/async-launch.ts +128 -0
  35. package/examples/complete-pipelines/async.ts +119 -0
  36. package/examples/complete-pipelines/hill-clohessy-wiltshire.ts +218 -0
  37. package/examples/complete-pipelines/hohmann-transfer.ts +159 -0
  38. package/examples/composition/advanced-composition.ts +32 -0
  39. package/examples/composition/curry-basics.ts +24 -0
  40. package/examples/composition/tupled-basics.ts +26 -0
  41. package/examples/index.ts +47 -0
  42. package/examples/interop/interop-examples.ts +110 -0
  43. package/examples/option/option-examples.ts +63 -0
  44. package/examples/result/result-examples.ts +110 -0
  45. package/examples/schema/basic.ts +78 -0
  46. package/examples/schema/union.ts +301 -0
  47. package/package.json +100 -0
@@ -0,0 +1,110 @@
1
+ import { pipe } from '@/composition';
2
+ import { ok, err, fromTry, match, flatMap, map, andThen, type Result } from '@/result';
3
+
4
+ // Example 1: Division by Zero
5
+ console.log('=== Division by Zero ===');
6
+
7
+ // Problem: Division can fail but functions don't show it in types
8
+ // function divide(a: number, b: number) {
9
+ // return a / b; // Returns Infinity for division by zero
10
+ // }
11
+
12
+ // Solution: Result makes failure explicit
13
+ function safeDivide(a: number, b: number) {
14
+ return b === 0 ? err('Division by zero') : ok(a / b);
15
+ }
16
+
17
+ const result1 = safeDivide(10, 2);
18
+ const result2 = safeDivide(10, 0);
19
+
20
+ match(result1, {
21
+ ok: (value) => console.log(`Result: ${value}`),
22
+ err: (error) => console.log(`Error: ${error}`),
23
+ }); // "Result: 5"
24
+
25
+ match(result2, {
26
+ ok: (value) => console.log(`Result: ${value}`),
27
+ err: (error) => console.log(`Error: ${error}`),
28
+ }); // "Error: Division by zero"
29
+
30
+ // Example 2: JSON Parsing
31
+ console.log('\n=== JSON Parsing ===');
32
+
33
+ // Problem: JSON.parse throws exceptions
34
+ // const data = JSON.parse('invalid json'); // Throws!
35
+
36
+ // Solution: fromTry captures exceptions as Results
37
+ const safeParseJson = (s: string) => fromTry(() => JSON.parse(s));
38
+
39
+ const valid = safeParseJson('{"name": "Alice"}');
40
+ const invalid = safeParseJson('invalid json');
41
+
42
+ match(valid, {
43
+ ok: (data) => console.log(`Parsed: ${data.name}`),
44
+ err: (error) => console.log(`Parse failed: ${error}`),
45
+ }); // "Parsed: Alice"
46
+
47
+ match(invalid, {
48
+ ok: (data) => console.log(`Parsed: ${data.name}`),
49
+ err: (error) => console.log(`Parse failed: ${error}`),
50
+ }); // "Parse failed: Unexpected token..."
51
+
52
+ // Example 3: Chaining Operations
53
+ console.log('\n=== Chaining Operations ===');
54
+
55
+ // Problem: Multiple operations that can fail require nested try/catch
56
+ // Solution: flatMapResult chains failing operations cleanly
57
+
58
+ const hasNumericValue = (u: unknown): u is { value: number } =>
59
+ typeof u === 'object' && u !== null && 'value' in u && typeof (u as { value: unknown }).value === 'number';
60
+
61
+ const toNumber = (data: unknown): Result<number, string> =>
62
+ hasNumericValue(data) ? ok(data.value) : err('Not a number');
63
+
64
+ const processNumber = (input: string) =>
65
+ pipe(
66
+ safeParseJson(input),
67
+ (result) => flatMap(result, toNumber),
68
+ (result) => flatMap(result, (num) => safeDivide(num, 2)),
69
+ (result) => map(result, (num) => Math.round(num)),
70
+ );
71
+
72
+ const success = processNumber('{"value": 42}');
73
+ const failure = processNumber('{"value": "not a number"}');
74
+
75
+ match(success, {
76
+ ok: (value) => console.log(`Final result: ${value}`),
77
+ err: (error) => console.log(`Failed: ${error}`),
78
+ }); // "Final result: 21"
79
+
80
+ match(failure, {
81
+ ok: (value) => console.log(`Final result: ${value}`),
82
+ err: (error) => console.log(`Failed: ${error}`),
83
+ }); // "Failed: Not a number"
84
+
85
+ // Example 4: Async Chaining with andThen
86
+ console.log('\n=== Async Chaining ===');
87
+
88
+ const safeDivideAsync = async (a: number, b: number): Promise<Result<number, string>> =>
89
+ b === 0 ? err('Division by zero') : ok(a / b);
90
+
91
+ const processNumberAsync = async (input: string) =>
92
+ await pipe(
93
+ safeParseJson(input),
94
+ (r) => andThen(r, toNumber),
95
+ (p) => andThen(p, (n) => safeDivideAsync(n, 2)),
96
+ (p) => andThen(p, (n) => ok(Math.round(n))),
97
+ );
98
+
99
+ const successAsync = await processNumberAsync('{"value": 42}');
100
+ const failureAsync = await processNumberAsync('{"value": "not a number"}');
101
+
102
+ match(successAsync, {
103
+ ok: (value) => console.log(`Async final result: ${value}`),
104
+ err: (error) => console.log(`Async failed: ${error}`),
105
+ }); // "Async final result: 21"
106
+
107
+ match(failureAsync, {
108
+ ok: (value) => console.log(`Async final result: ${value}`),
109
+ err: (error) => console.log(`Async failed: ${error}`),
110
+ }); // "Async failed: Not a number"
@@ -0,0 +1,78 @@
1
+ import {
2
+ array,
3
+ chain,
4
+ email,
5
+ matches,
6
+ minLength,
7
+ object,
8
+ optional,
9
+ parseBool,
10
+ parseDate,
11
+ parseNumber,
12
+ pattern,
13
+ required,
14
+ string,
15
+ stringEnum,
16
+ validateAndFormatResult,
17
+ nonEmpty,
18
+ } from '@/schema';
19
+
20
+ const invalidInput = {
21
+ username: 'jo', // too short
22
+ email: 'not-an-email', // invalid format
23
+ password: 'password', // not complex enough
24
+ age: '25', // string that will be parsed to a number
25
+ birthdate: '1995-05-15', // string that will be parsed to a Date
26
+ termsAccepted: 'yes', // string that will be parsed to boolean true
27
+ address: {
28
+ street: '123 Main St',
29
+ city: 'A', // too short
30
+ zipCode: '1234', // invalid format
31
+ },
32
+ contacts: ['email', 'phone', 'fax'], // fax is not a valid option
33
+ };
34
+
35
+ const validInput = {
36
+ username: 'john_doe',
37
+ email: 'valid@email.com',
38
+ password: 'ComplexPassword123!',
39
+ age: 30,
40
+ birthdate: new Date('1995-05-15'),
41
+ hasAcceptedTerms: true,
42
+ role: 'user',
43
+ address: {
44
+ street: '123 Main St',
45
+ city: 'New York',
46
+ zipCode: '10001',
47
+ },
48
+ contacts: ['email', 'phone'],
49
+ };
50
+
51
+ export const addressSchema = object({
52
+ street: optional(chain(string(), minLength(3))),
53
+ city: optional(chain(string(), minLength(2))),
54
+ zipCode: optional(chain(string(), pattern(/^\d{5}$/))),
55
+ });
56
+
57
+ export const userSchema = object({
58
+ username: required(chain(string(), nonEmpty(), minLength(3))),
59
+ email: required(chain(string(), nonEmpty(), email())),
60
+ password: required(chain(string(), nonEmpty(), minLength(8))),
61
+ age: required(parseNumber()),
62
+ birthdate: required(parseDate()),
63
+ hasAcceptedTerms: required(chain(parseBool(), matches(true, 'You must check this field'))),
64
+ role: required(stringEnum(['admin', 'user'])),
65
+ address: optional(addressSchema),
66
+ contacts: optional(array(stringEnum(['email', 'phone']))),
67
+ });
68
+
69
+ // Using validateAndFormatResult - one-liner convenience function
70
+ const valid = validateAndFormatResult(validInput, userSchema);
71
+
72
+ console.log('--- Valid User ---\n');
73
+ console.log(valid);
74
+
75
+ const invalid = validateAndFormatResult(invalidInput, userSchema);
76
+
77
+ console.log('--- Invalid User ---\n');
78
+ console.log(invalid);
@@ -0,0 +1,301 @@
1
+ import { match } from '@/result';
2
+ import {
3
+ between,
4
+ boolean,
5
+ chain,
6
+ discriminatedUnion,
7
+ formatErrors,
8
+ literal,
9
+ object,
10
+ parseDate,
11
+ parseNumber,
12
+ pattern,
13
+ required,
14
+ string,
15
+ stringEnum,
16
+ validate,
17
+ type InferSchemaType,
18
+ type ValidationError,
19
+ type ValidationResult,
20
+ } from '@/schema';
21
+
22
+ // === Literal Constants ===
23
+ export const ALERT_TYPES = {
24
+ ENGINE: 'engine',
25
+ HYDRAULIC: 'hydraulic',
26
+ ELECTRICAL: 'electrical',
27
+ FUEL: 'fuel',
28
+ } as const;
29
+
30
+ export const SEVERITY_LEVELS = ['warning', 'caution', 'advisory'] as const;
31
+ export type SeverityLevel = (typeof SEVERITY_LEVELS)[number];
32
+
33
+ export const ENGINE_NUMBERS = ['1', '2', '3', '4'] as const;
34
+ export type EngineNumber = (typeof ENGINE_NUMBERS)[number];
35
+
36
+ export const ENGINE_PARAMETERS = ['temperature', 'pressure', 'vibration', 'oil'] as const;
37
+ export type EngineParameter = (typeof ENGINE_PARAMETERS)[number];
38
+
39
+ export const HYDRAULIC_SYSTEMS = ['primary', 'backup', 'emergency'] as const;
40
+ export type HydraulicSystem = (typeof HYDRAULIC_SYSTEMS)[number];
41
+
42
+ export const ELECTRICAL_BUSES = ['main', 'essential', 'battery'] as const;
43
+ export type ElectricalBus = (typeof ELECTRICAL_BUSES)[number];
44
+
45
+ export const POWER_SOURCES = ['generator', 'apu', 'battery', 'external'] as const;
46
+ export type PowerSource = (typeof POWER_SOURCES)[number];
47
+
48
+ export const FUEL_TANKS = ['left_main', 'right_main', 'center', 'auxiliary'] as const;
49
+ export type FuelTank = (typeof FUEL_TANKS)[number];
50
+
51
+ // === Helper function to create common field definitions ===
52
+ const createCommonFields = () => ({
53
+ timestamp: required(parseDate()),
54
+ aircraftId: required(chain(string(), pattern(/^[A-Z]-[A-Z0-9]{4,5}$/))), // e.g., N-12345, G-ABCD
55
+ flightNumber: required(chain(string(), pattern(/^[A-Z]{2,3}\d{1,4}$/))), // e.g., UA123, DLH4567
56
+ severity: required(stringEnum<SeverityLevel>([...SEVERITY_LEVELS], 'Invalid severity level')),
57
+ acknowledged: required(boolean()),
58
+ });
59
+
60
+ // === Engine Alert Schema ===
61
+ const engineAlertSchema = object({
62
+ ...createCommonFields(),
63
+ type: required(literal(ALERT_TYPES.ENGINE)),
64
+ engineNumber: required(chain(stringEnum<EngineNumber>([...ENGINE_NUMBERS], 'Invalid engine number'), parseNumber())),
65
+ parameter: required(stringEnum<EngineParameter>([...ENGINE_PARAMETERS], 'Invalid engine parameter')),
66
+ value: required(chain(parseNumber(), between(0, 1000))),
67
+ threshold: required(chain(parseNumber(), between(0, 1000))),
68
+ exceedanceTime: required(chain(parseNumber(), between(0, 3600))),
69
+ });
70
+
71
+ // === Hydraulic System Alert Schema ===
72
+ const hydraulicAlertSchema = object({
73
+ ...createCommonFields(),
74
+ type: required(literal(ALERT_TYPES.HYDRAULIC)),
75
+ system: required(stringEnum<HydraulicSystem>([...HYDRAULIC_SYSTEMS], 'Invalid hydraulic system')),
76
+ pressure: required(chain(parseNumber(), between(0, 5000))),
77
+ fluidLevel: required(chain(parseNumber(), between(0, 100))),
78
+ temperature: required(chain(parseNumber(), between(-50, 150))),
79
+ });
80
+
81
+ // === Electrical System Alert Schema ===
82
+ const electricalAlertSchema = object({
83
+ ...createCommonFields(),
84
+ type: required(literal(ALERT_TYPES.ELECTRICAL)),
85
+ bus: required(stringEnum<ElectricalBus>([...ELECTRICAL_BUSES], 'Invalid electrical bus')),
86
+ voltage: required(chain(parseNumber(), between(0, 30))),
87
+ current: required(chain(parseNumber(), between(0, 200))),
88
+ source: required(stringEnum<PowerSource>([...POWER_SOURCES], 'Invalid power source')),
89
+ frequency: required(chain(parseNumber(), between(380, 420))),
90
+ });
91
+
92
+ // === Fuel System Alert Schema ===
93
+ const fuelAlertSchema = object({
94
+ ...createCommonFields(),
95
+ type: required(literal(ALERT_TYPES.FUEL)),
96
+ tank: required(stringEnum<FuelTank>([...FUEL_TANKS], 'Invalid fuel tank')),
97
+ quantity: required(chain(parseNumber(), between(0, 50_000))),
98
+ imbalance: required(boolean()),
99
+ consumptionRate: required(chain(parseNumber(), between(0, 10_000))),
100
+ estimatedEndurance: required(chain(parseNumber(), between(0, 24))),
101
+ });
102
+
103
+ // === Type Definitions ===
104
+ type EngineAlert = InferSchemaType<typeof engineAlertSchema>;
105
+ type HydraulicAlert = InferSchemaType<typeof hydraulicAlertSchema>;
106
+ type ElectricalAlert = InferSchemaType<typeof electricalAlertSchema>;
107
+ type FuelAlert = InferSchemaType<typeof fuelAlertSchema>;
108
+
109
+ type AlertTypes = EngineAlert | HydraulicAlert | ElectricalAlert | FuelAlert;
110
+
111
+ // === Create Discriminated Union ===
112
+ const completeAlertSchema = discriminatedUnion<AlertTypes>('type', {
113
+ [ALERT_TYPES.ENGINE]: engineAlertSchema,
114
+ [ALERT_TYPES.HYDRAULIC]: hydraulicAlertSchema,
115
+ [ALERT_TYPES.ELECTRICAL]: electricalAlertSchema,
116
+ [ALERT_TYPES.FUEL]: fuelAlertSchema,
117
+ });
118
+
119
+ type CompleteAlertSchema = InferSchemaType<typeof completeAlertSchema>;
120
+
121
+ // Result type used in this example that includes extra display fields
122
+ type AlertValidationDisplay = ValidationResult<CompleteAlertSchema> & {
123
+ summary?: string;
124
+ errorCount?: number;
125
+ };
126
+
127
+ // === Valid Data Examples ===
128
+ const validEngineAlert = {
129
+ // Common fields
130
+ timestamp: new Date('2025-01-17T14:30:00Z'),
131
+ aircraftId: 'N-12345',
132
+ flightNumber: 'UA456',
133
+ severity: 'warning',
134
+ acknowledged: false,
135
+ // Engine-specific fields
136
+ type: ALERT_TYPES.ENGINE,
137
+ engineNumber: '2',
138
+ parameter: 'temperature',
139
+ value: 850,
140
+ threshold: 800,
141
+ exceedanceTime: 45,
142
+ };
143
+
144
+ const validHydraulicAlert = {
145
+ // Common fields
146
+ timestamp: new Date('2025-01-17T14:35:00Z'),
147
+ aircraftId: 'G-ABCD',
148
+ flightNumber: 'BA789',
149
+ severity: 'caution',
150
+ acknowledged: true,
151
+ // Hydraulic-specific fields
152
+ type: ALERT_TYPES.HYDRAULIC,
153
+ system: 'primary',
154
+ pressure: 2950,
155
+ fluidLevel: 85,
156
+ temperature: 45,
157
+ };
158
+
159
+ // === Invalid Data Examples ===
160
+ const invalidAircraftIdPattern = {
161
+ timestamp: new Date('2025-01-17T14:40:00Z'),
162
+ aircraftId: '12345', // Missing prefix letter and dash
163
+ flightNumber: 'DL123',
164
+ severity: 'advisory',
165
+ acknowledged: false,
166
+ type: ALERT_TYPES.ELECTRICAL,
167
+ bus: 'main',
168
+ voltage: 28,
169
+ current: 50,
170
+ source: 'generator',
171
+ frequency: 400,
172
+ };
173
+
174
+ const invalidEngineNumber = {
175
+ timestamp: new Date('2025-01-17T14:45:00Z'),
176
+ aircraftId: 'N-98765',
177
+ flightNumber: 'AA100',
178
+ severity: 'warning',
179
+ acknowledged: false,
180
+ type: ALERT_TYPES.ENGINE,
181
+ engineNumber: '5', // Invalid engine number (only 1-4 allowed)
182
+ parameter: 'pressure',
183
+ value: 450,
184
+ threshold: 400,
185
+ exceedanceTime: 120,
186
+ };
187
+
188
+ const invalidFuelQuantity = {
189
+ timestamp: new Date('2025-01-17T14:50:00Z'),
190
+ aircraftId: 'C-FGHI',
191
+ flightNumber: 'AC202',
192
+ severity: 'caution',
193
+ acknowledged: true,
194
+ type: ALERT_TYPES.FUEL,
195
+ tank: 'center',
196
+ quantity: 75_000, // Exceeds maximum of 50_000 pounds
197
+ imbalance: true,
198
+ consumptionRate: 5000,
199
+ estimatedEndurance: 10,
200
+ };
201
+
202
+ const invalidAlertType = {
203
+ timestamp: new Date('2025-01-17T14:55:00Z'),
204
+ aircraftId: 'D-JKLM',
205
+ flightNumber: 'LH404',
206
+ severity: 'warning',
207
+ acknowledged: false,
208
+ type: 'navigation', // Invalid alert type
209
+ latitude: 45.5,
210
+ longitude: -73.5,
211
+ };
212
+
213
+ const missingCommonField = {
214
+ // Missing timestamp
215
+ aircraftId: 'F-NOPQ',
216
+ flightNumber: 'AF505',
217
+ severity: 'advisory',
218
+ acknowledged: false,
219
+ type: ALERT_TYPES.HYDRAULIC,
220
+ system: 'backup',
221
+ pressure: 3000,
222
+ fluidLevel: 90,
223
+ temperature: 25,
224
+ };
225
+
226
+ const extraFieldsInjection = {
227
+ // Test that extra fields are rejected
228
+ timestamp: new Date('2025-01-17T15:00:00Z'),
229
+ aircraftId: 'N-54321',
230
+ flightNumber: 'UA999',
231
+ severity: 'warning',
232
+ acknowledged: false,
233
+ type: ALERT_TYPES.ENGINE,
234
+ engineNumber: '1',
235
+ parameter: 'temperature',
236
+ value: 750,
237
+ threshold: 700,
238
+ exceedanceTime: 30,
239
+ // Attempting to inject extra fields
240
+ maliciousField: 'should-be-rejected',
241
+ __proto__: { injected: true },
242
+ constructor: { name: 'hack' },
243
+ };
244
+
245
+ // === Validation Function ===
246
+ const processValidation = (data: unknown) => {
247
+ const validationResult = validate(data, completeAlertSchema);
248
+ return match<CompleteAlertSchema, ValidationError[], AlertValidationDisplay>(validationResult, {
249
+ ok: (validData) => ({
250
+ valid: true,
251
+ data: validData,
252
+ summary: `Alert processed: ${validData.type} on ${validData.aircraftId} (${validData.severity})`,
253
+ }),
254
+ err: (errors) => ({
255
+ valid: false,
256
+ errors: formatErrors(errors),
257
+ errorCount: errors.length,
258
+ }),
259
+ });
260
+ };
261
+
262
+ // === Process and Log Results ===
263
+
264
+ console.log('=== Aircraft System Alert Validation Examples ===\n');
265
+
266
+ console.log('--- Valid Engine Alert ---');
267
+ const validEngineResult = processValidation(validEngineAlert);
268
+ console.log(validEngineResult);
269
+
270
+ console.log('--- Valid Hydraulic Alert ---');
271
+ const validHydraulicResult = processValidation(validHydraulicAlert);
272
+ console.log(validHydraulicResult);
273
+
274
+ console.log('--- Invalid: Bad Aircraft ID Pattern ---');
275
+ const invalidPatternResult = processValidation(invalidAircraftIdPattern);
276
+ console.log(invalidPatternResult);
277
+
278
+ console.log('--- Invalid: Engine Number Out of Range ---');
279
+ const invalidEngineResult = processValidation(invalidEngineNumber);
280
+ console.log(invalidEngineResult);
281
+
282
+ console.log('--- Invalid: Fuel Quantity Exceeds Limit ---');
283
+ const invalidFuelResult = processValidation(invalidFuelQuantity);
284
+ console.log(invalidFuelResult);
285
+
286
+ console.log('--- Invalid: Unknown Alert Type ---');
287
+ const invalidTypeResult = processValidation(invalidAlertType);
288
+ console.log(invalidTypeResult);
289
+
290
+ console.log('--- Invalid: Missing Common Field (timestamp) ---');
291
+ const missingFieldResult = processValidation(missingCommonField);
292
+ console.log(missingFieldResult);
293
+
294
+ console.log('--- Security Test: Extra Fields Injection ---');
295
+ const injectionResult = processValidation(extraFieldsInjection);
296
+ // After your processValidation call
297
+ console.log('--- Prototype Pollution Check ---');
298
+ console.log("Does a fresh object have 'injected'? ->", ({} as any).injected); // undefined
299
+ console.log("Does Object.prototype have 'injected'? ->", (Object.prototype as any).injected); // undefined
300
+ console.log(injectionResult);
301
+ console.log('Note: Extra fields should be rejected in strict mode');
package/package.json ADDED
@@ -0,0 +1,100 @@
1
+ {
2
+ "name": "@railway-ts/pipelines",
3
+ "version": "0.1.0",
4
+ "description": "Functional programming abstractions for TypeScript: Build robust data pipelines with schema validation, Option, Result, and railway-oriented programming.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./option": {
16
+ "types": "./dist/option/index.d.ts",
17
+ "import": "./dist/option/index.mjs",
18
+ "require": "./dist/option/index.cjs"
19
+ },
20
+ "./result": {
21
+ "types": "./dist/result/index.d.ts",
22
+ "import": "./dist/result/index.mjs",
23
+ "require": "./dist/result/index.cjs"
24
+ },
25
+ "./composition": {
26
+ "types": "./dist/composition/index.d.ts",
27
+ "import": "./dist/composition/index.mjs",
28
+ "require": "./dist/composition/index.cjs"
29
+ },
30
+ "./schema": {
31
+ "types": "./dist/schema/index.d.ts",
32
+ "import": "./dist/schema/index.mjs",
33
+ "require": "./dist/schema/index.cjs"
34
+ }
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "README.md",
39
+ "examples"
40
+ ],
41
+ "scripts": {
42
+ "build": "bunx tsup",
43
+ "build:watch": "bunx tsup --watch",
44
+ "dev": "bunx tsup --watch",
45
+ "test": "bun test",
46
+ "test:watch": "bun test --watch",
47
+ "test:coverage": "bun test --coverage",
48
+ "test:coverage:lcov": "mkdir -p coverage && bun test --coverage --coverage-reporter=lcov",
49
+ "test:bail": "bun test --bail",
50
+ "test:fast": "bun test --bail --timeout=1000",
51
+ "test:pattern": "bun test --test-name-pattern",
52
+ "test:only": "bun test --only",
53
+ "test:reporter": "bun test --reporter=junit --reporter-outfile=junit.xml",
54
+ "lint": "bunx eslint .",
55
+ "lint:fix": "bunx eslint . --fix",
56
+ "format": "bunx prettier --write .",
57
+ "format:check": "bunx prettier --check .",
58
+ "typecheck": "bunx tsc --noEmit",
59
+ "prepublishOnly": "bun run typecheck && bun run lint && bun run test && bun run build",
60
+ "check": "bun run typecheck && bun run lint && bun run test"
61
+ },
62
+ "keywords": [
63
+ "typescript",
64
+ "functional",
65
+ "option",
66
+ "result",
67
+ "railway",
68
+ "monads",
69
+ "schema",
70
+ "pipeline"
71
+ ],
72
+ "repository": {
73
+ "type": "git",
74
+ "url": "git+https://github.com/sakobu/railway-ts-pipelines.git"
75
+ },
76
+ "homepage": "https://github.com/sakobu/railway-ts-pipelines#readme",
77
+ "bugs": {
78
+ "url": "https://github.com/sakobu/railway-ts-pipelines/issues"
79
+ },
80
+ "sideEffects": false,
81
+ "author": "Sarkis Melkonian",
82
+ "license": "MIT",
83
+ "devDependencies": {
84
+ "@eslint/js": "^9.36.0",
85
+ "@types/bun": "latest",
86
+ "eslint": "^9.36.0",
87
+ "eslint-import-resolver-typescript": "^4.4.4",
88
+ "eslint-plugin-import": "^2.32.0",
89
+ "eslint-plugin-prettier": "^5.5.4",
90
+ "eslint-plugin-security": "^3.0.1",
91
+ "eslint-plugin-unicorn": "^61.0.2",
92
+ "globals": "^16.4.0",
93
+ "prettier": "^3.6.2",
94
+ "tsup": "^8.5.0",
95
+ "typescript-eslint": "^8.44.1"
96
+ },
97
+ "peerDependencies": {
98
+ "typescript": "^5"
99
+ }
100
+ }