@jakobkg/shapes-ts 0.3.2 → 0.5.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.
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export * as Shapes from "./shapes";
2
+ export { type Shape } from "./shapes";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/shapes/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/shapes/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,UAAU,CAAC;AACnC,OAAO,EAAE,KAAK,KAAK,EAAE,MAAM,UAAU,CAAC"}
package/dist/shapes.d.ts CHANGED
@@ -9,12 +9,19 @@ type ShapePredicate<T> = {
9
9
  predicate: (x: T) => boolean;
10
10
  description?: string | undefined;
11
11
  };
12
- interface Shape<T> {
12
+ type ShapeValidationError = {
13
+ path: string;
14
+ message: string;
15
+ expected: string;
16
+ got: unknown;
17
+ };
18
+ export type Shape<T> = {
13
19
  readonly typename: string;
14
20
  readonly [Predicates]: ShapePredicate<T>[];
15
21
  readonly [Properties]?: Record<string, Shape<T>>;
16
22
  readonly [AllowUnknownProperties]?: boolean;
17
23
  check(x: unknown): x is T;
24
+ errors(x: unknown): ShapeValidationError[];
18
25
  /**
19
26
  * Adds a custom validation predicate to the shape
20
27
  * @param predicate A function that takes a value of the shape's type and returns a boolean
@@ -24,7 +31,7 @@ interface Shape<T> {
24
31
  where(predicate: (x: T) => boolean, description?: string | undefined): Shape<T>;
25
32
  and<U>(other: Shape<U>): Shape<T & U>;
26
33
  or<U>(other: Shape<U>): Shape<T | U>;
27
- }
34
+ };
28
35
  interface ObjectOptions {
29
36
  readonly allowUnknownProperties?: boolean;
30
37
  readonly additionalPermittedProperties?: Record<string, Shape<Record<string, unknown>>>;
@@ -51,7 +58,7 @@ type Primitive = number | string | boolean | null | undefined;
51
58
  * get when doing something like `const one = 1 as const;`,
52
59
  * where the type is just the literal `1`
53
60
  */
54
- export declare function literal<T extends Primitive>(x: T): Shape<T>;
61
+ export declare function literal<T extends Primitive>(literal: T): Shape<T>;
55
62
  /**
56
63
  * Creates an array shape, representing `Array<T>` (aka `T[]`).
57
64
  * Takes the shape representing `T` as a parameter.
@@ -1 +1 @@
1
- {"version":3,"file":"shapes.d.ts","sourceRoot":"","sources":["../src/shapes/shapes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shapes.d.ts","sourceRoot":"","sources":["../src/shapes/shapes.ts"],"names":[],"mappings":"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"}
package/dist/shapes.js CHANGED
@@ -80,6 +80,7 @@ function base() {
80
80
  check: function (_) { return false; }
81
81
  },
82
82
  _a[Predicates] = [],
83
+ _a.errors = function (_) { return []; },
83
84
  _a.where = function (predicate, description) {
84
85
  var _a;
85
86
  return __assign(__assign({}, this), (_a = {}, _a[Predicates] = __spreadArray(__spreadArray([], this[Predicates], true), [{ predicate: predicate, description: description }], false), _a));
@@ -93,7 +94,31 @@ function base() {
93
94
  _a;
94
95
  }
95
96
  function makePrimitive(name, guard) {
96
- return __assign(__assign({}, base()), { typename: name, check: function (x) {
97
+ return __assign(__assign({}, base()), { typename: name, errors: function (x) {
98
+ var _a;
99
+ var errors = [];
100
+ if (!guard(x)) {
101
+ errors.push({
102
+ path: "",
103
+ message: "unexpected type",
104
+ expected: this.typename,
105
+ got: x,
106
+ });
107
+ return errors;
108
+ }
109
+ for (var _i = 0, _b = this[Predicates]; _i < _b.length; _i++) {
110
+ var predicate = _b[_i];
111
+ if (!predicate.predicate(x)) {
112
+ errors.push({
113
+ path: "",
114
+ message: (_a = predicate.description) !== null && _a !== void 0 ? _a : "predicate failed",
115
+ expected: this.typename,
116
+ got: x,
117
+ });
118
+ }
119
+ }
120
+ return errors;
121
+ }, check: function (x) {
97
122
  return guard(x) && tryPredicates(this, x);
98
123
  } });
99
124
  }
@@ -124,18 +149,39 @@ function boolean() {
124
149
  * get when doing something like `const one = 1 as const;`,
125
150
  * where the type is just the literal `1`
126
151
  */
127
- function literal(x) {
152
+ function literal(literal) {
128
153
  function matchesLiteral(u) {
129
- return u === x;
154
+ return u === literal;
130
155
  }
131
- return __assign(__assign({}, base()), { typename: isUndefined(x) ? "undefined" : JSON.stringify(x), check: function (x) {
156
+ return __assign(__assign({}, base()), { typename: isUndefined(literal) ? "undefined" : JSON.stringify(literal), check: function (x) {
132
157
  return matchesLiteral(x) && tryPredicates(this, x);
158
+ }, errors: function (x) {
159
+ var _a;
160
+ if (!matchesLiteral(x))
161
+ return [{ path: "", message: "unexpected type", expected: this.typename, got: x }];
162
+ var errors = [];
163
+ for (var _i = 0, _b = this[Predicates]; _i < _b.length; _i++) {
164
+ var predicate = _b[_i];
165
+ if (!predicate.predicate(x)) {
166
+ errors.push({
167
+ path: "",
168
+ message: (_a = predicate.description) !== null && _a !== void 0 ? _a : "predicate failed",
169
+ expected: this.typename,
170
+ got: x,
171
+ });
172
+ }
173
+ }
174
+ return errors;
133
175
  } });
134
176
  }
135
177
  /// COMPLEX SHAPE FACTORIES
136
178
  function makeUnion(left, right) {
137
179
  return __assign(__assign({}, base()), { typename: "".concat(left.typename, " | ").concat(right.typename), check: function (x) {
138
180
  return (left.check(x) || right.check(x)) && tryPredicates(this, x);
181
+ }, errors: function (x) {
182
+ if (this.check(x))
183
+ return [];
184
+ return __spreadArray(__spreadArray([], left.errors(x), true), right.errors(x), true);
139
185
  } });
140
186
  }
141
187
  function makeIntersection(left, right) {
@@ -143,8 +189,20 @@ function makeIntersection(left, right) {
143
189
  // Trickery: combine permitted properties of left and right shape
144
190
  var tolerantLeft = __assign(__assign({}, left), (_a = {}, _a[AllowUnknownProperties] = true, _a));
145
191
  var tolerantRight = __assign(__assign({}, right), (_b = {}, _b[AllowUnknownProperties] = true, _b));
146
- return __assign(__assign({}, base()), (_c = { typename: "".concat(left.typename, " & ").concat(right.typename) }, _c[Properties] = __assign(__assign({}, left[Properties]), right[Properties]), _c.check = function (x) {
147
- return tolerantLeft.check(x) && tolerantRight.check(x) && tryPredicates(this, x);
192
+ var combinedProperties = __assign(__assign({}, left[Properties]), right[Properties]);
193
+ return __assign(__assign({}, base()), (_c = { typename: "".concat(left.typename, " & ").concat(right.typename) }, _c[Properties] = combinedProperties, _c[AllowUnknownProperties] = !!(left[AllowUnknownProperties] && right[AllowUnknownProperties]), _c.check = function (x) {
194
+ if (!tolerantLeft.check(x) || !tolerantRight.check(x))
195
+ return false;
196
+ if (!this[AllowUnknownProperties] &&
197
+ (left[Properties] !== undefined || right[Properties] !== undefined)) {
198
+ for (var key in x) {
199
+ if (!(key in combinedProperties))
200
+ return false;
201
+ }
202
+ }
203
+ return tryPredicates(this, x);
204
+ }, _c.errors = function (x) {
205
+ return __spreadArray(__spreadArray([], left.errors(x), true), right.errors(x), true);
148
206
  }, _c));
149
207
  }
150
208
  /**
@@ -157,6 +215,37 @@ function array(shape) {
157
215
  }
158
216
  return __assign(__assign({}, base()), { typename: "Array<".concat(shape.typename, ">"), check: function (x) {
159
217
  return isArray(x) && innerMatches(x) && tryPredicates(this, x);
218
+ }, errors: function (x) {
219
+ var _a;
220
+ if (!isArray(x)) {
221
+ return [{
222
+ path: ".",
223
+ message: "unexpected type",
224
+ expected: this.typename,
225
+ got: x,
226
+ }];
227
+ }
228
+ var errors = [];
229
+ x.flatMap(function (value, idx) {
230
+ return shape.errors(value).map(function (err) {
231
+ err.path = ".[".concat(idx, "]") + err.path;
232
+ return err;
233
+ });
234
+ }).forEach(function (error) { return errors.push(error); });
235
+ if (errors.length > 0)
236
+ return errors;
237
+ for (var _i = 0, _b = this[Predicates]; _i < _b.length; _i++) {
238
+ var predicate = _b[_i];
239
+ if (!predicate.predicate(x)) {
240
+ errors.push({
241
+ path: "",
242
+ message: (_a = predicate.description) !== null && _a !== void 0 ? _a : "predicate failed",
243
+ expected: this.typename,
244
+ got: x,
245
+ });
246
+ }
247
+ }
248
+ return errors;
160
249
  } });
161
250
  }
162
251
  // deno-lint-ignore no-explicit-any
@@ -208,9 +297,53 @@ function object(nameOrProperties, propertiesOrOptions, maybeOptions) {
208
297
  }
209
298
  return true;
210
299
  }
211
- return __assign(__assign({}, base()), (_a = { typename: typename !== null && typename !== void 0 ? typename : "object" }, _a[AllowUnknownProperties] = allowUnknownProperties, _a.check = function (x) {
300
+ return __assign(__assign({}, base()), (_a = { typename: typename !== null && typename !== void 0 ? typename : "object" }, _a[Properties] = __assign(__assign({}, properties), options === null || options === void 0 ? void 0 : options.additionalPermittedProperties), _a[AllowUnknownProperties] = allowUnknownProperties, _a.check = function (x) {
212
301
  return matchesShape(this, x) && tryPredicates(this, x);
213
- }, _a[Properties] = __assign(__assign({}, properties), options === null || options === void 0 ? void 0 : options.additionalPermittedProperties), _a));
302
+ }, _a.errors = function (x) {
303
+ var _a;
304
+ if (!isObject(x)) {
305
+ return [{
306
+ path: ".",
307
+ message: "unexpected type",
308
+ expected: this.typename,
309
+ got: x,
310
+ }];
311
+ }
312
+ var errors = [];
313
+ var inputKeys = Object.keys(x);
314
+ var _loop_1 = function (propKey) {
315
+ var propShape = this_1[Properties][propKey];
316
+ if (!inputKeys.includes(propKey)) {
317
+ errors.push({
318
+ path: ".",
319
+ message: "unexpected property \"".concat(propKey, "\""),
320
+ expected: "undefined",
321
+ got: propShape.typename,
322
+ });
323
+ return "continue";
324
+ }
325
+ propShape.errors(Object.entries(x).find(function (entry) { return entry[0] === propKey; })[1]).map(function (err) {
326
+ err.path = ".".concat(propKey) + err.path;
327
+ return err;
328
+ }).forEach(function (error) { return errors.push(error); });
329
+ };
330
+ var this_1 = this;
331
+ for (var propKey in this[Properties]) {
332
+ _loop_1(propKey);
333
+ }
334
+ for (var _i = 0, _b = this[Predicates]; _i < _b.length; _i++) {
335
+ var predicate = _b[_i];
336
+ if (!predicate.predicate(x)) {
337
+ errors.push({
338
+ path: "",
339
+ message: (_a = predicate.description) !== null && _a !== void 0 ? _a : "predicate failed",
340
+ expected: this.typename,
341
+ got: x,
342
+ });
343
+ }
344
+ }
345
+ return errors;
346
+ }, _a));
214
347
  }
215
348
  /**
216
349
  * Creates a shape representing a tuple type, with an optional rest
@@ -231,7 +364,8 @@ function tuple(shapes, rest) {
231
364
  return false;
232
365
  }
233
366
  }
234
- return shapes.every(function (shape, idx) { return shape.check(x[idx]); }) && tryPredicates(this, x);
367
+ return (shapes.every(function (shape, idx) { return shape.check(x[idx]); }) &&
368
+ tryPredicates(this, x));
235
369
  } });
236
370
  }
237
371
  /**
@@ -242,7 +376,9 @@ function tuple(shapes, rest) {
242
376
  */
243
377
  function enumOf(values) {
244
378
  return __assign(__assign({}, base()), { typename: "".concat(values.map(function (v) { return JSON.stringify(v); }).join(" | ")), check: function (x) {
245
- return (isNumber(x) || isString(x)) && values.includes(x) && tryPredicates(this, x);
379
+ return ((isNumber(x) || isString(x)) &&
380
+ values.includes(x) &&
381
+ tryPredicates(this, x));
246
382
  } });
247
383
  }
248
384
  /// TYPE MODIFIERS
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "homepage": "https://codeberg.org/jakobkg/shapes-ts#readme",
8
8
  "license": "BSD-3-Clause",
9
- "version": "0.3.2",
9
+ "version": "0.5.0",
10
10
  "private": false,
11
11
  "main": "dist/index.js",
12
12
  "scripts": {