1
- import { JsonPath } from '@stoplight/types' ;
2
1
import { decodeSegmentFragment , getClosestJsonPath , printPath , PrintStyle } from '@stoplight/spectral-runtime' ;
3
2
import { get , isError } from 'lodash' ;
4
3
import { ErrorWithCause } from 'pony-cause' ;
5
4
6
5
import { Document } from '../document' ;
7
- import { IFunctionResult , IGivenNode , RulesetFunctionContext } from '../types' ;
8
- import { IRunnerInternalContext } from './types' ;
6
+ import type { IFunctionResult , IGivenNode , RulesetFunctionContext } from '../types' ;
7
+ import type { IRunnerInternalContext } from './types' ;
9
8
import { getLintTargets , MessageVars , message } from './utils' ;
10
- import { Rule } from '../ruleset/rule' ;
9
+ import type { Rule } from '../ruleset/rule' ;
11
10
12
11
export const lintNode = ( context : IRunnerInternalContext , node : IGivenNode , rule : Rule ) : void => {
13
- const fnContext : RulesetFunctionContext = {
12
+ const givenPath = node . path . length > 0 && node . path [ 0 ] === '$' ? node . path . slice ( 1 ) : node . path . slice ( ) ;
13
+
14
+ const fnContext : RulesetFunctionContext & { rule : Rule } = {
14
15
document : context . documentInventory . document ,
15
16
documentInventory : context . documentInventory ,
16
17
rule,
17
- path : [ ] ,
18
+ path : givenPath ,
18
19
} ;
19
20
20
- const givenPath = node . path . length > 0 && node . path [ 0 ] === '$' ? node . path . slice ( 1 ) : node . path ;
21
-
22
21
for ( const then of rule . then ) {
23
22
const targets = getLintTargets ( node . value , then . field ) ;
24
23
25
24
for ( const target of targets ) {
26
- const path = target . path . length > 0 ? [ ...givenPath , ...target . path ] : givenPath ;
25
+ if ( target . path . length > 0 ) {
26
+ fnContext . path = [ ...givenPath , ...target . path ] ;
27
+ }
27
28
28
29
let targetResults ;
29
30
try {
30
- targetResults = then . function ( target . value , then . functionOptions ?? null , {
31
- ...fnContext ,
32
- path,
33
- } ) ;
31
+ targetResults = then . function ( target . value , then . functionOptions ?? null , fnContext ) ;
34
32
} catch ( e ) {
35
33
throw new ErrorWithCause (
36
34
`Function "${ then . function . name } " threw an exception${ isError ( e ) ? `: ${ e . message } ` : '' } ` ,
@@ -43,36 +41,25 @@ export const lintNode = (context: IRunnerInternalContext, node: IGivenNode, rule
43
41
if ( targetResults === void 0 ) continue ;
44
42
45
43
if ( 'then' in targetResults ) {
44
+ const _fnContext = { ...fnContext } ;
46
45
context . promises . push (
47
46
targetResults . then ( results =>
48
- results === void 0
49
- ? void 0
50
- : void processTargetResults (
51
- context ,
52
- results ,
53
- rule ,
54
- path , // todo: get rid of it somehow.
55
- ) ,
47
+ results === void 0 ? void 0 : processTargetResults ( context , _fnContext , results ) ,
56
48
) ,
57
49
) ;
58
50
} else {
59
- processTargetResults (
60
- context ,
61
- targetResults ,
62
- rule ,
63
- path , // todo: get rid of it somehow.
64
- ) ;
51
+ processTargetResults ( context , fnContext , targetResults ) ;
65
52
}
66
53
}
67
54
}
68
55
} ;
69
56
70
57
function processTargetResults (
71
58
context : IRunnerInternalContext ,
59
+ fnContext : RulesetFunctionContext & { rule : Rule } ,
72
60
results : IFunctionResult [ ] ,
73
- rule : Rule ,
74
- targetPath : JsonPath ,
75
61
) : void {
62
+ const { rule, path : targetPath } = fnContext ;
76
63
for ( const result of results ) {
77
64
const escapedJsonPath = ( result . path ?? targetPath ) . map ( decodeSegmentFragment ) ;
78
65
const associatedItem = context . documentInventory . findAssociatedItemForPath ( escapedJsonPath , rule . resolved ) ;
0 commit comments