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

cf-safe-deploy

v0.6.0

Published

Safety net for manual Cloud Foundry MTA deployments: verifies the targeted org/space against a whitelist, enforces git branch rules for protected targets and asks for confirmation before the deploy proceeds

Downloads

830

Readme

Cloud Foundry Deploy Safe-Guard

npm version

cf-safe-deploy demo: resolved target details, a bordered PRODUCTION deployment warning, and the confirmation prompt

A safety net for manual Cloud Foundry MTA deployments, meant to run as an npm predeploy hook. Before your cf deploy starts, it

  • verifies the currently targeted CF org/space (cf target) against a whitelist committed to your repository,
  • optionally enforces git branch rules for protected targets (must be on a specific branch, must not be behind the upstream),
  • prints a prominent warning banner for production targets, and
  • asks for interactive confirmation before the deploy proceeds.

It exists because cf deploy happily ships whatever you are currently targeting — one stale cf target and your feature branch lands in production.

This is a client-side convenience guard, not a security boundary. It protects against accidents, not intent (anyone can run cf deploy directly). Protect production with CF space roles / restricted space developers and CI-only production deployments; use this tool as an additional local safety net.

Install

npm i -D cf-safe-deploy

Requirements:

  • Node.js >= 18
  • cf CLI installed and logged in (cf login)
  • git on the PATH if you use requireBranch / requireUpToDate

The package has zero runtime dependencies.

Wiring it up

npm runs the predeploy script automatically before deploy. If predeploy exits non-zero, the deploy never starts:

// package.json
{
  "scripts": {
    "predeploy": "cf-safe-deploy",
    "deploy": "cf deploy mta_archives/archive.mtar"
  }
}

Then create a .cf-safe-deploy.json next to your package.json (any parent directory works — the file is searched upward from the current working directory):

{
  "allowedTargets": [
    { "org": "acme-dev", "space": "web-apps" },
    { "org": "acme-test", "space": "web-apps" },
    {
      "org": "acme-prod",
      "space": "web-apps",
      "region": "eu10-004",
      "requireBranch": "release",
      "requireUpToDate": true,
      "warnProduction": true
    }
  ]
}

With this config, npm run deploy:

  • is blocked for any org/space not in the list,
  • for acme-prod/web-apps additionally requires the targeted API endpoint to be on the eu10-004 region, you to be on the release branch and not behind its remote tracking branch (a git fetch is run first), and shows a red PRODUCTION banner,
  • always ends with Continue with deploy to <org>/<space>? (y/N): — only y/yes (case-insensitive) proceeds.

Configuration reference

.cf-safe-deploy.json — unknown keys are rejected (typo protection, fail closed).

| Key | Type | Required | Default | Description | | ---------------------------------- | ------- | --------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | allowedTargets | array | yes (non-empty) | – | List of org/space combinations that may be deployed to. | | allowedTargets[].org | string | yes | – | CF org name; must exactly match the org: line of cf target. | | allowedTargets[].space | string | yes | – | CF space name; must exactly match the space: line of cf target. | | allowedTargets[].region | string | no | – | CF region/landscape id (e.g. eu10-004), compared case-insensitively against the region extracted from the API endpoint: line (https://api.cf.<region>.<domain>). Fails closed when the endpoint does not match that pattern. | | allowedTargets[].requireBranch | string | no | – | Current git branch must equal this value. Not being in a git repository counts as a failure. | | allowedTargets[].requireUpToDate | boolean | no | false | Runs git fetch, then fails if the local branch is behind its upstream tracking branch (or has none, or the fetch fails). | | allowedTargets[].warnProduction | boolean | no | false | Prints a prominent red PRODUCTION warning banner before the confirmation prompt. | | allowedTargets[].confirm | boolean | no | true | Asks Continue with deploy to <org>/<space>? (y/N). Set to false to skip the prompt for this target. |

A missing or invalid configuration always blocks the deploy (exit code 1).

Why region? CF org and space names are only unique per CF instance/region (API endpoint) — an org called acme-prod may exist on several landscapes. If you work with more than one region, pin protected targets to their region so being logged in against the wrong API endpoint cannot slip through the org/space whitelist.

CLI

Usage: cf-safe-deploy [options]

  -y, --yes            skip the interactive confirmation prompt
      --config <path>  use this config file instead of searching for .cf-safe-deploy.json
  -h, --help           show this help
  -v, --version        print the version

add-target

Adds the currently targeted CF org/space (from cf target) to the whitelist in .cf-safe-deploy.json, so you don't have to hand-edit JSON after cf target -o ... -s ...:

cf target -o acme-prod -s web-apps
cf-safe-deploy add-target --require-branch release --require-up-to-date --warn-production
Usage: cf-safe-deploy add-target [options]

      --region <region>          pin a region (default: auto-detected from the API endpoint)
      --require-branch <branch>  require this git branch for deploys to this target
      --require-up-to-date       require the branch to be up to date with its upstream
      --warn-production          show the production warning banner for this target
      --no-confirm               skip the confirmation prompt for this target
      --config <path>            use/create this config file instead of searching for one
  -h, --help                     show this help

If no .cf-safe-deploy.json is found (searching upward from the current directory, same as elsewhere), a new one is created in the current directory. Only the flags you actually pass are written — e.g. without --require-up-to-date, the entry won't contain "requireUpToDate": false. If an entry for the same org/space (and, if given, region) is already whitelisted, add-target fails with exit code 1 and leaves the file untouched.

CI usage

In CI there is no TTY to answer the prompt. cf-safe-deploy never hangs on a non-interactive stdin — it exits 1 with a hint instead. Pass --yes to skip the confirmation:

npm run deploy -- # blocked in CI unless confirm is false or --yes is passed
cf-safe-deploy --yes && cf deploy mta_archives/archive.mtar

or in package.json, e.g. as a dedicated CI script:

{
  "scripts": {
    "deploy:ci": "cf-safe-deploy --yes && cf deploy mta_archives/archive.mtar"
  }
}

All other checks (whitelist, branch rules) still apply with --yes.

Colored output is disabled automatically when stdout is not a TTY or when the NO_COLOR environment variable is set.

Exit codes

| Code | Meaning | | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 0 | All checks passed (and the user confirmed, if required) — the deploy may proceed. | | 1 | Blocked: target not whitelisted, branch rule violated, cf/git error, missing/invalid config, confirmation declined, or confirmation required on a non-interactive stdin without --yes. |

License

MIT © Ludwig Stockbauer-Muhr