vest 4.0.1 → 4.0.2-dev-6e9534

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.
@@ -1,20 +1,311 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('n4s'), require('context')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'n4s', 'context'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vest = {}, global.n4s, global.context));
5
- }(this, (function (exports, n4s, context$1) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3
+ typeof define === 'function' && define.amd ? define(['exports'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vest = {}));
5
+ }(this, (function (exports) { 'use strict';
6
6
 
7
7
  var assign = Object.assign;
8
8
 
9
+ function isFunction(value) {
10
+ return typeof value === 'function';
11
+ }
12
+
13
+ function bindNot(fn) {
14
+ return function () {
15
+ var args = [];
16
+ for (var _i = 0; _i < arguments.length; _i++) {
17
+ args[_i] = arguments[_i];
18
+ }
19
+ return !fn.apply(void 0, args);
20
+ };
21
+ }
22
+
23
+ function isNull(value) {
24
+ return value === null;
25
+ }
26
+ var isNotNull = bindNot(isNull);
27
+
28
+ function isUndefined(value) {
29
+ return value === undefined;
30
+ }
31
+ var isNotUndefined = bindNot(isUndefined);
32
+
33
+ function isNullish(value) {
34
+ return isNull(value) || isUndefined(value);
35
+ }
36
+ var isNotNullish = bindNot(isNullish);
37
+
38
+ function isStringValue(v) {
39
+ return String(v) === v;
40
+ }
41
+
42
+ function endsWith(value, arg1) {
43
+ return isStringValue(value) && isStringValue(arg1) && value.endsWith(arg1);
44
+ }
45
+ var doesNotEndWith = bindNot(endsWith);
46
+
47
+ function equals(value, arg1) {
48
+ return value === arg1;
49
+ }
50
+ var notEquals = bindNot(equals);
51
+
52
+ function isNumeric(value) {
53
+ var str = String(value);
54
+ var num = Number(value);
55
+ var result = !isNaN(parseFloat(str)) && !isNaN(Number(value)) && isFinite(num);
56
+ return Boolean(result);
57
+ }
58
+ var isNotNumeric = bindNot(isNumeric);
59
+
60
+ function greaterThan(value, gt) {
61
+ return isNumeric(value) && isNumeric(gt) && Number(value) > Number(gt);
62
+ }
63
+
64
+ function greaterThanOrEquals(value, gte) {
65
+ return isNumeric(value) && isNumeric(gte) && Number(value) >= Number(gte);
66
+ }
67
+
68
+ // The module is named "isArrayValue" since it
69
+ // is conflicting with a nested npm dependency.
70
+ // We may need to revisit this in the future.
71
+ function isArray(value) {
72
+ return Boolean(Array.isArray(value));
73
+ }
74
+ var isNotArray = bindNot(isArray);
75
+
76
+ function inside(value, arg1) {
77
+ if (isArray(arg1)) {
78
+ return arg1.indexOf(value) !== -1;
79
+ }
80
+ // both value and arg1 are strings
81
+ if (isStringValue(arg1) && isStringValue(value)) {
82
+ return arg1.indexOf(value) !== -1;
83
+ }
84
+ return false;
85
+ }
86
+ var notInside = bindNot(inside);
87
+
88
+ function lessThanOrEquals(value, lte) {
89
+ return isNumeric(value) && isNumeric(lte) && Number(value) <= Number(lte);
90
+ }
91
+
92
+ function isBetween(value, min, max) {
93
+ return greaterThanOrEquals(value, min) && lessThanOrEquals(value, max);
94
+ }
95
+ var isNotBetween = bindNot(isBetween);
96
+
97
+ function isBlank(value) {
98
+ return isNullish(value) || (isStringValue(value) && !value.trim());
99
+ }
100
+ var isNotBlank = bindNot(isBlank);
101
+
102
+ function isBoolean(value) {
103
+ return !!value === value;
104
+ }
105
+
106
+ var isNotBoolean = bindNot(isBoolean);
107
+
9
108
  /**
10
- * @returns a unique numeric id.
109
+ * A safe hasOwnProperty access
11
110
  */
12
- var genId = (function (n) { return function () {
13
- return "" + n++;
14
- }; })(0);
111
+ function hasOwnProperty(obj, key) {
112
+ return Object.prototype.hasOwnProperty.call(obj, key);
113
+ }
15
114
 
16
- function isFunction(value) {
17
- return typeof value === 'function';
115
+ function isNumber(value) {
116
+ return Boolean(typeof value === 'number');
117
+ }
118
+ var isNotNumber = bindNot(isNumber);
119
+
120
+ function lengthEquals(value, arg1) {
121
+ return value.length === Number(arg1);
122
+ }
123
+ var lengthNotEquals = bindNot(lengthEquals);
124
+
125
+ function isEmpty(value) {
126
+ if (!value) {
127
+ return true;
128
+ }
129
+ else if (isNumber(value)) {
130
+ return value === 0;
131
+ }
132
+ else if (hasOwnProperty(value, 'length')) {
133
+ return lengthEquals(value, 0);
134
+ }
135
+ else if (typeof value === 'object') {
136
+ return lengthEquals(Object.keys(value), 0);
137
+ }
138
+ return true;
139
+ }
140
+ var isNotEmpty = bindNot(isEmpty);
141
+
142
+ /**
143
+ * Validates that a given value is an even number
144
+ */
145
+ var isEven = function (value) {
146
+ if (isNumeric(value)) {
147
+ return value % 2 === 0;
148
+ }
149
+ return false;
150
+ };
151
+
152
+ function isNaN$1(value) {
153
+ return Number.isNaN(value);
154
+ }
155
+ var isNotNaN = bindNot(isNaN$1);
156
+
157
+ function isNegative(value) {
158
+ if (isNumeric(value)) {
159
+ return Number(value) < 0;
160
+ }
161
+ return false;
162
+ }
163
+ var isPositive = bindNot(isNegative);
164
+
165
+ /**
166
+ * Validates that a given value is an odd number
167
+ */
168
+ var isOdd = function (value) {
169
+ if (isNumeric(value)) {
170
+ return value % 2 !== 0;
171
+ }
172
+ return false;
173
+ };
174
+
175
+ var isNotString = bindNot(isStringValue);
176
+
177
+ function isTruthy(value) {
178
+ return !!value;
179
+ }
180
+ var isFalsy = bindNot(isTruthy);
181
+
182
+ function lessThan(value, lt) {
183
+ return isNumeric(value) && isNumeric(lt) && Number(value) < Number(lt);
184
+ }
185
+
186
+ function longerThan(value, arg1) {
187
+ return value.length > Number(arg1);
188
+ }
189
+
190
+ function longerThanOrEquals(value, arg1) {
191
+ return value.length >= Number(arg1);
192
+ }
193
+
194
+ function matches(value, regex) {
195
+ if (regex instanceof RegExp) {
196
+ return regex.test(value);
197
+ }
198
+ else if (isStringValue(regex)) {
199
+ return new RegExp(regex).test(value);
200
+ }
201
+ else {
202
+ return false;
203
+ }
204
+ }
205
+ var notMatches = bindNot(matches);
206
+
207
+ function numberEquals(value, eq) {
208
+ return isNumeric(value) && isNumeric(eq) && Number(value) === Number(eq);
209
+ }
210
+ var numberNotEquals = bindNot(numberEquals);
211
+
212
+ function condition(value, callback) {
213
+ try {
214
+ return callback(value);
215
+ }
216
+ catch (_a) {
217
+ return false;
218
+ }
219
+ }
220
+
221
+ function shorterThan(value, arg1) {
222
+ return value.length < Number(arg1);
223
+ }
224
+
225
+ function shorterThanOrEquals(value, arg1) {
226
+ return value.length <= Number(arg1);
227
+ }
228
+
229
+ function startsWith(value, arg1) {
230
+ return isStringValue(value) && isStringValue(arg1) && value.startsWith(arg1);
231
+ }
232
+ var doesNotStartWith = bindNot(startsWith);
233
+
234
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, max-lines-per-function
235
+ function rules() {
236
+ return {
237
+ condition: condition,
238
+ doesNotEndWith: doesNotEndWith,
239
+ doesNotStartWith: doesNotStartWith,
240
+ endsWith: endsWith,
241
+ equals: equals,
242
+ greaterThan: greaterThan,
243
+ greaterThanOrEquals: greaterThanOrEquals,
244
+ gt: greaterThan,
245
+ gte: greaterThanOrEquals,
246
+ inside: inside,
247
+ isArray: isArray,
248
+ isBetween: isBetween,
249
+ isBlank: isBlank,
250
+ isBoolean: isBoolean,
251
+ isEmpty: isEmpty,
252
+ isEven: isEven,
253
+ isFalsy: isFalsy,
254
+ isNaN: isNaN$1,
255
+ isNegative: isNegative,
256
+ isNotArray: isNotArray,
257
+ isNotBetween: isNotBetween,
258
+ isNotBlank: isNotBlank,
259
+ isNotBoolean: isNotBoolean,
260
+ isNotEmpty: isNotEmpty,
261
+ isNotNaN: isNotNaN,
262
+ isNotNull: isNotNull,
263
+ isNotNullish: isNotNullish,
264
+ isNotNumber: isNotNumber,
265
+ isNotNumeric: isNotNumeric,
266
+ isNotString: isNotString,
267
+ isNotUndefined: isNotUndefined,
268
+ isNull: isNull,
269
+ isNullish: isNullish,
270
+ isNumber: isNumber,
271
+ isNumeric: isNumeric,
272
+ isOdd: isOdd,
273
+ isPositive: isPositive,
274
+ isString: isStringValue,
275
+ isTruthy: isTruthy,
276
+ isUndefined: isUndefined,
277
+ lengthEquals: lengthEquals,
278
+ lengthNotEquals: lengthNotEquals,
279
+ lessThan: lessThan,
280
+ lessThanOrEquals: lessThanOrEquals,
281
+ longerThan: longerThan,
282
+ longerThanOrEquals: longerThanOrEquals,
283
+ lt: lessThan,
284
+ lte: lessThanOrEquals,
285
+ matches: matches,
286
+ notEquals: notEquals,
287
+ notInside: notInside,
288
+ notMatches: notMatches,
289
+ numberEquals: numberEquals,
290
+ numberNotEquals: numberNotEquals,
291
+ shorterThan: shorterThan,
292
+ shorterThanOrEquals: shorterThanOrEquals,
293
+ startsWith: startsWith
294
+ };
295
+ }
296
+
297
+ var baseRules = rules();
298
+ function getRule(ruleName) {
299
+ return baseRules[ruleName];
300
+ }
301
+
302
+ function eachEnforceRule(action) {
303
+ for (var ruleName in baseRules) {
304
+ var ruleFn = getRule(ruleName);
305
+ if (isFunction(ruleFn)) {
306
+ action(ruleName, ruleFn);
307
+ }
308
+ }
18
309
  }
19
310
 
20
311
  function optionalFunctionValue(value) {
@@ -42,6 +333,344 @@
42
333
  }, 0);
43
334
  }
44
335
 
336
+ // eslint-disable-next-line max-lines-per-function
337
+ function createContext(init) {
338
+ var storage = { ancestry: [] };
339
+ return {
340
+ bind: bind,
341
+ run: run,
342
+ use: use,
343
+ useX: useX
344
+ };
345
+ function useX(errorMessage) {
346
+ var _a;
347
+ return ((_a = storage.ctx) !== null && _a !== void 0 ? _a : throwError(defaultTo(errorMessage, 'Context was used after it was closed')));
348
+ }
349
+ function run(ctxRef, fn) {
350
+ var _a;
351
+ var parentContext = use();
352
+ var out = assign({}, parentContext ? parentContext : {}, (_a = optionalFunctionValue(init, ctxRef, parentContext)) !== null && _a !== void 0 ? _a : ctxRef);
353
+ var ctx = set(Object.freeze(out));
354
+ storage.ancestry.unshift(ctx);
355
+ var res = fn(ctx);
356
+ clear();
357
+ return res;
358
+ }
359
+ function bind(ctxRef, fn) {
360
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
361
+ // @ts-ignore - this one's pretty hard to get right
362
+ var returnedFn = function () {
363
+ var runTimeArgs = [];
364
+ for (var _i = 0; _i < arguments.length; _i++) {
365
+ runTimeArgs[_i] = arguments[_i];
366
+ }
367
+ return run(ctxRef, function () {
368
+ return fn.apply(void 0, runTimeArgs);
369
+ });
370
+ };
371
+ return returnedFn;
372
+ }
373
+ function use() {
374
+ return storage.ctx;
375
+ }
376
+ function set(value) {
377
+ return (storage.ctx = value);
378
+ }
379
+ function clear() {
380
+ var _a;
381
+ storage.ancestry.shift();
382
+ set((_a = storage.ancestry[0]) !== null && _a !== void 0 ? _a : null);
383
+ }
384
+ }
385
+
386
+ var ctx = createContext(function (ctxRef, parentContext) {
387
+ var base = {
388
+ value: ctxRef.value,
389
+ meta: ctxRef.meta || {}
390
+ };
391
+ if (!parentContext) {
392
+ return assign(base, {
393
+ parent: emptyParent
394
+ });
395
+ }
396
+ else if (ctxRef.set) {
397
+ return assign(base, {
398
+ parent: function () { return stripContext(parentContext); }
399
+ });
400
+ }
401
+ return parentContext;
402
+ });
403
+ function stripContext(ctx) {
404
+ if (!ctx) {
405
+ return ctx;
406
+ }
407
+ return {
408
+ value: ctx.value,
409
+ meta: ctx.meta,
410
+ parent: ctx.parent
411
+ };
412
+ }
413
+ function emptyParent() {
414
+ return null;
415
+ }
416
+
417
+ /*! *****************************************************************************
418
+ Copyright (c) Microsoft Corporation.
419
+
420
+ Permission to use, copy, modify, and/or distribute this software for any
421
+ purpose with or without fee is hereby granted.
422
+
423
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
424
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
425
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
426
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
427
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
428
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
429
+ PERFORMANCE OF THIS SOFTWARE.
430
+ ***************************************************************************** */
431
+
432
+ var __assign = function() {
433
+ __assign = Object.assign || function __assign(t) {
434
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
435
+ s = arguments[i];
436
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
437
+ }
438
+ return t;
439
+ };
440
+ return __assign.apply(this, arguments);
441
+ };
442
+
443
+ function __spreadArray(to, from, pack) {
444
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
445
+ if (ar || !(i in from)) {
446
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
447
+ ar[i] = from[i];
448
+ }
449
+ }
450
+ return to.concat(ar || Array.prototype.slice.call(from));
451
+ }
452
+
453
+ function isProxySupported() {
454
+ try {
455
+ return isFunction(Proxy);
456
+ }
457
+ catch (_a) {
458
+ return false;
459
+ }
460
+ }
461
+
462
+ function ruleReturn(pass, message) {
463
+ var output = { pass: pass };
464
+ if (message) {
465
+ output.message = message;
466
+ }
467
+ return output;
468
+ }
469
+ function passing() {
470
+ return ruleReturn(true);
471
+ }
472
+ function defaultToPassing(callback) {
473
+ return defaultTo(callback, passing());
474
+ }
475
+
476
+ /**
477
+ * Transform the result of a rule into a standard format
478
+ */
479
+ function transformResult(result, ruleName, value) {
480
+ var args = [];
481
+ for (var _i = 3; _i < arguments.length; _i++) {
482
+ args[_i - 3] = arguments[_i];
483
+ }
484
+ validateResult(result);
485
+ // if result is boolean
486
+ if (isBoolean(result)) {
487
+ return ruleReturn(result);
488
+ }
489
+ else {
490
+ return ruleReturn(result.pass, optionalFunctionValue.apply(void 0, __spreadArray([result.message, ruleName, value], args)));
491
+ }
492
+ }
493
+ function validateResult(result) {
494
+ // if result is boolean, or if result.pass is boolean
495
+ if (isBoolean(result) || (result && isBoolean(result.pass))) {
496
+ return;
497
+ }
498
+ throwError('Incorrect return value for rule: ' + JSON.stringify(result));
499
+ }
500
+
501
+ function enforceEager(value) {
502
+ var target = {};
503
+ if (!isProxySupported()) {
504
+ eachEnforceRule(function (ruleName, ruleFn) {
505
+ target[ruleName] = genRuleCall(target, ruleFn, ruleName);
506
+ });
507
+ return target;
508
+ }
509
+ var proxy = new Proxy(target, {
510
+ get: function (_, ruleName) {
511
+ var rule = getRule(ruleName);
512
+ if (rule) {
513
+ return genRuleCall(proxy, rule, ruleName);
514
+ }
515
+ }
516
+ });
517
+ return proxy;
518
+ function genRuleCall(target, rule, ruleName) {
519
+ return function ruleCall() {
520
+ var args = [];
521
+ for (var _i = 0; _i < arguments.length; _i++) {
522
+ args[_i] = arguments[_i];
523
+ }
524
+ var transformedResult = transformResult.apply(void 0, __spreadArray([ctx.run({ value: value }, function () { return rule.apply(void 0, __spreadArray([value], args)); }),
525
+ ruleName,
526
+ value], args));
527
+ if (!transformedResult.pass) {
528
+ if (isEmpty(transformedResult.message)) {
529
+ throwError("enforce/" + ruleName + " failed with " + JSON.stringify(value));
530
+ }
531
+ else {
532
+ // Explicitly throw a string so that vest.test can pick it up as the validation error message
533
+ throw transformedResult.message;
534
+ }
535
+ }
536
+ return target;
537
+ };
538
+ }
539
+ }
540
+
541
+ function mapFirst(array, callback) {
542
+ var broke = false;
543
+ var breakoutValue = null;
544
+ for (var i = 0; i < array.length; i++) {
545
+ callback(array[i], breakout, i);
546
+ if (broke) {
547
+ return breakoutValue;
548
+ }
549
+ }
550
+ function breakout(value) {
551
+ broke = true;
552
+ breakoutValue = value;
553
+ }
554
+ }
555
+
556
+ // eslint-disable-next-line max-lines-per-function
557
+ function genEnforceLazy(key) {
558
+ var registeredRules = [];
559
+ var lazyMessage;
560
+ return addLazyRule(key);
561
+ // eslint-disable-next-line max-lines-per-function
562
+ function addLazyRule(ruleName) {
563
+ // eslint-disable-next-line max-lines-per-function
564
+ return function () {
565
+ var args = [];
566
+ for (var _i = 0; _i < arguments.length; _i++) {
567
+ args[_i] = arguments[_i];
568
+ }
569
+ var rule = getRule(ruleName);
570
+ registeredRules.push(function (value) {
571
+ return transformResult.apply(void 0, __spreadArray([rule.apply(void 0, __spreadArray([value], args)), ruleName, value], args));
572
+ });
573
+ var proxy = {
574
+ run: function (value) {
575
+ return defaultToPassing(mapFirst(registeredRules, function (rule, breakout) {
576
+ var _a;
577
+ var res = ctx.run({ value: value }, function () { return rule(value); });
578
+ if (!res.pass) {
579
+ breakout(ruleReturn(!!res.pass, (_a = optionalFunctionValue(lazyMessage, value, res.message)) !== null && _a !== void 0 ? _a : res.message));
580
+ }
581
+ }));
582
+ },
583
+ test: function (value) { return proxy.run(value).pass; },
584
+ message: function (message) {
585
+ if (message) {
586
+ lazyMessage = message;
587
+ }
588
+ return proxy;
589
+ }
590
+ };
591
+ if (!isProxySupported()) {
592
+ eachEnforceRule(function (ruleName) {
593
+ proxy[ruleName] = addLazyRule(ruleName);
594
+ });
595
+ return proxy;
596
+ }
597
+ // reassigning the proxy here is not pretty
598
+ // but it's a cleaner way of getting `run` and `test` for free
599
+ proxy = new Proxy(proxy, {
600
+ get: function (target, key) {
601
+ if (getRule(key)) {
602
+ return addLazyRule(key);
603
+ }
604
+ return target[key]; // already has `run` and `test` on it
605
+ }
606
+ });
607
+ return proxy;
608
+ };
609
+ }
610
+ }
611
+
612
+ /**
613
+ * Enforce is quite complicated, I want to explain it in detail.
614
+ * It is dynamic in nature, so a lot of proxy objects are involved.
615
+ *
616
+ * Enforce has two main interfaces
617
+ * 1. eager
618
+ * 2. lazy
619
+ *
620
+ * The eager interface is the most commonly used, and the easier to understand.
621
+ * It throws an error when a rule is not satisfied.
622
+ * The eager interface is declared in enforceEager.ts and it is quite simple to understand.
623
+ * enforce is called with a value, and the return value is a proxy object that points back to all the rules.
624
+ * When a rule is called, the value is mapped as its first argument, and if the rule passes, the same
625
+ * proxy object is returned. Otherwise, an error is thrown.
626
+ *
627
+ * The lazy interface works quite differently. It is declared in genEnforceLazy.ts.
628
+ * Rather than calling enforce directly, the lazy interface has all the rules as "methods" (only by proxy).
629
+ * Calling the first function in the chain will initialize an array of calls. It stores the different rule calls
630
+ * and the parameters passed to them. None of the rules are called yet.
631
+ * The rules are only invoked in sequence once either of these chained functions are called:
632
+ * 1. test(value)
633
+ * 2. run(value)
634
+ *
635
+ * Calling run or test will call all the rules in sequence, with the difference that test will only return a boolean value,
636
+ * while run will return an object with the validation result and an optional message created by the rule.
637
+ */
638
+ function genEnforce() {
639
+ var target = {
640
+ context: function () { return ctx.useX(); },
641
+ extend: function (customRules) {
642
+ assign(baseRules, customRules);
643
+ }
644
+ };
645
+ if (!isProxySupported()) {
646
+ eachEnforceRule(function (ruleName) {
647
+ // Only on the first rule access - start the chain of calls
648
+ target[ruleName] = genEnforceLazy(ruleName);
649
+ });
650
+ return target;
651
+ }
652
+ return new Proxy(assign(enforceEager, target), {
653
+ get: function (target, key) {
654
+ if (key in target) {
655
+ return target[key];
656
+ }
657
+ if (!getRule(key)) {
658
+ return;
659
+ }
660
+ // Only on the first rule access - start the chain of calls
661
+ return genEnforceLazy(key);
662
+ }
663
+ });
664
+ }
665
+ var enforce = genEnforce();
666
+
667
+ /**
668
+ * @returns a unique numeric id.
669
+ */
670
+ var genId = (function (n) { return function () {
671
+ return "" + n++;
672
+ }; })(0);
673
+
45
674
  // eslint-disable-next-line max-lines-per-function
46
675
  function createState(onStateChange) {
47
676
  var state = {
@@ -178,7 +807,7 @@
178
807
  };
179
808
  }
180
809
 
181
- var context = context$1.createContext(function (ctxRef, parentContext) {
810
+ var context = createContext(function (ctxRef, parentContext) {
182
811
  return parentContext
183
812
  ? null
184
813
  : assign({}, {
@@ -186,6 +815,7 @@
186
815
  tests: {},
187
816
  groups: {}
188
817
  },
818
+ inclusion: {},
189
819
  isolate: {
190
820
  type: IsolateTypes.DEFAULT,
191
821
  keys: {
@@ -197,28 +827,6 @@
197
827
  }, ctxRef);
198
828
  });
199
829
 
200
- function bindNot(fn) {
201
- return function () {
202
- var args = [];
203
- for (var _i = 0; _i < arguments.length; _i++) {
204
- args[_i] = arguments[_i];
205
- }
206
- return !fn.apply(void 0, args);
207
- };
208
- }
209
-
210
- // The module is named "isArrayValue" since it
211
- // is conflicting with a nested npm dependency.
212
- // We may need to revisit this in the future.
213
- function isArray(value) {
214
- return Boolean(Array.isArray(value));
215
- }
216
-
217
- function isNull(value) {
218
- return value === null;
219
- }
220
- var isNotNull = bindNot(isNull);
221
-
222
830
  // This is sort of a map/filter in one function.
223
831
  // Normally, behaves like a nested-array map
224
832
  // Returning `null` will drop the element from the array
@@ -264,31 +872,11 @@
264
872
  return current;
265
873
  }
266
874
 
267
- function isUndefined(value) {
268
- return value === undefined;
269
- }
270
-
271
- function isNullish(value) {
272
- return isNull(value) || isUndefined(value);
273
- }
274
-
275
- function isStringValue(v) {
276
- return String(v) === v;
277
- }
278
-
279
875
  function shouldUseErrorAsMessage(message, error) {
280
876
  // kind of cheating with this safe guard, but it does the job
281
877
  return isUndefined(message) && isStringValue(error);
282
878
  }
283
879
 
284
- function lengthEquals(value, arg1) {
285
- return value.length === Number(arg1);
286
- }
287
-
288
- function longerThan(value, arg1) {
289
- return value.length > Number(arg1);
290
- }
291
-
292
880
  /**
293
881
  * Creates a cache function
294
882
  */
@@ -604,34 +1192,6 @@
604
1192
  return context.useX().isolate.type === IsolateTypes.EACH;
605
1193
  }
606
1194
 
607
- /**
608
- * A safe hasOwnProperty access
609
- */
610
- function hasOwnProperty(obj, key) {
611
- return Object.prototype.hasOwnProperty.call(obj, key);
612
- }
613
-
614
- function isNumber(value) {
615
- return Boolean(typeof value === 'number');
616
- }
617
-
618
- function isEmpty(value) {
619
- if (!value) {
620
- return true;
621
- }
622
- else if (isNumber(value)) {
623
- return value === 0;
624
- }
625
- else if (hasOwnProperty(value, 'length')) {
626
- return lengthEquals(value, 0);
627
- }
628
- else if (typeof value === 'object') {
629
- return lengthEquals(Object.keys(value), 0);
630
- }
631
- return true;
632
- }
633
- var isNotEmpty = bindNot(isEmpty);
634
-
635
1195
  function nonMatchingFieldName(testObject, fieldName) {
636
1196
  return !!fieldName && !matchingFieldName(testObject, fieldName);
637
1197
  }
@@ -719,42 +1279,6 @@
719
1279
  return testKey;
720
1280
  }
721
1281
 
722
- /*! *****************************************************************************
723
- Copyright (c) Microsoft Corporation.
724
-
725
- Permission to use, copy, modify, and/or distribute this software for any
726
- purpose with or without fee is hereby granted.
727
-
728
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
729
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
730
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
731
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
732
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
733
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
734
- PERFORMANCE OF THIS SOFTWARE.
735
- ***************************************************************************** */
736
-
737
- var __assign = function() {
738
- __assign = Object.assign || function __assign(t) {
739
- for (var s, i = 1, n = arguments.length; i < n; i++) {
740
- s = arguments[i];
741
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
742
- }
743
- return t;
744
- };
745
- return __assign.apply(this, arguments);
746
- };
747
-
748
- function __spreadArray(to, from, pack) {
749
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
750
- if (ar || !(i in from)) {
751
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
752
- ar[i] = from[i];
753
- }
754
- }
755
- return to.concat(ar || from);
756
- }
757
-
758
1282
  function either(a, b) {
759
1283
  return !!a !== !!b;
760
1284
  }
