%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /www/specpages-backup/node_modules/warehouse/lib/jsonstream/
Upload File :
Create Path :
Current File : /www/specpages-backup/node_modules/warehouse/lib/jsonstream/index.js

'use strict';

const through2 = require('through2');
const Parser = require('jsonparse');

/**
 * Check whether a x and y are equal, or x matches y, or x(y) is truthy.
 * @param {boolean | string | RegExp | (args: any[]) => boolean} x
 * @param {*} y
 * @returns {boolean}
 */
const check = (x, y) => {
  if (typeof x === 'string') {
    return y === x;
  }

  if (x && typeof x.exec === 'function') {
    return x.exec(y);
  }

  if (typeof x === 'boolean' || typeof x === 'object') {
    return x;
  }

  if (typeof x === 'function') {
    return x(y);
  }

  return false;
};

module.exports.parse = function(path, map) {
  let header, footer;

  const parser = new Parser();
  const stream = through2.obj(
    (chunk, enc, cb) => {
      if (typeof chunk === 'string') {
        chunk = Buffer.from(chunk);
      }
      parser.write(chunk);
      cb();
    },
    cb => {
      if (header) {
        stream.emit('header', header);
      }
      if (footer) {
        stream.emit('footer', footer);
      }

      if (parser.tState !== Parser.C.START || parser.stack.length > 0) {
        cb(new Error('Incomplete JSON'));
        return;
      }

      cb();
    }
  );

  if (typeof path === 'string') {
    path = path.split('.').map(e => {
      if (e === '$*') {
        return { emitKey: true };
      }
      if (e === '*') {
        return true;
      }
      if (e === '') {
        // '..'.split('.') returns an empty string
        return { recurse: true };
      }
      return e;
    });
  }


  if (!path || !path.length) {
    path = null;
  }

  parser.onValue = function(value) {
    if (!this.root) { stream.root = value; }

    if (!path) return;

    let i = 0; // iterates on path
    let j = 0; // iterates on stack
    let emitKey = false;
    let emitPath = false;
    while (i < path.length) {
      const key = path[i];
      let c;
      j++;

      if (key && !key.recurse) {
        c = j === this.stack.length ? this : this.stack[j];
        if (!c) return;
        if (!check(key, c.key)) {
          setHeaderFooter(c.key, value);
          return;
        }
        emitKey = !!key.emitKey;
        emitPath = !!key.emitPath;
        i++;
      } else {
        i++;
        const nextKey = path[i];
        if (!nextKey) return;

        // eslint-disable-next-line no-constant-condition
        while (true) {
          c = j === this.stack.length ? this : this.stack[j];
          if (!c) return;
          if (check(nextKey, c.key)) {
            i++;
            if (!Object.isFrozen(this.stack[j])) {
              this.stack[j].value = null;
            }
            break;
          } else {
            setHeaderFooter(c.key, value);
          }
          j++;
        }
      }

    }

    // emit header
    if (header) {
      stream.emit('header', header);
      header = false;
    }
    if (j !== this.stack.length) return;

    const actualPath = this.stack.slice(1).map(element => element.key);
    actualPath.push(this.key);

    let data = this.value[this.key];
    if (data != null) {
      if ((data = map ? map(data, actualPath) : data) != null) {
        if (emitKey || emitPath) {
          data = {
            value: data
          };
          if (emitKey) {
            data.key = this.key;
          }
          if (emitPath) {
            data.path = actualPath;
          }
        }

        stream.push(data);
      }
    }

    delete this.value[this.key];

    for (const k in this.stack) {
      if (!Object.isFrozen(this.stack[k])) {
        this.stack[k].value = null;
      }
    }
  };
  parser._onToken = parser.onToken;

  parser.onToken = function(token, value) {
    parser._onToken(token, value);
    if (this.stack.length === 0) {
      if (stream.root) {
        if (!path) { stream.push(stream.root); }

        stream.root = null;
      }
    }
  };

  parser.onError = function(err) {
    if (err.message.includes('at position')) {
      err.message = 'Invalid JSON (' + err.message + ')';
    }
    stream.destroy(err);
  };

  return stream;

  function setHeaderFooter(key, value) {
    // header has not been emitted yet
    if (header !== false) {
      header = header || {};
      header[key] = value;
    }

    // footer has not been emitted yet but header has
    if (footer !== false && header === false) {
      footer = footer || {};
      footer[key] = value;
    }
  }
};

Zerion Mini Shell 1.0