File Explorer

/var/runtime/node_modules/@aws-sdk/node_modules/axios/lib/helpers

This explorer reads the filesystem of the server it runs on, so /workspace/user isn't present here. Browsing and the terminal still work against this server's own disk from /.

formDataToStream.js3.0 KB · 120 lines
import util from 'util';import { Readable } from 'stream';import utils from '../utils.js';import readBlob from './readBlob.js';import platform from '../platform/index.js'; const BOUNDARY_ALPHABET = platform.ALPHABET.ALPHA_DIGIT + '-_'; const textEncoder = typeof TextEncoder === 'function' ? new TextEncoder() : new util.TextEncoder(); const CRLF = '\r\n';const CRLF_BYTES = textEncoder.encode(CRLF);const CRLF_BYTES_COUNT = 2; class FormDataPart {  constructor(name, value) {    const { escapeName } = this.constructor;    const isStringValue = utils.isString(value);     let headers = `Content-Disposition: form-data; name="${escapeName(name)}"${      !isStringValue && value.name ? `; filename="${escapeName(value.name)}"` : ''    }${CRLF}`;     if (isStringValue) {      value = textEncoder.encode(String(value).replace(/\r?\n|\r\n?/g, CRLF));    } else {      const safeType = String(value.type || 'application/octet-stream').replace(/[\r\n]/g, '');      headers += `Content-Type: ${safeType}${CRLF}`;    }     this.headers = textEncoder.encode(headers + CRLF);     this.contentLength = isStringValue ? value.byteLength : value.size;     this.size = this.headers.byteLength + this.contentLength + CRLF_BYTES_COUNT;     this.name = name;    this.value = value;  }   async *encode() {    yield this.headers;     const { value } = this;     if (utils.isTypedArray(value)) {      yield value;    } else {      yield* readBlob(value);    }     yield CRLF_BYTES;  }   static escapeName(name) {    return String(name).replace(      /[\r\n"]/g,      (match) =>        ({          '\r': '%0D',          '\n': '%0A',          '"': '%22',        })[match]    );  }} const formDataToStream = (form, headersHandler, options) => {  const {    tag = 'form-data-boundary',    size = 25,    boundary = tag + '-' + platform.generateString(size, BOUNDARY_ALPHABET),  } = options || {};   if (!utils.isFormData(form)) {    throw TypeError('FormData instance required');  }   if (boundary.length < 1 || boundary.length > 70) {    throw Error('boundary must be 10-70 characters long');  }   const boundaryBytes = textEncoder.encode('--' + boundary + CRLF);  const footerBytes = textEncoder.encode('--' + boundary + '--' + CRLF);  let contentLength = footerBytes.byteLength;   const parts = Array.from(form.entries()).map(([name, value]) => {    const part = new FormDataPart(name, value);    contentLength += part.size;    return part;  });   contentLength += boundaryBytes.byteLength * parts.length;   contentLength = utils.toFiniteNumber(contentLength);   const computedHeaders = {    'Content-Type': `multipart/form-data; boundary=${boundary}`,  };   if (Number.isFinite(contentLength)) {    computedHeaders['Content-Length'] = contentLength;  }   headersHandler && headersHandler(computedHeaders);   return Readable.from(    (async function* () {      for (const part of parts) {        yield boundaryBytes;        yield* part.encode();      }       yield footerBytes;    })()  );}; export default formDataToStream;