All files / json-pointer/src/codegen findRef.ts

100% Statements 16/16
100% Branches 5/5
100% Functions 2/2
100% Lines 12/12

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    1x 1x       1x 12x 2x           10x 10x 22x 22x                                     10x               10x           12x  
import type {Reference} from '../find';
import type {Path} from '../types';
import {type JavaScriptLinked, compileClosure} from '@jsonjoy.com/codegen';
import {hasOwnProperty as has} from '@jsonjoy.com/util/lib/hasOwnProperty';
 
type Fn = (val: unknown) => Reference;
 
export const $$findRef = (path: Path): JavaScriptLinked<Fn> => {
  if (!path.length) {
    return {
      deps: [] as unknown[],
      js: /* js */ `(function(){return function(val){return {val:val}}})`,
    } as JavaScriptLinked<Fn>;
  }
 
  let loop = '';
  for (let i = 0; i < path.length; i++) {
    const key = JSON.stringify(path[i]);
    loop += /* js */ `
      obj = val;
      key = ${key};
      if (obj instanceof Array) {
        var length = obj.length;
        if (key === '-') key = length;
        else {
          var key2 = ${~~path[i]};
          ${String(~~path[i]) !== String(path[i]) ? `if ('' + key2 !== key) throw new Error('INVALID_INDEX');` : ''}
          ${~~path[i] < 0 ? `throw new Error('INVALID_INDEX');` : ''}
          key = key2;
        }
        val = obj[key];
      } else if (typeof obj === 'object' && !!obj) {
        val = has(obj, key) ? obj[key] : undefined;
      } else throw new Error('NOT_FOUND');
    `;
  }
 
  const js = /* js */ `(function(has, path){
    return function(val) {
      var obj, key;
      ${loop}
      return {val:val, obj:obj, key:key};
    };
  })`;
 
  return {
    deps: [has, path] as unknown[],
    js,
  } as JavaScriptLinked<Fn>;
};
 
export const $findRef = (path: Path): Fn => compileClosure($$findRef(path));