index.js
function readTo(stream, needle, options) {
  const endOK = Boolean(options && (options.endOK || options.endOk));
  let needleForIndexOf;
  let needleLength;
  function until(result, chunk, ended) {
    if (ended) {
      return endOK ? (result ? result.length : 0) : -1;
    }

    if (Array.isArray(result)) {
      // objectMode.  Use strict equality, like Array.prototype.indexOf
      return chunk === needle ? result.length : -1;
    }

    // Calculate the length of the needle, as used by indexOf and perform the
    // type conversion done by indexOf once, to avoid converting on every call
    if (needleLength === undefined) {
      if (typeof result === 'string') {
        needleForIndexOf = String(needle);
        needleLength = needleForIndexOf.length;
      } else if (result instanceof Buffer) {
        if (typeof needle === 'number') {
          // buffertools requires a Buffer or string
          // buffer-indexof-polyfill converts number to Buffer on each call
          needleForIndexOf = result.indexOf ? needle
            : Buffer.from ? Buffer.from([needle])
              // eslint-disable-next-line no-buffer-constructor
              : new Buffer([needle]);
          needleLength = 1;
        } else if (typeof needle === 'string') {
          needleForIndexOf = needle;
          needleLength = Buffer.byteLength(needle);
        } else if (needle instanceof Buffer) {
          needleForIndexOf = needle;
          needleLength = needle.length;
        }
      }

      if (needleLength === undefined) {
        throw new TypeError(`Unsupported indexOf argument types: ${
          Object.prototype.toString.call(result)}.indexOf(${
          Object.prototype.toString.call(needle)})`);
      }

      // Buffer.prototype.indexOf returns -1 for 0-length string/Buffer.
      // To be consistent with string, we return 0.
      // Note:  If removing this check, remove + 1 from start calc when 0.
      if (needleLength === 0) {
        return 0;
      }
    }

    const start =
      Math.max((result.length - chunk.length - needleLength) + 1, 0);
    const needleIndex = result.indexOf(needleForIndexOf, start);
    if (needleIndex < 0) {
      return -1;
    }

    return needleIndex + needleLength;
  }
  return readInternal(stream, undefined, until, options);
}
function readTo(stream, needle, options) {
  const endOK = Boolean(options && (options.endOK || options.endOk));
  let needleForIndexOf;
  let needleLength;
  function until(result, chunk, ended) {
    if (ended) {
      return endOK ? (result ? result.length : 0) : -1;
    }

    if (Array.isArray(result)) {
      // objectMode.  Use strict equality, like Array.prototype.indexOf
      return chunk === needle ? result.length : -1;
    }

    // Calculate the length of the needle, as used by indexOf and perform the
    // type conversion done by indexOf once, to avoid converting on every call
    if (needleLength === undefined) {
      if (typeof result === 'string') {
        needleForIndexOf = String(needle);
        needleLength = needleForIndexOf.length;
      } else if (result instanceof Buffer) {
        if (typeof needle === 'number') {
          // buffertools requires a Buffer or string
          // buffer-indexof-polyfill converts number to Buffer on each call
          needleForIndexOf = result.indexOf ? needle
            : Buffer.from ? Buffer.from([needle])
              // eslint-disable-next-line no-buffer-constructor
              : new Buffer([needle]);
          needleLength = 1;
        } else if (typeof needle === 'string') {
          needleForIndexOf = needle;
          needleLength = Buffer.byteLength(needle);
        } else if (needle instanceof Buffer) {
          needleForIndexOf = needle;
          needleLength = needle.length;
        }
      }

      if (needleLength === undefined) {
        throw new TypeError(`Unsupported indexOf argument types: ${
          Object.prototype.toString.call(result)}.indexOf(${
          Object.prototype.toString.call(needle)})`);
      }

      // Buffer.prototype.indexOf returns -1 for 0-length string/Buffer.
      // To be consistent with string, we return 0.
      // Note:  If removing this check, remove + 1 from start calc when 0.
      if (needleLength === 0) {
        return 0;
      }
    }

    const start =
      Math.max((result.length - chunk.length - needleLength) + 1, 0);
    const needleIndex = result.indexOf(needleForIndexOf, start);
    if (needleIndex < 0) {
      return -1;
    }

    return needleIndex + needleLength;
  }
  return readInternal(stream, undefined, until, options);
}
function readTo ( stream , needle , options ) { const endOK = Boolean ( options && ( options . endOK || options . endOk ) ) ; let needleForIndexOf ; let needleLength ; function until ( result , chunk , ended ) { if ( ended ) { return endOK ? ( result ? result . length : 0 ) : - 1 ; } if ( Array . isArray ( result ) ) { // objectMode.  Use strict equality, like Array.prototype.indexOf return chunk === needle ? result . length : - 1 ; } // Calculate the length of the needle, as used by indexOf and perform the // type conversion done by indexOf once, to avoid converting on every call if ( needleLength === undefined ) { if ( typeof result === 'string' ) { needleForIndexOf = String ( needle ) ; needleLength = needleForIndexOf . length ; } else if ( result instanceof Buffer ) { if ( typeof needle === 'number' ) { // buffertools requires a Buffer or string // buffer-indexof-polyfill converts number to Buffer on each call needleForIndexOf = result . indexOf ? needle : Buffer . from ? Buffer . from ( [ needle ] ) // eslint-disable-next-line no-buffer-constructor : new Buffer ( [ needle ] ) ; needleLength = 1 ; } else if ( typeof needle === 'string' ) { needleForIndexOf = needle ; needleLength = Buffer . byteLength ( needle ) ; } else if ( needle instanceof Buffer ) { needleForIndexOf = needle ; needleLength = needle . length ; } } if ( needleLength === undefined ) { throw new TypeError ( ` ${ Object . prototype . toString . call ( result ) } ${ Object . prototype . toString . call ( needle ) } ` ) ; } // Buffer.prototype.indexOf returns -1 for 0-length string/Buffer. // To be consistent with string, we return 0. // Note:  If removing this check, remove + 1 from start calc when 0. if ( needleLength === 0 ) { return 0 ; } } const start = Math . max ( ( result . length - chunk . length - needleLength ) + 1 , 0 ) ; const needleIndex = result . indexOf ( needleForIndexOf , start ) ; if ( needleIndex < 0 ) { return - 1 ; } return needleIndex + needleLength ; } return readInternal ( stream , undefined , until , options ) ; }
Reads from a stream.Readable until a given value is found.

<p>This function calls {@link readUntil} with an <code>until</code> function
which uses <code>.indexOf</code> to search for <code>needle</code>.  When
reading Buffers and performance is paramount, consider using
{@link readUntil} directly with an optional function for the problem (e.g.
{@link
https://www.npmjs.com/package/buffer-indexof-fast buffer-indexof-fast} for
single-character search).</p>

<p>Doc note:  options should be a ReadToOptions type which extends
{@link ReadOptions}, but record types can't currently be extended.
See {@link https://github.com/google/closure-compiler/issues/604}.</p>

@param {stream.Readable} stream Stream from which to read.
@param {!Buffer|string|*} needle Value to search for in the read result.
The stream will be read until this value is found or <code>'end'</code> or
<code>'error'</code> is emitted.
@param {ReadOptions=} options Options.  This function additionally supports
an <code>endOK</code> option which prevents {@link EOFError} on
<code>'end'</code>.
@return {Promise<Buffer|string|Array>|
CancellableReadPromise<Buffer|string|Array>} Promise with the data read, up
to and including <code>needle</code>, or an Error if one occurs.  If
<code>stream</code> does not support <code>unshift</code>, the result may
include additional data.  If <code>'end'</code> is emitted before
<code>needle</code> is found, an {@link EOFError} is returned, unless
<code>options.endOK</code> is truthy in which case any remaining data is
returned or <code>null</code> if none was read.  If an error occurs after
reading some data, the <code>.read</code> property of the error object will
contain the partial read result.  The promise is resolved synchronously for
streams in flowing mode (see README.md for details).
Reads from a stream . Readable until a given value is found .