All files / cli/src/commands bundle.ts

92.3% Statements 12/13
50% Branches 2/4
100% Functions 4/4
92.3% Lines 12/13

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                                                        7x 7x 7x 7x 5x 5x 4x                             2x 2x 2x   4x                                 1x      
import type { Logger } from '@metamask/logger';
import { glob } from 'glob';
import { writeFile } from 'node:fs/promises';
import { resolve, join } from 'node:path';
 
import { isDirectory } from '../file.ts';
import { resolveBundlePath } from '../path.ts';
import { bundleVat } from '../vite/vat-bundler.ts';
 
type BundleFileOptions = {
  logger: Logger;
  targetPath?: string;
};
 
/**
 * Create a bundle given path to an entry point.
 *
 * @param sourcePath - Path to the source file that is the root of the bundle.
 * @param options - Options for bundling the file.
 * @param options.logger - The logger to use for logging (required).
 * @param options.targetPath - Optional path to which to write the bundle.
 *  If not provided, defaults to sourcePath with `.bundle` extension.
 * @returns A promise that resolves when the bundle has been written.
 */
export async function bundleFile(
  sourcePath: string,
  options: BundleFileOptions,
): Promise<void> {
  const { logger, targetPath } = options;
  const sourceFullPath = resolve(sourcePath);
  const bundlePath = targetPath ?? resolveBundlePath(sourceFullPath);
  const bundle = await bundleVat(sourceFullPath);
  const bundleContent = JSON.stringify(bundle);
  await writeFile(bundlePath, bundleContent);
  logger.info(`Wrote ${bundlePath}: ${new Blob([bundleContent]).size} bytes`);
}
 
/**
 * Create a bundle given path to an entry point.
 *
 * @param sourceDir - Path to a directory of source files to bundle.
 * @param options - Options for bundling the directory.
 * @param options.logger - The logger to use for logging (required).
 * @returns A promise that resolves when the bundles have been written.
 */
export async function bundleDir(
  sourceDir: string,
  options: { logger: Logger },
): Promise<void> {
  const { logger } = options;
  logger.info('Bundling directory:', sourceDir);
  await Promise.all(
    (await glob(join(sourceDir, '*.{js,ts}'))).map(
      async (source) => await bundleFile(source, { logger }),
    ),
  );
}
 
/**
 * Bundle a target file or every file in the target directory.
 *
 * @param target - The file or directory to apply the bundler to.
 * @param logger - The logger to use for logging.
 *
 * @returns A promise that resolves when bundling is done.
 */
export async function bundleSource(
  target: string,
  logger: Logger,
): Promise<void> {
  const targetIsDirectory = await isDirectory(target);
  await (targetIsDirectory ? bundleDir : bundleFile)(target, { logger });
}