@muze-nl/assert 0.3.3 → 0.4.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/README.md CHANGED
@@ -1,9 +1,59 @@
1
- # Asserts
1
+ [![GitHub License](https://img.shields.io/github/license/muze-nl/assert)](https://github.com/muze-nl/assert/blob/main/LICENSE)
2
+ [![GitHub package.json version](https://img.shields.io/github/package-json/v/muze-nl/assert)]()
3
+ [![NPM Version](https://img.shields.io/npm/v/@muze-nl/assert)](https://www.npmjs.com/package/@muze-nl/assert)
4
+ [![npm bundle size](https://img.shields.io/bundlephobia/min/@muze-nl/assert)](https://www.npmjs.com/package/@muze-nl/assert)
5
+ [![Project stage: Development][project-stage-badge: Development]][project-stage-page]
2
6
 
3
- [![Project stage: Experimental][project-stage-badge: Experimental]][project-stage-page]
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.1.1/dist/browser.js" integrity="sha384-fqO47gvA1/4UGo0iokMu6ZXdBCkRUbNfXejhrmZrWpJaP+7FPaJqJ03Irhzl1ifk" crossorigin="anonymous"></script>
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
- enable()
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muze-nl/assert",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
4
4
  "description": "light optional assert library",
5
5
  "type": "module",
6
6
  "main": "src/assert.mjs",
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
- console.warn('data does not contain recommended value', data, pattern, path)
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
+ }