@@ -7,9 +7,17 @@ import { getRule, RuleValue, Args, RuleBase, KBaseRules } from 'runtimeRules';
77import { transformResult } from 'transformResult' ;
88
99type IRules = n4s . IRules < Record < string , any > > ;
10+ type TModifiers = {
11+ message : ( input : string ) => EnforceEagerReturn ;
12+ } ;
1013
11- export default function enforceEager ( value : RuleValue ) : IRules {
12- const target = { } as IRules ;
14+ type EnforceEagerReturn = IRules & TModifiers ;
15+
16+ export default function enforceEager ( value : RuleValue ) : EnforceEagerReturn {
17+ const target = {
18+ message,
19+ } as EnforceEagerReturn ;
20+ let customMessage : string | undefined = undefined ;
1321
1422 // This condition is for when we don't have proxy support (ES5).
1523 // In this case, we need to manually assign the rules to the target object on runtime.
@@ -25,15 +33,16 @@ export default function enforceEager(value: RuleValue): IRules {
2533 }
2634
2735 // We create a proxy intercepting access to the target object (which is empty).
28- const proxy : IRules = new Proxy ( target , {
29- get : ( _ , ruleName : string ) => {
36+ const proxy : EnforceEagerReturn = new Proxy ( target , {
37+ get : ( _ , key : string ) => {
3038 // On property access, we identify if it is a rule or not.
31- const rule = getRule ( ruleName ) ;
39+ const rule = getRule ( key ) ;
3240
3341 // If it is a rule, we wrap it with `genRuleCall` that adds the base enforce behavior
3442 if ( rule ) {
35- return genRuleCall ( proxy , rule , ruleName ) ;
43+ return genRuleCall ( proxy , rule , key ) ;
3644 }
45+ return target [ key ] ;
3746 } ,
3847 } ) ;
3948
@@ -42,28 +51,41 @@ export default function enforceEager(value: RuleValue): IRules {
4251 // This function is used to wrap a rule with the base enforce behavior
4352 // It takes the target object, the rule function, and the rule name
4453 // It then returns the rule, in a manner that can be used by enforce
45- function genRuleCall ( target : IRules , rule : RuleBase , ruleName : string ) {
54+ function genRuleCall (
55+ target : EnforceEagerReturn ,
56+ rule : RuleBase ,
57+ ruleName : string
58+ ) {
4659 return function ruleCall ( ...args : Args ) {
4760 // Order of operation:
4861 // 1. Create a context with the value being enforced
4962 // 2. Call the rule within the context, and pass over the arguments passed to it
5063 // 3. Transform the result to the correct output format
51- const transformedResult = ctx . run ( { value } , ( ) =>
52- transformResult ( rule ( value , ...args ) , ruleName , value , ...args )
53- ) ;
64+ const transformedResult = ctx . run ( { value } , ( ) => {
65+ return transformResult ( rule ( value , ...args ) , ruleName , value , ...args ) ;
66+ } ) ;
67+
68+ function enforceMessage ( ) {
69+ const shouldUseCustomMessage = ! isNullish ( customMessage ) ;
70+ if ( shouldUseCustomMessage ) return customMessage ;
71+ if ( isNullish ( transformedResult . message ) ) {
72+ return `enforce/${ ruleName } failed with ${ JSON . stringify ( value ) } ` ;
73+ }
74+ return StringObject ( transformedResult . message ) ;
75+ }
5476
5577 // On rule failure (the result is false), we either throw an error
5678 // or throw a string value if the rule has a message defined in it.
57- invariant (
58- transformedResult . pass ,
59- isNullish ( transformedResult . message )
60- ? `enforce/${ ruleName } failed with ${ JSON . stringify ( value ) } `
61- : StringObject ( transformedResult . message )
62- ) ;
79+ invariant ( transformedResult . pass , enforceMessage ( ) ) ;
6380
6481 return target ;
6582 } ;
6683 }
84+
85+ function message ( input : string ) : EnforceEagerReturn {
86+ customMessage = input ;
87+ return proxy ;
88+ }
6789}
6890
69- export type EnforceEager = ( value : RuleValue ) => IRules ;
91+ export type EnforceEager = ( value : RuleValue ) => EnforceEagerReturn ;
0 commit comments