1 | # Changelog
|
2 |
|
3 | This document maintains a list of changes to the `superstruct` package with each new version. Until `1.0.0` is released, breaking changes will be added as minor version bumps, and smaller changes and fixes won't be detailed.
|
4 |
|
5 | ### `0.8.0` — October 8, 2019
|
6 |
|
7 | ###### BREAKING
|
8 |
|
9 | **Several structs have been renamed!** Superstruct tries to mimic established naming schemes whenever possible for its API, and TypeScript is one of our main comparisons. To make things easier for people, we've renamed a few structs to more closely match their TypeScript counterparts:
|
10 |
|
11 | - The `list` struct is now called `array`.
|
12 | - The `partial` struct is now called `pick`.
|
13 | - The `dict` struct is now called `record`.
|
14 |
|
15 | Hopefully this will make them easier to understand at a glance!
|
16 |
|
17 | **The `enums` struct has been removed!** This was special-cased in the API previously, but you can get the exact same behavior by creating an using the `array` and `enum` structs:
|
18 |
|
19 | ```js
|
20 | struct.array(struct.enum(['red', 'blue', 'green']))
|
21 | ```
|
22 |
|
23 | **The `any` struct has been removed! (Not the scalar though.)** Previously `struct.any()` was exposed that did the same thing as `struct()`, allowing you to use shorthands for common structs. But this was confusingly named because it has nothing to do with the `'any'` scalar type. And since it was redundant it has been removed.
|
24 |
|
25 | **The `interface` struct now returns the original, unaltered value!** In an effort to make things more familiar, the `interface` struct now always returns the object that it is called with when it passes validation. So if the object was a function, a function will be returned. This makes it match more closely with the idea of "structural typing" that TypeScript and other typing systems are based on. \_If you want the old behavior, use the `pick` struct.
|
26 |
|
27 | **Computed values function signatures have changed!** Previously a computed value would be called with a signature of `(value, root)` in some cases and `(value, parent)` in others. This was confusing, and the cause for the inconsistency was complex. This logic has been simplified, and now computed values are called with `(value, branch, path)` in all cases.
|
28 |
|
29 | ```js
|
30 | struct.dynamic((value, branch, path) => {
|
31 | value === branch[branch.length - 1] // you can get the value...
|
32 | const parent = branch[branch.length - 2] // ...and the parent...
|
33 | const key = path[path.length - 1] // ...and the key...
|
34 | value === parent[key]
|
35 | const root = branch[0] // ...and the root!
|
36 | })
|
37 | ```
|
38 |
|
39 | The `path` is an array of keys representing the nested value's location in the root value. And the `branch` is an array of all of the sub values along the path to get to the current one. This allows you to always be able to receive both the **parent** and the **root** values from any location—as well as any value in between.
|
40 |
|
41 | **The `error.errors` property has been renamed `error.failures`, and isn't cyclical.** It being cyclical caused lots of issues whenever an `StructError` object was attempted to be serialized. And the `errors` property was slightly confusing because the elements of the array weren't full error objects. The new structure is easier to understand and work with.
|
42 |
|
43 | **The `error.reason` property is no longer special-cased.** Previously you could return a "reason" string from validator functions and it would be added to error objects. However, now you must return an error properties object (with a `reason` property if you'd like), and all of the properties will be added to the error object. This makes Superstruct even more flexible as far as custom error details go.
|
44 |
|
45 | **The `type` property of structs have been rewritten to be more clear.** This is an implementation mostly, but the `struct.type` string which shows up in error messages have been tweaked to be slightly more clear exactly what type they are checking for.
|
46 |
|
47 | ###### NEW
|
48 |
|
49 | **Superstruct is now written in TypeScript.** It was rewritten from the ground up to make use of types, and to have better inline documented if you use a TypeScript-compatible IDE. There are probably improvements that can be made, so if you'd like to contribute please do!
|
50 |
|
51 | **A new `partial` struct mimics TypeScript's `Partial` utility.** The new struct validates that its input partially matches an object defined as a set of properties with associated types. All of the properties of the object are optional.
|
52 |
|
53 | **A new `size` struct allows validating array and string lengths.** The new struct validates that its input has a certain size, by checking its `length` property. This works strings or arrays.
|
54 |
|
55 | **You can now provide a custom `Error` setting.** By passing in your own constructor when configuring Superstruct you can have complete control over the exact errors that are generated by structs that fail validation.
|
56 |
|
57 | ### `0.7.0` — September 21, 2019
|
58 |
|
59 | ###### BREAKING
|
60 |
|
61 | - **The build process now outputs ES5 code.** Previously it was outputting ES6 code, which posed problems for some builders. This change shouldn't really affect anyone negatively, but it's being released as a breaking version just in case.
|
62 |
|
63 | ---
|
64 |
|
65 | ### `0.6.0` — September 13, 2018
|
66 |
|
67 | ###### BREAKING
|
68 |
|
69 | - **Invalid `Date` objects are now considered invalid.** Previously using the built-in `'date'` validator would only check that the object was a `Date` instance, and not that it was a valid one. This has been fixed, and although it is technically a breaking change, most everyone would have expected this behavior to begin with.
|
70 |
|
71 | ---
|
72 |
|
73 | ### `0.5.0` — December 21, 2017
|
74 |
|
75 | ###### BREAKING
|
76 |
|
77 | - **Validators must now return `true`, `false` or an error reason string.** Previously any truthy value would be considered valid. Now you can provide more information for the thrown errors by providing a string which will be attached as `error.reason`. However, this means that truthy string values now equate to invalid, not valid.
|
78 |
|
79 | - **Property validators now receive `data` as their second argument.** Previously you only had access to the property `value`, but now you also have access to the entire object's `data`.
|
80 |
|
81 | ###### NEW
|
82 |
|
83 | - **Errors can now contain reason information.** Validator functions can now return string instead of a boolean, denoting the reason a value was invalid. This can then be used to create more helpful error messages.
|
84 |
|
85 | ---
|
86 |
|
87 | ### `0.4.0` — December 1, 2017
|
88 |
|
89 | ###### BREAKING
|
90 |
|
91 | - **`object` structs are no longer optional-ish.** Previously object struct types would not throw if `undefined` was passed and no properties were required. This was not only confusing, but complex to maintain. Now if you want an object struct to be optional, use the `struct.optional(...)` helper.
|
92 |
|
93 | - **Removed the `Struct.default` method.** If you need to get the default value, use the `Struct.validate` or `Struct.assert` methods's return value instead.
|
94 |
|
95 | ###### NEW
|
96 |
|
97 | - **Added the `dict`, `enum`, `intersection`, `union` and `tuple` structs.** These are all available as `struct.dict`, `struct.enum`, etc.
|
98 |
|
99 | ---
|
100 |
|
101 | ### `0.3.0` — November 30, 2017
|
102 |
|
103 | ###### BREAKING
|
104 |
|
105 | - **The `validate()` method now returns `[ error, result ]`.** Previously it only had a single return value, which necessitated extra type checking to see if the value was an error or a result. Now you can just destructure the array to get either return value, for easier coding.
|
106 |
|
107 | - **Errors have been simplified, removing "codes".** Previously there were multiple types of errors that were thrown and you could differentiate between them with the `error.code` property. But the other properties of the error already let you infer the code, so having multiple types of errors made for a larger API surface without much benefit.
|
108 |
|
109 | ---
|
110 |
|
111 | ### `0.2.0` — November 30, 2017
|
112 |
|
113 | ###### BREAKING
|
114 |
|
115 | - **Structs are now functions again.** :smile: They are built on the same underlying schema classes underneath though, since that helps the code structure. But to allow for the `struct = Struct({ ... })` syntax the structs themselves have changed to be function.
|
116 |
|
117 | ###### NEW
|
118 |
|
119 | - **The basic case is now `Struct(data)`.** Previously you had to use `Struct.assert(data)`. Although the `assert` method (and others) are still there, the basic case is a bit terser and more similar to the struct-initializing APIs in other languages.
|
120 |
|
121 | ---
|
122 |
|
123 | ### `0.1.0` — November 29, 2017
|
124 |
|
125 | ###### BREAKING
|
126 |
|
127 | - **Structs are now classes instead of functions.** This is better in terms of the API being a bit less magic-y. It's also useful so that we can add other helpful methods to structs besides the `assert` method. What was previously `struct(data)` is now `struct.assert(data)`.
|
128 |
|
129 | ---
|
130 |
|
131 | ### `0.0.0` — November 24, 2017
|
132 |
|
133 | :tada:
|