@@ -1263,13 +1787,14 @@
1263
1787
  return !!context.useX().skipped;
1264
1788
  }
1265
1789
  //Checks whether a certain test profile excluded by any of the exclusion groups.
1266
- // eslint-disable-next-line complexity, max-statements
1790
+ // eslint-disable-next-line complexity, max-statements, max-lines-per-function
1267
1791
  function isExcluded(testObject) {
1268
1792
  var fieldName = testObject.fieldName, groupName = testObject.groupName;
1269
1793
  if (isExcludedIndividually())
1270
1794
  return true;
1271
1795
  var context$1 = context.useX();
1272
1796
  var exclusion = context$1.exclusion;
1797
+ var inclusion = context$1.inclusion;
1273
1798
  var keyTests = exclusion.tests;
1274
1799
  var testValue = keyTests[fieldName];
1275
1800
  // if test is skipped
@@ -1299,8 +1824,12 @@
1299
1824
  if (isTestIncluded)
1300
1825
  return false;
1301
1826
  // If there is _ANY_ `only`ed test (and we already know this one isn't) return true
1302
- // Otherwise return false
1303
- return hasIncludedTests(keyTests);
1827
+ if (hasIncludedTests(keyTests)) {
1828
+ // Check if inclusion rules for this field (`include` hook)
1829
+ return !optionalFunctionValue(inclusion[fieldName]);
1830
+ }
1831
+ // We're done here. This field is not excluded
1832
+ return false;
1304
1833
  }
