@muze-nl/assert 0.3.3 → 0.3.4
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 +59 -8
- package/package.json +1 -1
- package/src/assert.mjs +7 -3
package/README.md
CHANGED
|
@@ -1,9 +1,59 @@
|
|
|
1
|
-
|
|
1
|
+
[](https://github.com/muze-nl/assert/blob/main/LICENSE)
|
|
2
|
+
[]()
|
|
3
|
+
[](https://www.npmjs.com/package/assert)
|
|
4
|
+
[](https://www.npmjs.com/package/assert)
|
|
5
|
+
[![Project stage: Development][project-stage-badge: Development]][project-stage-page]
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
# Assert: javascript optional assertion checking
|
|
4
8
|
|
|
5
9
|
This is a light-weight library to do optional assertion checking. By default any assertions made are not tested. Assertion code is not run. Unless you toggle assertion checking, usually in developer mode, by calling `enable`. Now your assertions are run, and if any assertions fail, an error is thrown with information about the specific failure.
|
|
6
10
|
|
|
11
|
+
This style of assertion testing is often used with [Design by Contract](https://en.wikipedia.org/wiki/Design_by_contract) software development. When implementing a fixed specification, like a W3C recommendation or RFC, using design by contract allows you to write code very similar to the specification.
|
|
12
|
+
|
|
13
|
+
Here is an example from the [@muze-nl/metro-oidc](https://github.com/muze-nl/,etro-oidc) library, which shows how you can use Assert to check specification requirements, in a dense but readable way:
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
// https://openid.net/specs/openid-connect-registration-1_0.html#ClientMetadata
|
|
17
|
+
const openid_client_metadata = {
|
|
18
|
+
redirect_uris: Required([validURL]),
|
|
19
|
+
response_types: Optional([]),
|
|
20
|
+
grant_types: Optional(anyOf('authorization_code','refresh_token')), //TODO: match response_types with grant_types
|
|
21
|
+
application_type: Optional(oneOf('native','web')),
|
|
22
|
+
contacts: Optional([validEmail]),
|
|
23
|
+
client_name: Optional(String),
|
|
24
|
+
logo_uri: Optional(validURL),
|
|
25
|
+
client_uri: Optional(validURL),
|
|
26
|
+
policy_uri: Optional(validURL),
|
|
27
|
+
tos_uri: Optional(validURL),
|
|
28
|
+
jwks_uri: Optional(validURL, not(MustHave('jwks'))),
|
|
29
|
+
jwks: Optional(validURL, not(MustHave('jwks_uri'))),
|
|
30
|
+
sector_identifier_uri: Optional(validURL),
|
|
31
|
+
subject_type: Optional(String),
|
|
32
|
+
id_token_signed_response_alg: Optional(oneOf(...validJWA)),
|
|
33
|
+
id_token_encrypted_response_alg: Optional(oneOf(...validJWA)),
|
|
34
|
+
id_token_encrypted_response_enc: Optional(oneOf(...validJWA), MustHave('id_token_encrypted_response_alg')),
|
|
35
|
+
userinfo_signed_response_alg: Optional(oneOf(...validJWA)),
|
|
36
|
+
userinfo_encrypted_response_alg: Optional(oneOf(...validJWA)),
|
|
37
|
+
userinfo_encrypted_response_enc: Optional(oneOf(...validJWA), MustHave('userinfo_encrypted_response_alg')),
|
|
38
|
+
request_object_signing_alg: Optional(oneOf(...validJWA)),
|
|
39
|
+
request_object_encryption_alg: Optional(oneOf(...validJWA)),
|
|
40
|
+
request_object_encryption_enc: Optional(oneOf(...validJWA)),
|
|
41
|
+
token_endpoint_auth_method: Optional(oneOf(...validAuthMethods)),
|
|
42
|
+
token_endpoint_auth_signing_alg: Optional(oneOf(...validJWA)),
|
|
43
|
+
default_max_age: Optional(Number),
|
|
44
|
+
require_auth_time: Optional(Boolean),
|
|
45
|
+
default_acr_values: Optional([String]),
|
|
46
|
+
initiate_login_uri: Optional([validURL]),
|
|
47
|
+
request_uris: Optional([validURL])
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
assert(options, {
|
|
51
|
+
client: Optional(instanceOf(metro.client().constructor)),
|
|
52
|
+
registration_endpoint: validURL,
|
|
53
|
+
client_info: openid_client_metadata
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
7
57
|
_Note:_ This library was created as part of the [@muze-nl/metro](https://github.com/muze-nl/metro/) package initially, but has escaped its confines. In the rest of the documentation, when referring to 'middleware', we mean middleware modules for the metro http client in the browser.
|
|
8
58
|
|
|
9
59
|
## Installation
|
|
@@ -27,16 +77,16 @@ import { assert, enable, disable, Optional, Required, Recommended, oneOf, anyOf,
|
|
|
27
77
|
|
|
28
78
|
### Using a CDN like jsdelivr
|
|
29
79
|
```html
|
|
30
|
-
<script src="https://cdn.jsdelivr.net/npm/@muze-nl/assert@0.
|
|
80
|
+
<script src="https://cdn.jsdelivr.net/npm/@muze-nl/assert@0.3.4/dist/browser.js" crossorigin="anonymous"></script>
|
|
31
81
|
```
|
|
32
82
|
|
|
33
|
-
_Note_: jsdelivr.com doesn't calculate the integrity hash for you, I've used https://www.srihash.org here.
|
|
34
|
-
|
|
35
83
|
Using a CDN like this means that assert is loaded globally as window.assert.
|
|
36
84
|
|
|
37
85
|
## Usage
|
|
38
86
|
|
|
39
87
|
```javascript
|
|
88
|
+
import { assert, Optional, Required, not, validURL } from '@muze-nl/assert'
|
|
89
|
+
|
|
40
90
|
function myFunction(param1, param2) {
|
|
41
91
|
assert(param1, Required(validURL))
|
|
42
92
|
assert(param2, Optional(not(/foo.*/)))
|
|
@@ -47,7 +97,9 @@ function myFunction(param1, param2) {
|
|
|
47
97
|
When calling myFunction above, none of the assertions are actually checked, unless you enable assertion checking first, like this:
|
|
48
98
|
|
|
49
99
|
```javascript
|
|
50
|
-
|
|
100
|
+
import * as assert from '@muze-nl/assert'
|
|
101
|
+
|
|
102
|
+
assert.enable()
|
|
51
103
|
```
|
|
52
104
|
|
|
53
105
|
## Asserting preconditions
|
|
@@ -105,6 +157,5 @@ assert.enable()
|
|
|
105
157
|
|
|
106
158
|
Once the [`assert.enable()`](./docs/enable.md) function is called, now `assert.check()` will throw an error if any assertion fails. The error is also logged to the console.
|
|
107
159
|
|
|
108
|
-
|
|
109
|
-
[project-stage-badge: Experimental]: https://img.shields.io/badge/Project%20Stage-Experimental-yellow.svg
|
|
160
|
+
[project-stage-badge: Development]: https://img.shields.io/badge/Project%20Stage-Development-yellowgreen.svg
|
|
110
161
|
[project-stage-page]: https://blog.pother.ca/project-stages/
|
package/package.json
CHANGED
package/src/assert.mjs
CHANGED
|
@@ -77,7 +77,7 @@ export function Required(pattern) {
|
|
|
77
77
|
export function Recommended(pattern) {
|
|
78
78
|
return function _Recommended(data, root, path) {
|
|
79
79
|
if (data==null || typeof data == 'undefined') {
|
|
80
|
-
|
|
80
|
+
warn('data does not contain recommended value', data, pattern, path)
|
|
81
81
|
return false
|
|
82
82
|
} else {
|
|
83
83
|
return fails(data, pattern, root, path)
|
|
@@ -293,13 +293,17 @@ export function fails(data, pattern, root, path='') {
|
|
|
293
293
|
*/
|
|
294
294
|
export function error(message, found, expected, path, problems) {
|
|
295
295
|
let result = {
|
|
296
|
+
path,
|
|
296
297
|
message,
|
|
297
298
|
found,
|
|
298
|
-
expected
|
|
299
|
-
path
|
|
299
|
+
expected
|
|
300
300
|
}
|
|
301
301
|
if (problems) {
|
|
302
302
|
result.problems = problems
|
|
303
303
|
}
|
|
304
304
|
return result
|
|
305
305
|
}
|
|
306
|
+
|
|
307
|
+
export function warn(message, data, pattern, path) {
|
|
308
|
+
console.warn('🅰️ Assert: '+path, message, pattern, data)
|
|
309
|
+
}
|