UNPKG

4.73 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const types_1 = require("@stoplight/types");
4const jp = require("jsonpath");
5const lodash_1 = require("lodash");
6exports.lintNode = (node, rule, then, apply, opts, parsedResult) => {
7 const givenPath = node.path[0] === '$' ? node.path.slice(1) : node.path;
8 const conditioning = exports.whatShouldBeLinted(givenPath, node.value, rule);
9 if (!conditioning.lint) {
10 return [];
11 }
12 const { parsed } = parsedResult;
13 const targetValue = conditioning.value;
14 const targets = [];
15 if (then && then.field) {
16 if (then.field === '@key') {
17 for (const key of Object.keys(targetValue)) {
18 targets.push({
19 path: key,
20 value: key,
21 });
22 }
23 }
24 else if (then.field[0] === '$') {
25 const nodes = jp.nodes(targetValue, then.field);
26 for (const n of nodes) {
27 targets.push({
28 path: n.path,
29 value: n.value,
30 });
31 }
32 }
33 else {
34 targets.push({
35 path: typeof then.field === 'string' ? then.field.split('.') : then.field,
36 value: lodash_1.get(targetValue, then.field),
37 });
38 }
39 }
40 else {
41 targets.push({
42 path: [],
43 value: targetValue,
44 });
45 }
46 if (!targets.length) {
47 targets.push({
48 path: [],
49 value: undefined,
50 });
51 }
52 let results = [];
53 for (const target of targets) {
54 const targetPath = givenPath.concat(target.path);
55 const targetResults = apply(target.value, then.functionOptions || {}, {
56 given: givenPath,
57 target: targetPath,
58 }, {
59 original: node.value,
60 given: node.value,
61 resolved: opts.resolvedTarget,
62 }) || [];
63 const severity = rule.severity !== undefined ? rule.severity : types_1.DiagnosticSeverity.Warning;
64 results = results.concat(targetResults.map(result => {
65 const path = result.path || targetPath;
66 const location = parsedResult.getLocationForJsonPath(parsed, path, true);
67 return Object.assign({ code: rule.name, get summary() {
68 return this.message;
69 }, message: rule.message === undefined
70 ? rule.summary || result.message
71 : typeof rule.message === 'function'
72 ? rule.message({
73 error: result.message,
74 property: path.length > 0 ? path[path.length - 1] : '',
75 description: rule.description,
76 })
77 : rule.message, path,
78 severity, source: parsedResult.source }, (location || {
79 range: {
80 start: {
81 character: 0,
82 line: 0,
83 },
84 end: {
85 character: 0,
86 line: 0,
87 },
88 },
89 }));
90 }));
91 }
92 return results;
93};
94exports.whatShouldBeLinted = (path, originalValue, rule) => {
95 const leaf = path[path.length - 1];
96 const when = rule.when;
97 if (!when) {
98 return {
99 lint: true,
100 value: originalValue,
101 };
102 }
103 const pattern = when.pattern;
104 const field = when.field;
105 const isKey = field === '@key';
106 if (!pattern) {
107 if (isKey) {
108 return {
109 lint: false,
110 value: originalValue,
111 };
112 }
113 return {
114 lint: lodash_1.has(originalValue, field),
115 value: originalValue,
116 };
117 }
118 if (isKey && pattern) {
119 return keyAndOptionalPattern(leaf, pattern, originalValue);
120 }
121 const fieldValue = String(lodash_1.get(originalValue, when.field));
122 return {
123 lint: fieldValue.match(pattern) !== null,
124 value: originalValue,
125 };
126};
127function keyAndOptionalPattern(key, pattern, value) {
128 if (typeof key === 'number' && typeof value === 'object') {
129 for (const k of Object.keys(value)) {
130 if (String(k).match(pattern)) {
131 return {
132 lint: true,
133 value,
134 };
135 }
136 }
137 }
138 else if (String(key).match(pattern)) {
139 return {
140 lint: true,
141 value,
142 };
143 }
144 return {
145 lint: false,
146 value,
147 };
148}
149//# sourceMappingURL=linter.js.map
\No newline at end of file