n4s 3.0.0 → 4.0.0-dev-1aae50

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 (64) hide show
  1. package/CHANGELOG.md +129 -0
  2. package/LICENSE +1 -2
  3. package/README.md +2 -5
  4. package/compose/package.json +7 -0
  5. package/compounds/package.json +7 -0
  6. package/dist/cjs/compose.development.js +139 -0
  7. package/dist/cjs/compose.js +7 -0
  8. package/dist/cjs/compose.production.js +1 -0
  9. package/dist/cjs/compounds.development.js +132 -0
  10. package/dist/cjs/compounds.js +7 -0
  11. package/dist/cjs/compounds.production.js +1 -0
  12. package/dist/cjs/n4s.development.js +602 -0
  13. package/dist/cjs/n4s.js +7 -0
  14. package/dist/cjs/n4s.production.js +1 -0
  15. package/dist/cjs/package.json +1 -0
  16. package/dist/cjs/schema.development.js +144 -0
  17. package/dist/cjs/schema.js +7 -0
  18. package/dist/cjs/schema.production.js +1 -0
  19. package/dist/es/compose.development.js +137 -0
  20. package/dist/es/compose.production.js +1 -0
  21. package/dist/es/compounds.development.js +130 -0
  22. package/dist/es/compounds.production.js +1 -0
  23. package/dist/es/n4s.development.js +597 -0
  24. package/dist/es/n4s.production.js +1 -0
  25. package/dist/es/package.json +1 -0
  26. package/dist/es/schema.development.js +140 -0
  27. package/dist/es/schema.production.js +1 -0
  28. package/dist/umd/compose.development.js +143 -0
  29. package/dist/umd/compose.production.js +1 -0
  30. package/dist/umd/compounds.development.js +136 -0
  31. package/dist/umd/compounds.production.js +1 -0
  32. package/dist/umd/n4s.development.js +606 -0
  33. package/dist/umd/n4s.production.js +1 -0
  34. package/dist/umd/schema.development.js +148 -0
  35. package/dist/umd/schema.production.js +1 -0
  36. package/docs/README.md +2 -5
  37. package/docs/_sidebar.md +1 -2
  38. package/docs/external.md +1 -28
  39. package/docs/rules.md +28 -0
  40. package/package.json +129 -42
  41. package/schema/package.json +7 -0
  42. package/tsconfig.json +8 -0
  43. package/types/compose.d.ts +134 -0
  44. package/types/compounds.d.ts +146 -0
  45. package/types/n4s.d.ts +167 -0
  46. package/types/schema.d.ts +151 -0
  47. package/config/jest/jest.setup.js +0 -14
  48. package/config/rollup/enforce.js +0 -8
  49. package/config/rollup/rollup.config.js +0 -3
  50. package/docs/compound.md +0 -187
  51. package/docs/custom.md +0 -52
  52. package/docs/template.md +0 -53
  53. package/esm/n4s.mjs.development.js +0 -1101
  54. package/esm/n4s.mjs.production.js +0 -1101
  55. package/esm/n4s.mjs.production.min.js +0 -1
  56. package/esm/package.json +0 -1
  57. package/jest.config.js +0 -3
  58. package/n4s.cjs.development.js +0 -1103
  59. package/n4s.cjs.production.js +0 -1103
  60. package/n4s.cjs.production.min.js +0 -1
  61. package/n4s.js +0 -7
  62. package/n4s.umd.development.js +0 -1109
  63. package/n4s.umd.production.js +0 -1192
  64. package/n4s.umd.production.min.js +0 -1
