• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ota-meshi / eslint-plugin-json-schema-validator / 21108266983

18 Jan 2026 07:45AM UTC coverage: 89.746% (+2.4%) from 87.363%
21108266983

Pull #452

github

web-flow
Merge 67a34021b into bb8e97af5
Pull Request #452: Bundle using tsdown

584 of 680 branches covered (85.88%)

Branch coverage included in aggregate %.

83 of 96 new or added lines in 15 files covered. (86.46%)

149 existing lines in 10 files now uncovered.

2558 of 2821 relevant lines covered (90.68%)

234.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.86
/src/utils/ast/json.ts
1
import type { AST as JSON } from "jsonc-eslint-parser";
1✔
2
import type { GetNodeFromPath, NodeData } from "./common";
1✔
3

1✔
4
type TraverseTarget =
1✔
5
  | JSON.JSONProgram
1✔
6
  | JSON.JSONExpressionStatement
1✔
7
  | JSON.JSONObjectExpression
1✔
8
  | JSON.JSONArrayExpression;
1✔
9

1✔
10
const TRAVERSE_TARGET_TYPE: Set<string> = new Set([
1✔
11
  "Program",
1✔
12
  "JSONExpressionStatement",
1✔
13
  "JSONObjectExpression",
1✔
14
  "JSONArrayExpression",
1✔
15
] as TraverseTarget["type"][]);
1✔
16

1✔
17
const GET_JSON_NODES: Record<
1✔
18
  TraverseTarget["type"],
1✔
19
  GetNodeFromPath<JSON.JSONNode>
1✔
20
> = {
1✔
21
  Program(node: JSON.JSONProgram, _paths: string[]) {
1✔
22
    return { value: node.body[0] };
120✔
23
  },
120✔
24
  JSONExpressionStatement(
1✔
25
    node: JSON.JSONExpressionStatement,
120✔
26
    _paths: string[],
120✔
27
  ) {
120✔
28
    return { value: node.expression };
120✔
29
  },
120✔
30
  JSONObjectExpression(node: JSON.JSONObjectExpression, paths: string[]) {
1✔
31
    const path = String(paths.shift());
173✔
32
    for (const prop of node.properties) {
173✔
33
      if (prop.key.type === "JSONIdentifier") {
286✔
34
        if (prop.key.name === path) {
7✔
35
          return { key: () => prop.key.range, value: prop.value };
7✔
36
        }
7✔
37
      } else {
286✔
38
        if (String(prop.key.value) === path) {
279✔
39
          return { key: () => prop.key.range, value: prop.value };
166✔
40
        }
166✔
41
      }
279✔
42
    }
286!
43
    throw new Error(`${"Unexpected state: ["}${[path, ...paths].join(", ")}]`);
×
UNCOV
44
  },
×
45
  JSONArrayExpression(node: JSON.JSONArrayExpression, paths: string[]) {
1✔
46
    const path = String(paths.shift());
57✔
47
    for (let index = 0; index < node.elements.length; index++) {
57✔
48
      if (String(index) !== path) {
104✔
49
        continue;
47✔
50
      }
47✔
51
      const element = node.elements[index];
57✔
52

57✔
53
      if (element) {
104✔
54
        return { value: element };
53✔
55
      }
53✔
56
      return {
4✔
57
        key: (sourceCode) => {
4✔
58
          const before = node.elements
4✔
59
            .slice(0, index)
4✔
60
            .reverse()
4✔
61
            .find((n) => n != null);
4✔
62
          let tokenIndex = before ? node.elements.indexOf(before) : -1;
4✔
63
          let token = before
4✔
64
            ? sourceCode.getTokenAfter(before)!
3✔
65
            : sourceCode.getFirstToken(node);
1✔
66
          while (tokenIndex < index) {
4✔
67
            tokenIndex++;
5✔
68
            token = sourceCode.getTokenAfter(token)!;
5✔
69
          }
5✔
70

4✔
71
          return [sourceCode.getTokenBefore(token)!.range![1], token.range![0]];
4✔
72
        },
4✔
73
        value: null,
4✔
74
      };
4✔
75
    }
4✔
76
    throw new Error(`${"Unexpected state: ["}${[path, ...paths].join(", ")}]`);
47✔
77
  },
47✔
78
};
1✔
79
/**
1✔
80
 * Get node from path
1✔
81
 */
1✔
82
export function getJSONNodeFromPath(
1✔
83
  node: JSON.JSONProgram,
134✔
84
  [...paths]: string[],
134✔
85
): NodeData<JSON.JSONNode> {
134✔
86
  let data: NodeData<JSON.JSONNode> = {
134✔
87
    key: (sourceCode) => {
134✔
88
      const dataNode = node.body[0].expression;
14✔
89
      if (
14✔
90
        dataNode.type === "JSONObjectExpression" ||
14✔
91
        dataNode.type === "JSONArrayExpression"
2✔
92
      ) {
14✔
93
        return sourceCode.getFirstToken(dataNode).range!;
12✔
94
      }
12✔
95
      return dataNode.range;
2✔
96
    },
2✔
97
    value: node,
134✔
98
  };
134✔
99
  while (paths.length && data.value) {
134✔
100
    if (!isTraverseTarget(data.value)) {
470!
101
      throw new Error(`Unexpected node type: ${data.value.type}`);
×
UNCOV
102
    }
×
103
    data = GET_JSON_NODES[data.value.type](data.value as never, paths);
470✔
104
  }
470✔
105
  return data;
134✔
106
}
134✔
107

1✔
108
/**
1✔
109
 * Checks whether given node is traverse target.
1✔
110
 */
1✔
111
function isTraverseTarget(node: JSON.JSONNode): node is TraverseTarget {
470✔
112
  return TRAVERSE_TARGET_TYPE.has(node.type);
470✔
113
}
470✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc