All files json.js

98.21% Statements 55/56
94.73% Branches 36/38
100% Functions 5/5
98.21% Lines 55/56

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 579x 9x 9x 9x 9x 67x 67x 64x 67x 5x 17x 5x 67x 67x 67x 1x   67x 9x 5x 5x 5x 5x 5x 9x 9x 9x 71x 38x 13x 3x 71x 9x 69x 69x 40x 69x 9x 9x 9x 9x 9x 9x 10x 10x 10x 10x 71x 71x 71x 69x 69x 71x 71x 10x 10x  
// JSON bodies whose signed values equal the literal text that is sent (DESIGN 5.2, JSON-body calls).
import { localError } from './errors.js';
 
/** Plain decimal text of a finite number, never in exponent form. */
export function formatPlainNumber(n) {
  if (typeof n !== 'number' || !isFinite(n)) throw localError(90010, 'numbers must be finite');
  if (n === 0) return '0';
  const s = String(n);
  if (s.indexOf('e') < 0) return s;
  const m = /^(-?)(\d)(?:\.(\d+))?e([+-]\d+)$/.exec(s);
  if (!m) return s;
  const sign = m[1];
  const digits = m[2] + (m[3] || '');
  const point = 1 + parseInt(m[4], 10);
  if (point <= 0) return sign + '0.' + repeat('0', -point) + digits;
  if (point >= digits.length) return sign + digits + repeat('0', point - digits.length);
  return sign + digits.slice(0, point) + '.' + digits.slice(point);
}
 
function repeat(ch, n) {
  let s = '';
  for (let i = 0; i < n; i++) s += ch;
  return s;
}
 
/** Text of a top level scalar as it is signed: strings as is, numbers plain decimal, booleans true or false. */
export function scalarText(v) {
  if (typeof v === 'string') return v;
  if (typeof v === 'number') return formatPlainNumber(v);
  if (typeof v === 'boolean') return v ? 'true' : 'false';
  return null;
}
 
function jsonValue(v) {
  if (typeof v === 'number') return formatPlainNumber(v);
  return JSON.stringify(v);
}
 
/**
 * Serializes a flat object to JSON text and collects the signed set: every top level non null
 * scalar. Undefined and null fields are not sent. Nested objects and arrays are sent but not signed.
 */
export function buildJsonBody(obj) {
  const parts = [];
  const signSet = {};
  const keys = Object.keys(obj);
  for (let i = 0; i < keys.length; i++) {
    const k = keys[i];
    const v = obj[k];
    if (v === undefined || v === null) continue;
    parts.push(JSON.stringify(k) + ':' + jsonValue(v));
    const t = scalarText(v);
    if (t !== null) signSet[k] = t;
  }
  return { text: '{' + parts.join(',') + '}', signSet };
}