1305
1834
  // eslint-disable-next-line max-statements
1306
1835
  function isMissingFromIncludedGroup(groupName) {
@@ -1405,6 +1934,29 @@
1405
1934
  throwError("Wrong arguments passed to group. Group " + error + ".");
1406
1935
  }
1407
1936
 
1937
+ function include(fieldName) {
1938
+ var context$1 = context.useX();
1939
+ var inclusion = context$1.inclusion, exclusion = context$1.exclusion;
1940
+ if (!fieldName) {
1941
+ return { when: when };
1942
+ }
1943
+ inclusion[fieldName] = defaultTo(exclusion.tests[fieldName], true);
1944
+ return { when: when };
1945
+ function when(condition) {
1946
+ var context$1 = context.useX();
1947
+ var inclusion = context$1.inclusion, exclusion = context$1.exclusion;
1948
+ inclusion[fieldName] = function () {
1949
+ if (hasOwnProperty(exclusion.tests, fieldName)) {
1950
+ return defaultTo(exclusion.tests[fieldName], true);
1951
+ }
1952
+ if (isStringValue(condition)) {
1953
+ return Boolean(exclusion.tests[condition]);
1954
+ }
1955
+ return optionalFunctionValue(condition, optionalFunctionValue(produceDraft));
1956
+ };
1957
+ }
1958
+ }
1959
+
1408
1960
  /**
1409
1961
  * Conditionally omits tests from the suite.
1410
1962
  *
@@ -1472,8 +2024,6 @@
1472
2024
  });
1473
2025
  }
1474
2026
 
1475
- var isNotString = bindNot(isStringValue);
1476
-
1477
2027
  function isPromise(value) {
1478
2028
  return value && isFunction(value.then);
1479
2029
  }
@@ -1683,6 +2233,7 @@
1683
2233
  }
1684
2234
  }
1685
2235
 
2236
+ /* eslint-disable jest/valid-title */
1686
2237
  // eslint-disable-next-line max-lines-per-function
1687
2238
  function bindTestMemo(test) {
1688
2239
  var cache = createCache(100); // arbitrary cache size
@@ -1760,19 +2311,15 @@
1760
2311
  ctx.currentTest.warn();
1761
2312
  }
1762
2313
 
1763
- var VERSION = "4.0.0";
2314
+ var VERSION = "4.0.2-dev-6e9534";
1764
2315
 
1765
- Object.defineProperty(exports, 'enforce', {
1766
- enumerable: true,
1767
- get: function () {
1768
- return n4s.enforce;
1769
- }
1770
- });
1771
2316
  exports.VERSION = VERSION;
1772
2317
  exports.context = context;
1773
2318
  exports.create = create;
1774
2319
  exports.each = each;
2320
+ exports.enforce = enforce;
1775
2321
  exports.group = group;
2322
+ exports.include = include;
1776
2323
  exports.omitWhen = omitWhen;
1777
2324
  exports.only = only;
1778
2325
  exports.optional = optional;