@@ -1,1192 +0,0 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3
- typeof define === 'function' && define.amd ? define(factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.n4s = factory());
5
- }(this, (function () { 'use strict';
6
-
7
- function _unsupportedIterableToArray(o, minLen) {
8
- if (!o) return;
9
- if (typeof o === "string") return _arrayLikeToArray(o, minLen);
10
- var n = Object.prototype.toString.call(o).slice(8, -1);
11
- if (n === "Object" && o.constructor) n = o.constructor.name;
12
- if (n === "Map" || n === "Set") return Array.from(o);
13
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
14
- }
15
-
16
- function _arrayLikeToArray(arr, len) {
17
- if (len == null || len > arr.length) len = arr.length;
18
-
19
- for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
20
-
21
- return arr2;
22
- }
23
-
24
- function _createForOfIteratorHelperLoose(o, allowArrayLike) {
25
- var it;
26
-
27
- if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
28
- if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
29
- if (it) o = it;
30
- var i = 0;
31
- return function () {
32
- if (i >= o.length) return {
33
- done: true
34
- };
35
- return {
36
- done: false,
37
- value: o[i++]
38
- };
39
- };
40
- }
41
-
42
- throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
43
- }
44
-
45
- it = o[Symbol.iterator]();
46
- return it.next.bind(it);
47
- }
48
-
49
- /**
50
- * Stores values and configuration passed down to compound rules.
51
- *
52
- * @param {Object} content
53
- */
54
- function EnforceContext(content) {
55
- Object.assign(this, content);
56
- }
57
- /**
58
- * Sets an EnforceContext config `failFast`
59
- *
60
- * @param {Boolean} failFast
61
- * @return {EnforceContext}
62
- */
63
-
64
- EnforceContext.prototype.setFailFast = function (failFast) {
65
- this.failFast = !!failFast;
66
- return this;
67
- };
68
- /**
69
- * Extracts the literal value from an EnforceContext object
70
- * @param {*} value
71
- * @return {*}
72
- */
73
-
74
-
75
- EnforceContext.unwrap = function unwrap(value) {
76
- return EnforceContext.is(value) ? value.value : value;
77
- };
78
- /**
79
- * Wraps a literal value within a context.
80
- * @param {*} value
81
- * @return {EnforceContext}
82
- */
83
-
84
-
85
- EnforceContext.wrap = function wrap(value) {
86
- return EnforceContext.is(value) ? value : new EnforceContext({
87
- value: value
88
- });
89
- };
90
- /**
91
- * Checks whether a given value is an EnforceContext instance
92
- *
93
- * @param {*} value
94
- * @returns {boolean}
95
- */
96
-
97
-
98
- EnforceContext.is = function is(value) {
99
- return value instanceof EnforceContext;
100
- };
101
-
102
- /**
103
- * A safe hasOwnProperty access
104
- */
105
- function hasOwnProperty(obj, key) {
106
- return Object.prototype.hasOwnProperty.call(obj, key);
107
- }
108
-
109
- function bindNot(fn) {
110
- return function () {
111
- return !fn.apply(this, arguments);
112
- };
113
- }
114
-
115
- function isBoolean(value) {
116
- return !!value === value;
117
- }
118
-
119
- var isNotBoolean = bindNot(isBoolean);
120
-
121
- function isNumeric(value) {
122
- var result = !isNaN(parseFloat(value)) && !isNaN(Number(value)) && isFinite(value);
123
- return Boolean(result);
124
- }
125
- var isNotNumeric = bindNot(isNumeric);
126
-
127
- function lengthEquals(value, arg1) {
128
- return value.length === Number(arg1);
129
- }
130
- var lengthNotEquals = bindNot(lengthEquals);
131
-
132
- function isEmpty(value) {
133
- if (!value) {
134
- return true;
135
- } else if (isNumeric(value)) {
136
- return value === 0;
137
- } else if (hasOwnProperty(value, 'length')) {
138
- return lengthEquals(value, 0);
139
- } else if (typeof value === 'object') {
140
- return lengthEquals(Object.keys(value), 0);
141
- }
142
-
143
- return true;
144
- }
145
- var isNotEmpty = bindNot(isEmpty);
146
-
147
- function isUndefined(value) {
148
- return value === undefined;
149
- }
150
- var isNotUndefined = bindNot(isUndefined);
151
-
152
- var HAS_WARNINGS = 'hasWarnings';
153
- var HAS_ERRORS = 'hasErrors';
154
-
155
- /**
156
- * Stores a rule result in an easy to inspect and manipulate structure.
157
- *
158
- * @param {boolean|RuleResult} ruleRunResult
159
- */
160
-
161
- function RuleResult(ruleRunResult) {
162
- if (isUndefined(ruleRunResult)) {
163
- return;
164
- }
165
-
166
- if (isBoolean(ruleRunResult)) {
167
- this.setFailed(!ruleRunResult);
168
- } else {
169
- this.extend(ruleRunResult);
170
- }
171
- }
172
- /**
173
- * Determines whether a given value is a RuleResult instance
174
- * @param {*} res
175
- * @return {boolean}
176
- */
177
-
178
- RuleResult.is = function (res) {
179
- return res instanceof RuleResult;
180
- };
181
- /**
182
- * Marks the current result object as an array
183
- */
184
-
185
-
186
- RuleResult.prototype.asArray = function () {
187
- this.isArray = true;
188
- return this;
189
- };
190
- /**
191
- * @param {string} key
192
- * @param {value} value
193
- * @return {RuleResult} current instance
194
- */
195
-
196
-
197
- RuleResult.prototype.setAttribute = function (key, value) {
198
- this[key] = value;
199
- return this;
200
- };
201
- /**
202
- * @param {boolean} failed
203
- * @return {RuleResult} current instance
204
- */
205
-
206
-
207
- RuleResult.prototype.setFailed = function (failed) {
208
- this.setAttribute(this.warn ? HAS_WARNINGS : HAS_ERRORS, failed);
209
- return this.setAttribute('failed', failed);
210
- };
211
- /**
212
- * Adds a nested result object
213
- *
214
- * @param {string} key
215
- * @param {RuleResult} child
216
- */
217
-
218
-
219
- RuleResult.prototype.setChild = function (key, child) {
220
- var isWarning = this[HAS_WARNINGS] || child[HAS_WARNINGS] || child.warn || this.warn;
221
- this.setAttribute(HAS_WARNINGS, isWarning && child.failed || false);
222
- this.setAttribute(HAS_ERRORS, this[HAS_ERRORS] || child[HAS_ERRORS] || !isWarning && child.failed || false);
223
- this.setFailed(this.failed || child.failed);
224
- this.children = this.children || {};
225
- this.children[key] = child;
226
- return child;
227
- };
228
- /**
229
- * Retrieves a child by its key
230
- *
231
- * @param {string} key
232
- * @return {RuleResult|undefined}
233
- */
234
-
235
-
236
- RuleResult.prototype.getChild = function (key) {
237
- return (this.children || {})[key];
238
- };
239
- /**
240
- * Extends current instance with a new provided result
241
- * @param {Boolean|RuleResult} newRes
242
- */
243
-
244
-
245
- RuleResult.prototype.extend = function (newRes) {
246
- var res = RuleResult.is(newRes) ? newRes : new RuleResult().setAttribute('warn', !!this.warn).setFailed(!newRes);
247
- var failed = this.failed || res.failed;
248
- var children = mergeChildren(res, this).children;
249
- Object.assign(this, res);
250
-
251
- if (!isEmpty(children)) {
252
- this.children = children;
253
- }
254
-
255
- this.setFailed(failed);
256
- this.setAttribute(HAS_WARNINGS, !!(this[HAS_WARNINGS] || res[HAS_WARNINGS]));
257
- this.setAttribute(HAS_ERRORS, !!(this[HAS_ERRORS] || res[HAS_ERRORS]));
258
- };
259
-
260
- Object.defineProperty(RuleResult.prototype, 'pass', {
261
- get: function get() {
262
- return !this.failed;
263
- }
264
- });
265
- /**
266
- * Deeply merge the nested children of compound rules
267
- *
268
- * @param {?RuleResult} base
269
- * @param {?RuleResult} add
270
- * @return {RuleResult}
271
- */
272
-
273
- function mergeChildren(base, add) {
274
- var isRuleResultBase = RuleResult.is(base);
275
- var isRuleResultAdd = RuleResult.is(add); // If both base and add are result objects
276
-
277
- if (isRuleResultBase && isRuleResultAdd) {
278
- // Use failed if either is failing
279
- base.setFailed(base.failed || add.failed); // If neither has a children object, or the children object is
280
-
281
- if (isEmpty(base.children) && isEmpty(add.children)) {
282
- return base;
283
- } // If both have a children object
284
-
285
-
286
- if (base.children && add.children) {
287
- // Merge all the "right side" children back to base
288
- for (var key in base.children) {
289
- mergeChildren(base.children[key], add.children[key]);
290
- } // If a child exists in "add" but not in "base", just copy the child as is
291
-
292
-
293
- for (var _key in add.children) {
294
- if (!hasOwnProperty(base.children, _key)) {
295
- base.setChild(_key, add.children[_key]);
296
- }
297
- } // Return the modified base object
298
-
299
-
300
- return base; // If base has no children (but add does)
301
- } else if (!base.children) {
302
- // Use add's children
303
- base.children = add.children; // If add has no children
304
- } else if (!add.children) {
305
- // return base as is
306
- return base;
307
- } // If only base is `RuleResult`
308
-
309
- } else if (isRuleResultBase) {
310
- // Return base as is
311
- return base; // If only add is RuleResult
312
- } else if (isRuleResultAdd) {
313
- // Return add as is
314
- return add;
315
- } // That's a weird case. Let's fail. Very unlikely.
316
-
317
-
318
- return new RuleResult(false);
319
- }
320
-
321
- var RUN_RULE = 'run';
322
- var TEST_RULE = 'test';
323
- var MODE_ALL = 'all';
324
- var MODE_ONE = 'one';
325
- var MODE_ANY = 'any';
326
-
327
- function isFunction (v) {
328
- return typeof v === 'function';
329
- }
330
-
331
- function asArray(possibleArg) {
332
- return [].concat(possibleArg);
333
- }
334
-
335
- /**
336
- * Determines whether we should bail out of an enforcement.
337
- *
338
- * @param {EnforceContext} ctx
339
- * @param {RuleResult} result
340
- */
341
-
342
- function shouldFailFast(ctx, result) {
343
- if (result.pass || result.warn) {
344
- return false;
345
- }
346
-
347
- return !!EnforceContext.is(ctx) && ctx.failFast;
348
- }
349
-
350
- /**
351
- * Runs multiple enforce rules that are passed to compounds.
352
- * Example: enforce.allOf(enforce.ruleOne(), enforce.ruleTwo().ruleThree())
353
- *
354
- * @param {{run: Function}[]} ruleGroups
355
- * @param {*} value
356
- * @return {RuleResult}
357
- */
358
-
359
- function runLazyRules(ruleGroups, value) {
360
- var result = new RuleResult(true);
361
-
362
- for (var _iterator = _createForOfIteratorHelperLoose(asArray(ruleGroups)), _step; !(_step = _iterator()).done;) {
363
- var chain = _step.value;
364
-
365
- if (shouldFailFast(value, result)) {
366
- break;
367
- }
368
-
369
- result.extend(runLazyRule(chain, value));
370
- }
371
-
372
- return result;
373
- }
374
- /**
375
- * Runs a single lazy rule
376
- *
377
- * @param {{run: Function}} ruleGroup
378
- * @param {*} value
379
- * @return {boolean|RuleResult}
380
- */
381
-
382
- function runLazyRule(ruleGroup, value) {
383
- return ruleGroup[RUN_RULE](value);
384
- }
385
-
386
- /**
387
- * Runs chains of rules
388
- *
389
- * @param {EnforceContext} value
390
- * @param {[{test: Function, run: Function}]} rules
391
- * @param {RuleResult} options
392
- */
393
-
394
- function runCompoundChain(value, rules, options) {
395
- var result = new RuleResult(true);
396
-
397
- if (isEmpty(rules)) {
398
- result.setFailed(true);
399
- }
400
-
401
- var failedResults = [];
402
- var count = 0;
403
-
404
- for (var _iterator = _createForOfIteratorHelperLoose(rules), _step; !(_step = _iterator()).done;) {
405
- var chain = _step.value;
406
- // Inner result for each iteration
407
- var currentResult = runLazyRule(chain, value);
408
- var pass = currentResult.pass;
409
-
410
- if (pass) {
411
- count++;
412
- } else {
413
- failedResults.push(currentResult);
414
- }
415
-
416
- if (options) {
417
- // "anyOf" is a special case.
418
- // It shouldn't extend with failed results,
419
- // that's why we continue
420
- if (options.mode === MODE_ANY) {
421
- if (pass) {
422
- result.extend(currentResult);
423
- break;
424
- }
425
-
426
- continue;
427
- }
428
-
429
- result.extend(currentResult); // MODE_ALL: All must pass.
430
- // If one failed, exit.
431
-
432
- if (options.mode === MODE_ALL) {
433
- if (!pass) {
434
- break;
435
- }
436
- } // MODE_ONE: only one must pass.
437
- // If more than one passed, exit.
438
-
439
-
440
- if (options.mode === MODE_ONE) {
441
- result.setFailed(count !== 1);
442
-
443
- if (count > 1) {
444
- break;
445
- }
446
- }
447
- } else {
448
- result.extend(currentResult);
449
-
450
- if (pass) {
451
- break;
452
- }
453
- }
454
- }
455
-
456
- if (result.pass && count === 0) {
457
- result.setFailed(true); // In some cases we do not want to extend failures, for example - in ANY
458
- // when there is a valid response, so we do it before returning
459
-
460
- failedResults.forEach(function (failedResult) {
461
- return result.extend(failedResult);
462
- });
463
- }
464
-
465
- return result;
466
- }
467
-
468
- function setFnName(fn, value) {
469
- return Object.defineProperty(fn, 'name', {
470
- value: value
471
- });
472
- }
473
-
474
- /**
475
- * ES5 Transpilation increases the size of spread arguments by a lot.
476
- * Wraps a function and passes its spread params as an array.
477
- *
478
- * @param {Function} cb
479
- * @param {String} [fnName]
480
- * @return {Function}
481
- */
482
-
483
- function withArgs(cb, fnName) {
484
- return setFnName(function () {
485
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
486
- args[_key] = arguments[_key];
487
- }
488
-
489
- var right = args.splice(cb.length - 1);
490
- return cb.apply(null, args.concat([right]));
491
- }, fnName || cb.name);
492
- }
493
-
494
- /**
495
- * Runs a chaen of rules, making sure that all assertions pass
496
- *
497
- * @param {EnforceContext} value
498
- * @param {[{test: Function, run: Function}]} ruleChains
499
- * @return {RuleResult}
500
- */
501
-
502
- function allOf(value, rules) {
503
- return runCompoundChain(value, rules, {
504
- mode: MODE_ALL
505
- });
506
- }
507
-
508
- var allOf$1 = withArgs(allOf);
509
-
510
- /**
511
- * Runs chains of rules, making sure
512
- * that at least one assertion passes
513
- *
514
- * @param {EnforceContext} value
515
- * @param {[{test: Function, run: Function}]} ruleChains
516
- * @return {RuleResult}
517
- */
518
-
519
- function anyOf(value, ruleChains) {
520
- return runCompoundChain(value, ruleChains, {
521
- mode: MODE_ANY
522
- });
523
- }
524
-
525
- var anyOf$1 = withArgs(anyOf);
526
-
527
- function isArray(value) {
528
- return Boolean(Array.isArray(value));
529
- }
530
- var isNotArray = bindNot(isArray);
531
-
532
- /**
533
- * Asserts that each element in an array passes
534
- * at least one of the provided rule chain
535
- *
536
- * @param {EnforceContext} value
537
- * @param {[{test: Function, run: Function}]} ruleChains
538
- * @return {RuleResult}
539
- */
540
-
541
- function isArrayOf(value, ruleChains) {
542
- var plainValue = EnforceContext.unwrap(value);
543
- var result = new RuleResult(true).asArray(); // Fails if current value is not an array
544
-
545
- if (isNotArray(plainValue)) {
546
- return result.setFailed(true);
547
- }
548
-
549
- for (var i = 0; i < plainValue.length; i++) {
550
- // Set result per each item in the array|
551
- result.setChild(i, runCompoundChain(EnforceContext.wrap(plainValue[i]).setFailFast(value.failFast), ruleChains, {
552
- mode: MODE_ANY
553
- }));
554
- }
555
-
556
- return result;
557
- }
558
-
559
- var isArrayOf$1 = withArgs(isArrayOf);
560
-
561
- /**
562
- * @param {EnforceContext} value
563
- * @param {[{test: Function, run: Function}]} ruleChains
564
- * @return {RuleResult}
565
- */
566
-
567
- function oneOf(value, rules) {
568
- return runCompoundChain(value, rules, {
569
- mode: MODE_ONE
570
- });
571
- }
572
-
573
- var oneOf$1 = withArgs(oneOf);
574
-
575
- function isNull(value) {
576
- return value === null;
577
- }
578
- var isNotNull = bindNot(isNull);
579
-
580
- /**
581
- * @param {Array} ObjectEntry Object and key leading to current value
582
- * @param {Function[]} rules Rules to validate the value with
583
- */
584
-
585
- function optional(inputObject, ruleGroups) {
586
- var obj = inputObject.obj,
587
- key = inputObject.key; // If current value is not defined, undefined or null
588
- // Pass without further assertions
589
-
590
- if (!hasOwnProperty(obj, key) || isUndefined(obj[key] || isNull(obj[key]))) {
591
- return true;
592
- } // Pass if exists but no assertions
593
-
594
-
595
- if (isEmpty(ruleGroups)) {
596
- return true;
597
- } // Run chain with `all` mode
598
-
599
-
600
- return runCompoundChain(obj[key], ruleGroups, {
601
- mode: MODE_ALL
602
- });
603
- }
604
-
605
- var optional$1 = withArgs(optional);
606
-
607
- /**
608
- * @param {EnforceContext} inputObject Data object that gets validated
609
- * @param {Object} shapeObj Shape definition
610
- * @param {Object} options
611
- * @param {boolean} options.loose Ignore extra keys not defined in shapeObj
612
- */
613
-
614
- function shape(inputObject, shapeObj, options) {
615
- // Extract the object from context
616
- var obj = EnforceContext.unwrap(inputObject); // Create a new result object
617
-
618
- var result = new RuleResult(true); // Iterate over the shape keys
619
-
620
- for (var key in shapeObj) {
621
- var current = shapeObj[key];
622
- var value = obj[key];
623
-
624
- if (shouldFailFast(value, result)) {
625
- break;
626
- } // Set each key in the result object
627
-
628
-
629
- result.setChild(key, runLazyRule(current, new EnforceContext({
630
- value: value,
631
- obj: obj,
632
- key: key
633
- }).setFailFast(inputObject.failFast)));
634
- } // If mode is not loose
635
-
636
-
637
- if (!(options || {}).loose) {
638
- // Check that each key in the input object exists in the shape
639
- for (var _key in obj) {
640
- if (!hasOwnProperty(shapeObj, _key)) {
641
- return result.setFailed(true);
642
- }
643
- }
644
- }
645
-
646
- return result;
647
- }
648
- var loose = function loose(obj, shapeObj) {
649
- return shape(obj, shapeObj, {
650
- loose: true
651
- });
652
- };
653
-
654
- var compounds = {
655
- allOf: allOf$1,
656
- anyOf: anyOf$1,
657
- isArrayOf: isArrayOf$1,
658
- loose: loose,
659
- oneOf: oneOf$1,
660
- optional: optional$1,
661
- shape: shape
662
- };
663
-
664
- /**
665
- * Takes a value. If it is a function, runs it and returns the result.
666
- * Otherwise, returns the value as is.
667
- *
668
- * @param {Function|*} value Value to return. Run it if a function.
669
- * @param {Any[]} [args] Arguments to pass if a function
670
- * @return {Any}
671
- */
672
-
673
- function optionalFunctionValue(value, args) {
674
- return isFunction(value) ? value.apply(null, args) : value;
675
- }
676
-
677
- function message(value, msg) {
678
- return optionalFunctionValue(msg, [EnforceContext.unwrap(value)]);
679
- }
680
-
681
- function warn(_, isWarn) {
682
- if (isWarn === void 0) {
683
- isWarn = true;
684
- }
685
-
686
- return isWarn;
687
- }
688
-
689
- var ruleMeta = {
690
- warn: warn,
691
- message: message
692
- };
693
-
694
- function isString (v) {
695
- return String(v) === v;
696
- }
697
-
698
- function endsWith(value, arg1) {
699
- return isString(value) && isString(arg1) && value.endsWith(arg1);
700
- }
701
- var doesNotEndWith = bindNot(endsWith);
702
-
703
- function equals(value, arg1) {
704
- return value === arg1;
705
- }
706
- var notEquals = bindNot(equals);
707
-
708
- function greaterThan(value, arg1) {
709
- return isNumeric(value) && isNumeric(arg1) && Number(value) > Number(arg1);
710
- }
711
-
712
- function greaterThanOrEquals(value, arg1) {
713
- return isNumeric(value) && isNumeric(arg1) && Number(value) >= Number(arg1);
714
- }
715
-
716
- function inside(value, arg1) {
717
- if (Array.isArray(arg1) && /^[s|n|b]/.test(typeof value)) {
718
- return arg1.indexOf(value) !== -1;
719
- } // both value and arg1 are strings
720
-
721
-
722
- if (isString(arg1) && isString(value)) {
723
- return arg1.indexOf(value) !== -1;
724
- }
725
-
726
- return false;
727
- }
728
- var notInside = bindNot(inside);
729
-
730
- function lessThanOrEquals(value, arg1) {
731
- return isNumeric(value) && isNumeric(arg1) && Number(value) <= Number(arg1);
732
- }
733
-
734
- function isBetween(value, min, max) {
735
- return greaterThanOrEquals(value, min) && lessThanOrEquals(value, max);
736
- }
737
- var isNotBetween = bindNot(isBetween);
738
-
739
- /**
740
- * Validates that a given value is an even number
741
- * @param {Number|String} value Value to be validated
742
- * @return {Boolean}
743
- */
744
-
745
- var isEven = function isEven(value) {
746
- if (isNumeric(value)) {
747
- return value % 2 === 0;
748
- }
749
-
750
- return false;
751
- };
752
-
753
- function isNaN$1(value) {
754
- return Number.isNaN(value);
755
- }
756
- var isNotNaN = bindNot(isNaN$1);
757
-
758
- function isNegative(value) {
759
- if (isNumeric(value)) {
760
- return Number(value) < 0;
761
- }
762
-
763
- return false;
764
- }
765
- var isPositive = bindNot(isNegative);
766
-
767
- function isNumber(value) {
768
- return Boolean(typeof value === 'number');
769
- }
770
- var isNotNumber = bindNot(isNumber);
771
-
772
- /**
773
- * Validates that a given value is an odd number
774
- * @param {Number|String} value Value to be validated
775
- * @return {Boolean}
776
- */
777
-
778
- var isOdd = function isOdd(value) {
779
- if (isNumeric(value)) {
780
- return value % 2 !== 0;
781
- }
782
-
783
- return false;
784
- };
785
-
786
- var isNotString = bindNot(isString);
787
-
788
- function isTruthy(value) {
789
- return !!value;
790
- }
791
- var isFalsy = bindNot(isTruthy);
792
-
793
- function lessThan(value, arg1) {
794
- return isNumeric(value) && isNumeric(arg1) && Number(value) < Number(arg1);
795
- }
796
-
797
- function longerThan(value, arg1) {
798
- return value.length > Number(arg1);
799
- }
800
-
801
- function longerThanOrEquals(value, arg1) {
802
- return value.length >= Number(arg1);
803
- }
804
-
805
- function matches(value, regex) {
806
- if (regex instanceof RegExp) {
807
- return regex.test(value);
808
- } else if (isString(regex)) {
809
- return new RegExp(regex).test(value);
810
- } else {
811
- return false;
812
- }
813
- }
814
- var notMatches = bindNot(matches);
815
-
816
- function numberEquals(value, arg1) {
817
- return isNumeric(value) && isNumeric(arg1) && Number(value) === Number(arg1);
818
- }
819
- var numberNotEquals = bindNot(numberEquals);
820
-
821
- function shorterThan(value, arg1) {
822
- return value.length < Number(arg1);
823
- }
824
-
825
- function shorterThanOrEquals(value, arg1) {
826
- return value.length <= Number(arg1);
827
- }
828
-
829
- function startsWith(value, arg1) {
830
- return isString(value) && isString(arg1) && value.startsWith(arg1);
831
- }
832
- var doesNotStartWith = bindNot(startsWith);
833
-
834
- function rules() {
835
- return {
836
- doesNotEndWith: doesNotEndWith,
837
- doesNotStartWith: doesNotStartWith,
838
- endsWith: endsWith,
839
- equals: equals,
840
- greaterThan: greaterThan,
841
- greaterThanOrEquals: greaterThanOrEquals,
842
- gt: greaterThan,
843
- gte: greaterThanOrEquals,
844
- inside: inside,
845
- isArray: isArray,
846
- isBetween: isBetween,
847
- isBoolean: isBoolean,
848
- isEmpty: isEmpty,
849
- isEven: isEven,
850
- isFalsy: isFalsy,
851
- isNaN: isNaN$1,
852
- isNegative: isNegative,
853
- isNotArray: isNotArray,
854
- isNotBetween: isNotBetween,
855
- isNotBoolean: isNotBoolean,
856
- isNotEmpty: isNotEmpty,
857
- isNotNaN: isNotNaN,
858
- isNotNull: isNotNull,
859
- isNotNumber: isNotNumber,
860
- isNotNumeric: isNotNumeric,
861
- isNotString: isNotString,
862
- isNotUndefined: isNotUndefined,
863
- isNull: isNull,
864
- isNumber: isNumber,
865
- isNumeric: isNumeric,
866
- isOdd: isOdd,
867
- isPositive: isPositive,
868
- isString: isString,
869
- isTruthy: isTruthy,
870
- isUndefined: isUndefined,
871
- lengthEquals: lengthEquals,
872
- lengthNotEquals: lengthNotEquals,
873
- lessThan: lessThan,
874
- lessThanOrEquals: lessThanOrEquals,
875
- longerThan: longerThan,
876
- longerThanOrEquals: longerThanOrEquals,
877
- lt: lessThan,
878
- lte: lessThanOrEquals,
879
- matches: matches,
880
- notEquals: notEquals,
881
- notInside: notInside,
882
- notMatches: notMatches,
883
- numberEquals: numberEquals,
884
- numberNotEquals: numberNotEquals,
885
- shorterThan: shorterThan,
886
- shorterThanOrEquals: shorterThanOrEquals,
887
- startsWith: startsWith
888
- };
889
- }
890
-
891
- var runtimeRules = Object.assign(rules(), compounds, ruleMeta);
892
-
893
- /**
894
- * Determines whether a given string is a name of a rule
895
- *
896
- * @param {string} name
897
- * @return {boolean}
898
- */
899
-
900
- var isRule = function isRule(name) {
901
- return hasOwnProperty(runtimeRules, name) && isFunction(runtimeRules[name]);
902
- };
903
-
904
- var GLOBAL_OBJECT = Function('return this')();
905
-
906
- var proxySupported = function proxySupported() {
907
- return isFunction(GLOBAL_OBJECT.Proxy);
908
- };
909
-
910
- function genRuleProxy(target, output) {
911
- if (proxySupported()) {
912
- return new Proxy(target, {
913
- get: function get(target, fnName) {
914
- // A faster bailout when we access `run` and `test`
915
- if (hasOwnProperty(target, fnName)) {
916
- return target[fnName];
917
- }
918
-
919
- if (isRule(fnName)) {
920
- return output(fnName);
921
- }
922
-
923
- return target[fnName];
924
- }
925
- });
926
- } else {
927
- var _loop = function _loop(fnName) {
928
- if (!isFunction(target[fnName])) {
929
- var _Object$definePropert;
930
-
931
- Object.defineProperties(target, (_Object$definePropert = {}, _Object$definePropert[fnName] = {
932
- get: function get() {
933
- return output(fnName);
934
- }
935
- }, _Object$definePropert));
936
- }
937
- };
938
-
939
- /**
940
- * This method is REALLY not recommended as it is slow and iterates over
941
- * all the rules for each direct enforce reference. We only use it as a
942
- * lightweight alternative for the much faster proxy interface
943
- */
944
- for (var fnName in runtimeRules) {
945
- _loop(fnName);
946
- }
947
-
948
- return target;
949
- }
950
- }
951
-
952
- /**
953
- * Determines whether a given rule is a compound.
954
- *
955
- * @param {Function} rule
956
- * @return {boolean}
957
- */
958
-
959
- function isCompound(rule) {
960
- return hasOwnProperty(compounds, rule.name);
961
- }
962
-
963
- /**
964
- * Creates a rule of lazily called rules.
965
- * Each rule gets added a `.run()` property
966
- * which runs all the accumulated rules in
967
- * the chain against the supplied value
968
- *
969
- * @param {string} ruleName
970
- * @return {{run: Function}}
971
- */
972
-
973
- function bindLazyRule(ruleName) {
974
- var registeredRules = []; // Chained rules
975
-
976
- var meta = []; // Meta properties to add onto the rule context
977
- // Appends a function to the registeredRules array.
978
- // It gets called every time the consumer usess chaining
979
- // so, for example - enforce.isArray() <- this calles addFn
980
-
981
- var addFn = function addFn(ruleName) {
982
- return withArgs(function (args) {
983
- var rule = runtimeRules[ruleName]; // Add a meta function
984
-
985
- if (ruleMeta[rule.name] === rule) {
986
- meta.push(function (value, ruleResult) {
987
- ruleResult.setAttribute(rule.name, rule(value, args[0]));
988
- });
989
- } else {
990
- // Register a rule
991
- registeredRules.push(setFnName(function (value) {
992
- return rule.apply(null, [// If the rule is compound - wraps the value with context
993
- // Otherwise - unwraps it
994
- isCompound(rule) ? EnforceContext.wrap(value) : EnforceContext.unwrap(value)].concat(args));
995
- }, ruleName));
996
- } // set addFn as the proxy handler
997
-
998
-
999
- var returnvalue = genRuleProxy({}, addFn);
1000
-
1001
- returnvalue[RUN_RULE] = function (value) {
1002
- var result = new RuleResult(true); // Run meta chains
1003
-
1004
- meta.forEach(function (fn) {
1005
- fn(value, result);
1006
- }); // Iterate over all the registered rules
1007
- // This runs the function that's inside `addFn`
1008
-
1009
- for (var _iterator = _createForOfIteratorHelperLoose(registeredRules), _step; !(_step = _iterator()).done;) {
1010
- var fn = _step.value;
1011
-
1012
- try {
1013
- result.extend(fn(value)); // If a chained rule fails, exit. We failed.
1014
-
1015
- if (!result.pass) {
1016
- break;
1017
- }
1018
- } catch (e) {
1019
- result.setFailed(true);
1020
- break;
1021
- }
1022
- }
1023
-
1024
- return result;
1025
- };
1026
-
1027
- returnvalue[TEST_RULE] = function (value) {
1028
- return returnvalue[RUN_RULE](EnforceContext.wrap(value).setFailFast(true)).pass;
1029
- };
1030
-
1031
- return returnvalue;
1032
- }, ruleName);
1033
- }; // Returns the initial rule in the chain
1034
-
1035
-
1036
- return addFn(ruleName);
1037
- }
1038
-
1039
- function bindExtend(enforce, Enforce) {
1040
- enforce.extend = function (customRules) {
1041
- Object.assign(runtimeRules, customRules);
1042
-
1043
- if (!proxySupported()) {
1044
- genRuleProxy(Enforce, bindLazyRule);
1045
- }
1046
-
1047
- return enforce;
1048
- };
1049
- }
1050
-
1051
- /**
1052
- * Throws a timed out error.
1053
- * @param {String} message Error message to display.
1054
- * @param {Error} [type] Alternative Error type.
1055
- */
1056
- var throwError = function throwError(message, type) {
1057
- if (type === void 0) {
1058
- type = Error;
1059
- }
1060
-
1061
- throw new type("[" + "n4s" + "]: " + message);
1062
- };
1063
-
1064
- function validateResult(result, rule) {
1065
- // if result is boolean, or if result.pass is boolean
1066
- if (isBoolean(result) || result && isBoolean(result.pass)) {
1067
- return;
1068
- }
1069
-
1070
- throwError( rule.name + 'wrong return value');
1071
- } // for easier testing and mocking
1072
-
1073
- function getDefaultResult(value, rule) {
1074
- return {
1075
- message: formatResultMessage(rule, "invalid " + typeof value + " value")
1076
- };
1077
- }
1078
- function formatResultMessage(rule, msg) {
1079
- return "[" + "n4s" + "]:" + rule.name + " " + msg;
1080
- }
1081
- /**
1082
- * Transform the result of a rule into a standard format
1083
- * @param {string} interfaceName to be used in the messages
1084
- * @param {*} result of the rule
1085
- * @param {Object} options
1086
- * @param {function} options.rule
1087
- * @param {*} options.value
1088
- * @returns {Object} result
1089
- * @returns {string} result.message
1090
- * @returns {boolean} result.pass indicates if the test passes or not
1091
- */
1092
-
1093
- function transformResult(result, _ref) {
1094
- var rule = _ref.rule,
1095
- value = _ref.value;
1096
- var defaultResult = getDefaultResult(value, rule);
1097
- validateResult(result, rule); // if result is boolean
1098
-
1099
- if (isBoolean(result)) {
1100
- return defaultResult.pass = result, defaultResult;
1101
- } else {
1102
- defaultResult.pass = result.pass;
1103
-
1104
- if (result.message) {
1105
- defaultResult.message = formatResultMessage(rule, optionalFunctionValue(result.message));
1106
- }
1107
-
1108
- return defaultResult;
1109
- }
1110
- }
1111
-
1112
- /**
1113
- * Run a single rule against enforced value (e.g. `isNumber()`)
1114
- *
1115
- * @param {Function} rule - rule to run
1116
- * @param {Any} value
1117
- * @param {Array} args list of arguments sent from consumer
1118
- * @throws
1119
- */
1120
-
1121
- function runner(rule, value, args) {
1122
- if (args === void 0) {
1123
- args = [];
1124
- }
1125
-
1126
- var result;
1127
- var isCompoundRule = isCompound(rule);
1128
- var ruleValue = isCompoundRule ? EnforceContext.wrap(value).setFailFast(true) : EnforceContext.unwrap(value);
1129
- result = rule.apply(null, [ruleValue].concat(args));
1130
-
1131
- if (!isCompoundRule) {
1132
- result = transformResult(result, {
1133
- rule: rule,
1134
- value: value
1135
- });
1136
- }
1137
-
1138
- if (!result.pass) {
1139
- throw new Error(result.message);
1140
- }
1141
- }
1142
-
1143
- /**
1144
- * Adds `template` property to enforce.
1145
- *
1146
- * @param {Function} enforce
1147
- */
1148
-
1149
- function bindTemplate(enforce) {
1150
- enforce.template = withArgs(function (rules) {
1151
- var template = function template(value) {
1152
- runner(runLazyRules.bind(null, rules), value);
1153
- var proxy = genRuleProxy({}, function (ruleName) {
1154
- return withArgs(function (args) {
1155
- runner(runtimeRules[ruleName], value, args);
1156
- return proxy;
1157
- });
1158
- });
1159
- return proxy;
1160
- }; // `run` returns a deep ResultObject
1161
-
1162
-
1163
- template[RUN_RULE] = function (value) {
1164
- return runLazyRules(rules, value);
1165
- }; // `test` returns a boolean
1166
-
1167
-
1168
- template[TEST_RULE] = function (value) {
1169
- return runLazyRules(rules, EnforceContext.wrap(value).setFailFast(true)).pass;
1170
- };
1171
-
1172
- return template;
1173
- });
1174
- }
1175
-
1176
- var Enforce = function Enforce(value) {
1177
- var proxy = genRuleProxy({}, function (ruleName) {
1178
- return withArgs(function (args) {
1179
- runner(runtimeRules[ruleName], value, args);
1180
- return proxy;
1181
- });
1182
- });
1183
- return proxy;
1184
- };
1185
-
1186
- var enforce = genRuleProxy(Enforce, bindLazyRule);
1187
- bindExtend(enforce, Enforce);
1188
- bindTemplate(enforce);
1189
-
1190
- return enforce;
1191
-
1192
- })));