Skip to content

bingo-systems

File, network, and shell wrapper APIs used by Bingo. šŸ§°

Terminal window
npm i bingo-systems

The bingo-systems package contains functions and types for the shared wrapper APIs used by Bingo templates. These wrappers are made available to templates via Input Contexts.

BingoSystem

The BingoSystem interface describes the shared object used by many Bingo APIs.

import { SystemFetchers, WritingFileSystem, SystemRunner } from "bingo-systems";
export interface BingoSystem {
fetchers: SystemFetchers;
fs: WritingFileSystem;
runner: SystemRunner;
}

The properties of BingoSystem describe three areas of native APIs:

  • fetchers: sending network requests
  • fs: interacting with directories and files on disk
  • runner: executing shell commands

Fetchers

Wrappers around sending network requests with fetch.

import { Octokit } from "octokit";
export interface SystemFetchers {
fetch: typeof fetch;
octokit: Octokit;
}

The octokit property is also available as a convenience for sending GitHub API requests. This is typically used to populate repository settings via the API.

createSystemFetchers

Creates a new SystemFetchers instance.

import { createSystemFetchers } from "bingo-systems";
const fetchers = createSystemFetchers();
await fetchers.fetch("...");

Takes in an optional object parameter with up to two properties:

  • auth (string): a GitHub auth token to pass to the octokit
  • fetch: a function to use in place of the global fetch
    • This is used both for the fetch property and in the octokit

auth

A GitHub auth token to pass to the octokit.

If not provided, the octokit will run as an anonymous user without authentication.

For example, this authenticates with the running userā€™s auth token if possible via get-github-auth-token:

import { createSystemFetchers } from "bingo-systems";
import { getGitHubAuthToken } from "get-github-auth-token";
const auth = await getGitHubAuthToken();
createSystemFetchers({
auth: auth.succeeded ? auth.token : undefined,
});

fetch

A function to use in place of the global fetch.

This can be useful if youā€™d like network requests to be instrumented and/or run in a virtual environment.

For example, this adds logging to all network requests, including those in the octokit:

import { createSystemFetchers } from "bingo-systems";
createSystemFetchers({
fetch: (...args) => {
const request = new Request(...args);
request.headers.set("Authorization", "Bearer ...");
return await fetch(request);
},
});

createSystemFetchersOffline

A version of [createSystemFetchers] that throws errors inside network requests. It takes no parameters.

import { createSystemFetchersOffline } from "bingo-systems";
const fetchers = createSystemFetchersOffline();
// Error: Offline specified. This request should be caught by its Input.
await fetchers.fetch("...");

Bingo uses this function when the --offline flag is enabled.

createSystemFetchersWithAuth

An asynchronous version of createSystemFetchers that retrieves the running userā€™s GitHub auth token, if possible.

import { createSystemFetchersWithAuth } from "bingo-systems";
const fetchers = createSystemFetchersWithAuth();
await fetchers.fetch("...");

createSystemFetchersWithAuth takes in the same optional parameter properties as createSystemFetchers, except for auth.

Files

Wrappers around accessing directories and files with node:fs.

ReadingFileSystem

Reading file systems are provided to Input Contexts. These file systems expose simplified views of the underlying directories and files that are tailored to working with bingo-fs.

export type ReadDirectory = (filePath: string) => Promise<string[]>;
export type ReadFile = (filePath: string) => Promise<string>;
export interface ReadingFileSystem {
readDirectory: ReadDirectory;
readFile: ReadFile;
}

createReadingFileSystem

Creates a new ReadingFileSystem instance. Internally, it calls to node:fs to read directories and files.

import { createReadingFileSystem } from "bingo-systems";
const files = createReadingFileSystem();
await files.readDirectory("src");
await files.readFile("src/index.js");

WritingFileSystem

Writing file systems are provided to runTemplate. These expose a superset of the reading APIs by adding in methods to write to the file system.

export interface WritingFileSystem extends ReadingFileSystem {
writeDirectory: WriteDirectory;
writeFile: WriteFile;
}

createWritingFileSystem

Creates a new WritingFileSystem instance. Internally, it calls to node:fs to read and write directories and files.

import { createWritingFileSystem } from "bingo-systems";
const files = createWritingFileSystem();
await files.writeDirectory("src");
await files.readFile("src/index.js", `console.log("Hello, world!");`);

Runner

Wrapper around executing shell commands with execa.

import { ExecaError, Result } from "execa";
export type SystemRunner = (command: string) => Promise<ExecaError | Result>;

createSystemRunner

Creates a new SystemRunner function. Internally it calls to execa with reject: false to return an error instead of rejecting.

import { createSystemRunner } from "bingo-systems";
const runner = createSystemRunner();
await runner("git branch -D master");

createSystemRunner takes a single parameter:

  • directory (string): the current working directory to execute from (by default, ".")

createSystemRunner returns either:

import { createSystemRunner } from "bingo-systems";
const runner = createSystemRunner();
const result = await runner("git tag -l");
if (result.failed) {
console.error(result.stderr);
} else {
console.log(result.stdout);
}
Made with šŸ’ in Boston by Josh Goldberg.