All files / json-path ast.ts

96.87% Statements 62/64
100% Branches 0/0
94.59% Functions 35/37
96.82% Lines 61/63

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158    4x 282x 4x 419x   4x 257x 54x   19x 22x   25x 94x     4x         64x         7x 14x       59x   3x   1x     4x 3x     83x 101x       59x           257x 257x       54x 54x       19x   19x 19x 19x         22x       25x 25x       94x 94x         419x 419x         282x         64x   64x 64x 64x         7x   7x 7x 7x         14x 14x       118x   118x 118x         3x 3x       1x 1x       3x               83x 83x       101x 101x    
import type * as types from './types';
 
export class Ast {
  public static path = (segments: types.PathSegment[]): types.JSONPath => new JSONPath(segments);
  public static segment = (selectors: types.AnySelector[], recursive?: boolean): types.PathSegment =>
    new PathSegment(selectors, recursive);
 
  public static selector = class selector {
    public static named = (name: string): types.NamedSelector => new Named(name);
    public static index = (index: number): types.IndexSelector => new Index(index);
    public static slice = (start?: number, end?: number, step?: number): types.SliceSelector =>
      new Slice(start, end, step);
    public static wildcard = (): types.WildcardSelector => new Wildcard();
    public static recursiveDescent = (selector: types.AnySelector): types.RecursiveDescentSelector =>
      new RecursiveDescent(selector);
    public static filter = (expression: types.FilterExpression): types.FilterSelector => new Filter(expression);
  };
 
  public static expression = class expression {
    public static comparison = (
      operator: types.ComparisonExpression['operator'],
      left: types.ValueExpression,
      right: types.ValueExpression,
    ): types.ComparisonExpression => new ComparisonExpression(operator, left, right);
    public static logical = (
      operator: types.LogicalExpression['operator'],
      left: types.FilterExpression,
      right: types.FilterExpression,
    ): types.LogicalExpression => new LogicalExpression(operator, left, right);
    public static existence = (path: types.JSONPath): types.ExistenceExpression => new ExistenceExpression(path);
    public static function = (
      name: string,
      args: (types.ValueExpression | types.FilterExpression | types.JSONPath)[],
    ): types.FunctionExpression => new FunctionExpression(name, args);
    public static paren = (expression: types.FilterExpression): types.ParenExpression =>
      new ParenthesizedExpression(expression);
    public static negation = (expression: types.FilterExpression): types.NegationExpression =>
      new NegationExpression(expression);
  };
 
  public static value = class value {
    public static current = (): types.CurrentNodeExpression => new CurrentNodeExpression();
    public static root = (): types.RootNodeExpression => new RootNodeExpression();
    public static literal = (value: string | number | boolean | null): types.LiteralExpression =>
      new LiteralExpression(value);
    public static path = (path: types.JSONPath): types.PathExpression => new PathExpression(path);
    public static function = (
      name: string,
      args: (types.ValueExpression | types.FilterExpression | types.JSONPath)[],
    ): types.FunctionExpression => new FunctionExpression(name, args);
  };
}
 
// Selector implementations with consistent property order for V8 hidden classes
class Named implements types.NamedSelector {
  public readonly type = 'name' as const;
  constructor(public readonly name: string) {}
}
 
class Index implements types.IndexSelector {
  public readonly type = 'index' as const;
  constructor(public readonly index: number) {}
}
 
class Slice implements types.SliceSelector {
  public readonly type = 'slice' as const;
  constructor(
    public readonly start?: number,
    public readonly end?: number,
    public readonly step?: number,
  ) {}
}
 
class Wildcard implements types.WildcardSelector {
  public readonly type = 'wildcard' as const;
}
 
class RecursiveDescent implements types.RecursiveDescentSelector {
  public readonly type = 'recursive-descent' as const;
  constructor(public readonly selector: types.AnySelector) {}
}
 
class Filter implements types.FilterSelector {
  public readonly type = 'filter' as const;
  constructor(public readonly expression: types.FilterExpression) {}
}
 
class PathSegment implements types.PathSegment {
  constructor(
    public readonly selectors: types.AnySelector[],
    public readonly recursive?: boolean,
  ) {}
}
 
class JSONPath implements types.JSONPath {
  constructor(public readonly segments: types.PathSegment[]) {}
}
 
// Filter expression implementations
class ComparisonExpression implements types.ComparisonExpression {
  public readonly type = 'comparison' as const;
  constructor(
    public readonly operator: types.ComparisonExpression['operator'],
    public readonly left: types.ValueExpression,
    public readonly right: types.ValueExpression,
  ) {}
}
 
class LogicalExpression implements types.LogicalExpression {
  public readonly type = 'logical' as const;
  constructor(
    public readonly operator: types.LogicalExpression['operator'],
    public readonly left: types.FilterExpression,
    public readonly right: types.FilterExpression,
  ) {}
}
 
class ExistenceExpression implements types.ExistenceExpression {
  public readonly type = 'existence' as const;
  constructor(public readonly path: types.JSONPath) {}
}
 
class FunctionExpression implements types.FunctionExpression {
  public readonly type = 'function' as const;
  constructor(
    public readonly name: string,
    public readonly args: (types.ValueExpression | types.FilterExpression | types.JSONPath)[],
  ) {}
}
 
class ParenthesizedExpression implements types.ParenExpression {
  public readonly type = 'paren' as const;
  constructor(public readonly expression: types.FilterExpression) {}
}
 
class NegationExpression implements types.NegationExpression {
  public readonly type = 'negation' as const;
  constructor(public readonly expression: types.FilterExpression) {}
}
 
class CurrentNodeExpression implements types.CurrentNodeExpression {
  public readonly type = 'current' as const;
}
 
class RootNodeExpression implements types.RootNodeExpression {
  public readonly type = 'root' as const;
}
 
class LiteralExpression implements types.LiteralExpression {
  public readonly type = 'literal' as const;
  constructor(public readonly value: string | number | boolean | null) {}
}
 
class PathExpression implements types.PathExpression {
  public readonly type = 'path' as const;
  constructor(public readonly path: types.JSONPath) {}
}