npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gkalpak/ng-maintain-utils

v0.1.3

Published

A private collection of utilities for developing tools to help maintain (AngularJS-related) GitHub repositories.

Readme

ng-maintain-utils Build Status

Description

A private collection of utilities for developing tools to help maintain (AngularJS-related) GitHub repositories.

Usage

You should generally not use it. You would use tools built on top of it, for example:

I may use it for building other tools (see above). Here is a brief overview of what's in the box:

  • AbstractCli: Can serve as a base-class for creating a Cli object that can orchestrate the execution of some type of work, based on a list of "raw" command-line arguments. It can display version info (with --version), show usage instructions (with --usage), outline the commands that need to be executed to complete the task at hand (with --instructions) - a sort of "dry-run", report the beginning/end of execution, etc.

    It exposes the following (public) methods:

    • getPhases(): Phase[] (abstract): This method must be overwritten and return an array of Phase objects (to be used for displaying instructions in the "dry-run" mode).
    • run(rawArgs: string[], doWork?: ({[key: string]: string}) => any): Promise: Parse the arguments and take appropriate action (see above).

    It also provides a number of "protected" methods, that can be overwritten by sub-classes:

    • _displayExperimentalTool(): void
    • _displayHeader(headerTmpl: string, input: {[key: string]: string}): void
    • _displayInstructions(phases: Phase[], input: {[key: string]: string}): void
    • _displayUsage(usageMessage: string): void
    • _displayVersionInfo(): void
    • _getAndValidateInput(rawArgs: string[], argSpecs: ArgSpec[]): Promise<{[key: string]: string}>
    • _insertEmptyLine<T>(value: T, isRejection?: boolean): T|Promise<T>
    • _theHappyEnd<T>(value: T): T
    • _theUnhappyEnd(err: any): Promise<any>

    Requires:

    • config: Config
  • ArgSpec/ArgSpec.Unnamed: Represents the specification for a command-line argument. When applied on a parsed arguments object (such as the ones returned by Utils#parseArgs()) it will extract the corresponding argument's value (either by name (ArgSpec) or by position (ArgSpec.Unnamed)), fall back to a default value if necessary, vaidate the value and assign it to the specified input object under the appropriate key.

    Requires:

    • index: number (ArgSpec.Unnamed only)
    • key: string
    • validator: (value: any) => boolean
    • errorCode: string
    • defaultValue?: string|boolean
  • CleanUper: A utility to help coordinate arbitrary tasks with their associated clean-up process.

    The general idea is this:

    1. Schedule a task to clean up after something.
    2. Do something.
    3. ...possibly do other things here...
    4. If anything goes wrong, the app will be able to clean up (or show instructions to the user).
    5. When cleaning up after something is no longer necessary, unschedule the clean-up task.

    Provides the following methods:

    • cleanUp(listOnly: boolean): Promise: Perform all clean-up tasks (or just list them). (Either way, the clean-up task queue is emptied.)
    • getCleanUpPhase(): Phase: Returns a clean-up Phase object (suitable for UiUtils#phase()).
    • hasTasks(): boolean: Returns whether or not there are any clean-up tasks scheduled.
    • registerTask(description: string, cb: () => Promise): TaskId: Register a task with the CleanUper. You can use the returned, unique TaskId for scheduling/unscheduling the task.
    • schedule(taskId: TaskId): void: Schedule a clean-up task.
    • unschedule(taskId: TaskId): void: Schedule (the last instance of) a clean-up task.
    • withTask(taskId: TaskId, fn: () => any): Promise: Schedule taskId and execute fn (can also return a promise). If all goes well, unschedule taskId. If an error occurs, leave taskId in the clean-up task queue.

    Requires:

    • logger: Logger
  • Config: Creates a Config object based on the specified messages and argSpecs (falling back to some default values if necessary). It exposes the following properties:

    • argSpecs: A (possibly empty) array of ArgSpec objects.
    • defaults: A {[argument: string]: string|number} map of default values per command-line argument keys. (Automatically extracted for argSpecs.)
    • messages: A (possibly nested) {[messageKey: string]: string} map with at least the following messages:
      • usage
      • instructionsHeaderTmpl
      • headerTmpl
      • errors:
        • ERROR_unexpected
      • warnings:
        • WARN_experimentalTool
    • versionInfo: A {name: string, version: string} map with values retrieved from the main module's package.json (i.e. the first package.json to be found starting from the main file's directory and moving upwards).

    Requires:

    • messages: {[messageKey: string]: string}
    • argSpecs: ArgSpec[]
  • GitUtils: A collection of Git-related command-wrappers and utilities. Mainly spawns Git commands in a separate process and (promises to) return the output. Support for commands is added in an "as-needed" basis. Currently, the available commands/utilities include:

    • abortAm(): Promise
    • abortRebase(): Promise
    • checkout(branch: string): Promise
    • clean(mode?: string = 'interactive'): Promise
    • countCommitsSince(commit: string): Promise<number>
    • createBranch(branch: string): Promise
    • deleteBranch(branch: string, force?: boolean): Promise
    • diff(commit: string, noColor?: boolean): Promise
    • diffWithHighlight(commit: string): Promise
    • diffWithHighlight2(commit: string): Promise
    • getCommitMessage(commit: string): Promise<string>
    • getLastCommitMessage(): Promise<string>
    • log(oneline?: boolean, count?: number, noDecorate?: boolean): Promise
    • mergePullRequest(prUrl: string): Promise
    • pull(branch: string, rebase?: boolean): Promise
    • push(branch: string): Promise
    • rebase(commit: string|number, interactive?: boolean): Promise
    • reset(commit: string, hard?: boolean): Promise
    • setLastCommitMessage(message: string): Promise
    • updateLastCommitMessage(getNewMessage: (oldMessage: string) => string): Promise

    Requires:

    • cleanUper: CleanUper
    • utils: Utils
  • GitUtils.DiffHighlighter: Can be used to enhance a diff by highlighting areas of interest. The general implementation is loosely based on the idea of diff-highlight, although the matching heuristics and coloring (among other things) are different.

    It exposes the underlying streams via:

    • getInputStream(): stream.PassThrough
    • getOutputStream(): stream.PassThrough

    Requires:

    • styles?:

      {
        lineRemoved?: (text: string) => string,
        lineAdded?: (text: string) => string,
        areaRemoved?: (text: string) => string,
        areaAdded?: (text: string) => string
      }
  • GitUtils.DiffHighlighter2: An alternative, API-compatible implementation of GitUtils.DiffHighlighter. The highlighting is more accurate, as it is able to only highlight the regions that have changed. The main drawback is that it fails to show removed/added empty lines, because of its dependency on Gits --word-diff=plain option.

    Similar to GitUtils.DiffHighlighter, it exposes the underlying streams via:

    • getInputStream(): stream.PassThrough
    • getOutputStream(): stream.PassThrough

    Requires:

    • styles?:

      {
        lineRemoved?: (text: string) => string,
        lineAdded?: (text: string) => string,
        areaRemoved?: (text: string) => string,
        areaAdded?: (text: string) => string
      }
  • Logger: A simple helper providing minimal logging utilities. This is mostly used in order to make it easier to test logging behavior without affecting console methods. Provides the following methods:

    • debug(): Delegate to console.debug().
    • error(): Delegate to console.error().
    • info(): Delegate to console.info().
    • log(): Delegate to console.log().
    • warn(): Delegate to console.warn().
  • Phase: A simple wrapper for "phase" entities (with validation). A "phase" is a description of a unit of work, including an ID, a short description, a list of the tasks involved and an error message (or code) specific to this "phase".

    Requires:

    • id: string
    • description: string
    • instructions?: string[]
    • error?: string (Can be either an error message or an error code.)
  • UiUtils: A collection of utilities useful for interacting with the user, including:

    • askQuestion(): Prompt the user with a question and (promise to) return the answer.
    • askYesOrNoQuestion(): Prompt the user with a yes-or-no question (e.g. a confirmation) and (promise to) resolve (for "yes") or reject (for "no").
    • offerToCleanUp(): Requests confirmation to perform the scheduled clean-up tasks. If the user turns the offer down, it will just list the pending tasks instead.
    • phase(): It will report the beginning and end of a "phase" (see Phase), do some work and properly handle possible errors (by means of reportAndRejectFnGen()).
    • reportAndRejectFnGen(): Generates a callback that will report the specified error (plus any extra error provided during invokation), will offer to clean up (if there are pending tasks and not configured otherwise) and return a rejection.

    Requires:

    • logger: Logger
    • cleanUper: CleanUper
    • errorMessages: {[errorCode: string]: string}
  • Utils: A collection of low-level, specific-purpose utilities, including:

    • asPromised(): Convert callback-based functions to promise-based.
    • interpolate(): Replace {{...}} placeholders in a string with values.
    • parseArgs(): Parse command-line arguments (and remove surrounding quotes).
    • resetOutputStyleOnExit(): Ensure the output style is reset when a process exists.
    • spawnAsPromised(): Spawn a sub-shell to run a (series of) command(s) with support for piping.
    • waitAsPromised(): setTimeout() wrapped in a promise.

Testing

The following test-types/modes are available:

  • Code-linting: npm run lint Lint JavaScript files using ESLint.

  • Unit tests: npm run test-unit Run all the unit tests once. These tests are quick and suitable to be run on every change.

  • E2E tests: npm run test-e2e Run all the end-to-end tests once. These test may hit actual API endpoints or perform expensive I/O operations and are considerably slower than unit tests.

  • All tests: npm test / npm run test Run all of the above tests (code-linting, unit tests, e2e tests). This command is automatically run before npm version and npm publish.

  • "Watch" mode: npm run test-watch Watch all files and rerun the unit tests whenever something changes. For performance reasons, code-linting and e2e tests are omitted.