All files / if-run/lib environment.ts

100% Statements 35/35
88.88% Branches 8/9
100% Functions 5/5
100% Lines 34/34

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 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 971x   1x 1x     1x     1x   1x               1x 5x   5x 5x   5x   5x       5x           1x 3x 61x 61x 61x   61x 61x       61x             1x 5x 5x   5x 3x   3x     2x           1x     5x   5x 5x 5x   5x                                
import {DateTime} from 'luxon';
 
import {osInfo} from '../util/os-checker';
import {execPromise} from '../../common/util/helpers';
import {Manifest} from '../../common/types/manifest';
 
import {STRINGS} from '../config/strings';
import {NpmListResponse, PackageDependency} from '../types/environment';
 
const packageJson = require('../../../package.json');
 
const {CAPTURING_RUNTIME_ENVIRONMENT_DATA} = STRINGS;
 
/**
 * 1. Gets the high-resolution real time when the application starts.
 * 2. Converts the high-resolution time to milliseconds.
 * 3. Gets the current DateTime.
 * 4. Subtracts the milliseconds from the current DateTime.
 */
const getProcessStartingTimestamp = () => {
  const startTime = process.hrtime();
 
  const [seconds, nanoseconds] = process.hrtime(startTime);
  const milliseconds = seconds * 1000 + nanoseconds / 1e6;
 
  const currentDateTime = DateTime.local();
 
  const applicationStartDateTime = currentDateTime.minus({
    milliseconds: milliseconds,
  });
 
  return applicationStartDateTime.toUTC().toString();
};
 
/**
 * Goes through the dependencies, converts them into oneliner.
 */
const flattenDependencies = (dependencies: [string, PackageDependency][]) =>
  dependencies.map(dependency => {
    const [packageName, versionInfo] = dependency;
    const {version, extraneous, resolved} = versionInfo;
    const ifExtraneous = extraneous ? ` extraneous -> ${resolved}` : '';
    const ifFromGithub =
      resolved && resolved.startsWith('git') ? ` (${resolved})` : '';
    const formattedString = `${packageName}@${version}${
      ifExtraneous || ifFromGithub
    }`;
 
    return formattedString;
  });
 
/**
 * 1. Runs `npm list --json`.
 * 2. Parses json data and converts to list.
 */
const listDependencies = async () => {
  const {stdout} = await execPromise('npm list --json');
  const npmListResponse: NpmListResponse = JSON.parse(stdout);
 
  if (npmListResponse.dependencies) {
    const dependencies = Object.entries(npmListResponse.dependencies);
 
    return flattenDependencies(dependencies);
  }
 
  return [];
};
 
/**
 * Injects execution information (command, environment) to existing manifest.
 */
export const injectEnvironment = async (
  manifest: Manifest
): Promise<Manifest> => {
  console.debug(CAPTURING_RUNTIME_ENVIRONMENT_DATA);
 
  const dependencies = await listDependencies();
  const info = await osInfo();
  const dateTime = `${getProcessStartingTimestamp()} (UTC)`;
 
  return {
    ...manifest,
    execution: {
      status: 'success',
      command: process.argv.join(' '),
      environment: {
        'if-version': packageJson.version,
        os: info.os,
        'os-version': info['os-version'],
        'node-version': process.versions.node,
        'date-time': dateTime,
        dependencies,
      },
    },
  };
};