<commit_before>import fs from 'fs';
import path from 'path';
import os from 'os';
import crypto from 'crypto';

import Archiver from 'archiver';

import { performance } from 'perf_hooks';

import { FILE_CREATION_DATE } from './createStaticPackage';
import Logger, { logTag } from './Logger';
import constructReport from './constructReport';
import createHash from './createHash';
import loadCSSFile from './loadCSSFile';
import makeRequest from './makeRequest';

function staticDirToZipFile(dir) {
  return new Promise((resolve, reject) => {
    const archive = new Archiver('zip');
    const rnd = crypto.randomBytes(4).toString('hex');
    const pathToZipFile = path.join(os.tmpdir(), `happo-static-${rnd}.zip`);
    const output = fs.createWriteStream(pathToZipFile);

    output.on('finish', () => {
      resolve(pathToZipFile);
    });
    archive.pipe(output);
    archive.directory(dir, false, { date: FILE_CREATION_DATE });
    archive.on('error', reject);
    archive.finalize();
  });
}

async function resolvePackageData(staticPackage) {
  if (typeof staticPackage === 'string') {
    // legacy plugins
    const buffer = Buffer.from(staticPackage, 'base64');
    return { value: buffer, hash: createHash(buffer) };
  }

  if (!staticPackage.path) {
    throw new Error(
      'Expected `staticPackage` to be an object with the following structure: `{ path: "path/to/folder" }`',
    );
  }

  const file = await staticDirToZipFile(staticPackage.path);
  const readStream = fs.createReadStream(file);
  const hash = await new Promise((resolve) => {
    const hashCreator = crypto.createHash('md5');
    readStream.pipe(hashCreator);
    hashCreator.setEncoding('hex');
    readStream.on('end', () => {
      hashCreator.end();
      resolve(hashCreator.read());
    });
  });
  return { value: readStream, hash };
}

async function uploadStaticPackage({ staticPackage, endpoint, apiKey, apiSecret }) {
  const { value, hash } = await resolvePackageData(staticPackage);
  const assetsRes = await makeRequest(
    {
      url: `${endpoint}/api/snap-requests/assets/${hash}`,
      method: 'POST',
      json: true,
      formData: {
        payload: {
          options: {
            filename: 'payload.zip',
            contentType: 'application/zip',
          },
          value,
        },
      },
    },<commit_msg>Recreate file stream before upload<commit_after>import fs from 'fs';
import path from 'path';
import os from 'os';
import crypto from 'crypto';

import Archiver from 'archiver';

import { performance } from 'perf_hooks';

import { FILE_CREATION_DATE } from './createStaticPackage';
import Logger, { logTag } from './Logger';
import constructReport from './constructReport';
import createHash from './createHash';
import loadCSSFile from './loadCSSFile';
import makeRequest from './makeRequest';

function staticDirToZipFile(dir) {
  return new Promise((resolve, reject) => {
    const archive = new Archiver('zip');
    const rnd = crypto.randomBytes(4).toString('hex');
    const pathToZipFile = path.join(os.tmpdir(), `happo-static-${rnd}.zip`);
    const output = fs.createWriteStream(pathToZipFile);

    output.on('finish', () => {
      resolve(pathToZipFile);
    });
    archive.pipe(output);
    archive.directory(dir, false, { date: FILE_CREATION_DATE });
    archive.on('error', reject);
    archive.finalize();
  });
}

async function resolvePackageData(staticPackage) {
  if (typeof staticPackage === 'string') {
    // legacy plugins
    const buffer = Buffer.from(staticPackage, 'base64');
    return { value: buffer, hash: createHash(buffer) };
  }

  if (!staticPackage.path) {
    throw new Error(
      'Expected `staticPackage` to be an object with the following structure: `{ path: "path/to/folder" }`',
    );
  }

  const file = await staticDirToZipFile(staticPackage.path);
  const readStream = fs.createReadStream(file);
  const hash = await new Promise((resolve) => {
    const hashCreator = crypto.createHash('md5');
    readStream.pipe(hashCreator);
    hashCreator.setEncoding('hex');
    readStream.on('end', () => {
      hashCreator.end();
      resolve(hashCreator.read());
    });
  });
  readStream.destroy();
  return { value: fs.createReadStream(file), hash };
}

async function uploadStaticPackage({ staticPackage, endpoint, apiKey, apiSecret }) {
  const { value, hash } = await resolvePackageData(staticPackage);
  const assetsRes = await makeRequest(
    {
      url: `${endpoint}/api/snap-requests/assets/${hash}`,
      method: 'POST',
      json: true,
      formData: {
        payload: {
          options: {
            filename: 'payload.zip',
            contentType: 'application/zip',
          },
          value,
        },
      },
    },
{'fraction_non_alphanumeric': 0.14288738357324302, 'fraction_numerical': 0.001693480101608806, 'mean_word_length': 3.48292220113852, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6845210', 'n_tokens_mistral': 1384, 'n_tokens_neox': 1371, 'n_words': 341}