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

@witbor/sdf

v2.0.1

Published

Deploy pipeline for NetSuite SDF projects on SuiteCloud CLI 4.x: files-check, dryrun, deploy, dependency fixing and audit log.

Readme

@witbor/sdf

Deploy pipeline for NetSuite SDF account customization projects, on top of SuiteCloud CLI 4.x.

files-check ──► [dryrun] ──► deploy
 git changes      mandatory for production,
 → deploy.xml     optional elsewhere (--include-preview)
 + adddependencies
  • Builds deploy.xml with exactly what the branch changed (gitflow: never another branch's work, never wildcards), and declares in manifest.xml everything those items reference.
  • Stops when nothing changed, so a stale deploy.xml is never deployed.
  • Reads SuiteCloud's --json result instead of its console output: status, errors and warnings per file, the exact list of files/objects that change, the account the result belongs to.
  • When the account lacks a dependency, says which one, who references it, and whether it is in the repository (someone deleted it from the account?) or not.
  • Production gates: preview always runs; clean and pushed working tree; confirmation outside the production branch.
  • Optional audit log per day in logs/deploy_YYYYMMDD.log ("log": true; one run id across every process of a run).

Requirements

  • Node.js 24+, Oracle JDK 17 or 21 (SuiteCloud CLI requirements).
  • SuiteCloud CLI >=4.1.0 <5, installed once per machine with npm (not pnpm: its postinstall downloads the SDK jar, and a pnpm install can lack the CLI's bundled sdk-core). This package does not install it (optional peer dependency).

Install

Once per machine (accepts the Oracle Free Use Terms):

$env:SUITECLOUD_CLI_ACCEPT_LICENSE = 'true'; npm install -g @oracle/suitecloud-cli@4
# bash: SUITECLOUD_CLI_ACCEPT_LICENSE=true npm install -g @oracle/suitecloud-cli@4

In the project:

pnpm add -D @witbor/sdf

wtb-sdf uses the CLI installed in the project if there is one, otherwise the npm global one next to suitecloud on the PATH, and stops with the install command when it finds neither (or a version out of range).

suitecloud.config.js:

const { projectDeploy, fileUpload } = require('@witbor/sdf/hooks');

module.exports = {
  defaultProjectFolder: 'src',
  commands: {
    'project:deploy': projectDeploy,
    'file:upload': fileUpload,
  },
};

package.json scripts:

{
  "deploy:help": "wtb-sdf --help",
  "deploy": "wtb-sdf deploy",
  "deploy:sbx": "wtb-sdf deploy --branch sandbox",
  "deploy:prd": "wtb-sdf deploy --branch production",
  "deploy-preview": "wtb-sdf preview",
  "deploy-preview:sbx": "wtb-sdf preview --branch sandbox",
  "deploy-preview:prd": "wtb-sdf preview --branch production"
}

.gitignore: logs and temp.

Configuration: wtb-sdf.config.json (optional)

Example with every key at its default: node_modules/@witbor/sdf/wtb-sdf.config.json.example (copy it to the project root as wtb-sdf.config.json).

{
  "eslint": true,
  "log": false,
  "branches": { "production": "main", "sandbox": "development" }
}

| Key | Default | Meaning | |---|---|---| | eslint | true | Run the project's own eslint over the project folder before every deploy/upload. Rules and ignores live in the project's eslint.config.js. | | log | false | Write the audit log to logs/deploy_YYYYMMDD.log (one file per day; every line carries the run id: grep "run <id>"). Off: nothing is written and no logs/ folder is created. | | branches.production | main | Base branch of --branch production, and the branch production deploys are expected from. | | branches.sandbox | development | Base branch of --branch sandbox. |

Unknown keys or wrong types are errors.

Commands

wtb-sdf deploy  [--branch current|sandbox|production] [--skip-file-check] [--include-preview] [--yes]
wtb-sdf preview [--branch current|sandbox|production] [--skip-file-check] [--yes]
wtb-sdf init
wtb-sdf <command> --help

Through npm, options go after --: npm run deploy -- --skip-file-check. --yes accepts the deploy.xml changes of --branch sandbox|production without a terminal (CI); the production deploy confirmation still asks.

What goes into deploy.xml and manifest.xml

| Command | Changes taken | deploy.xml / manifest.xml afterwards | |---|---|---| | preview / deploy (current) | uncommitted + untracked + unpushed commits (branch never pushed: commits since main) | restored (work in progress) | | --branch sandbox | since the branch left development | kept if it passes: commit them | | --branch production | since the branch left main: what the branch takes to production | kept if it passes: commit them |

  • One diff from that base to the working tree: a change committed and then undone, or a file added and deleted again, is not deployed. The base uses the newest of the local branch and origin/<branch>; during a merge (conflict being resolved) the commit being merged in counts as already part of the branch.
  • current and sandbox leave out (and list) files identical to main: main's work merged into the branch is not the branch's change. Not applied when working on main itself. Deletions are always reported.
  • Only FileCabinet files and Objects XML are deployed. A changed .attributes/x.js.attr.xml deploys x.js.
  • Reported, never deployed (SDF cannot or must not do it per branch): deletions and the old name of renames, folder attributes, AccountConfiguration / Translations / InstallationPreferences.
  • References of a deployed object ([scriptid=...], [/SuiteScripts/...]):
    • deployed too → nothing to declare;
    • in the repository but unchanged in the branch → declared in manifest.xml, not deployed (deploying it would overwrite what another branch put in the account). The account must already have it;
    • not in the repository → declared by project:adddependencies.
  • A dependency the account does not have fails the preview with a "Not in the account" list: in the repository (a person must check: deleted from the account? never deployed?) or not (create or import it).
  • manifest.xml is rebuilt on every run: the version at the base commit + main's declarations and features that the branch contains + what the branch needs. Dependencies from earlier runs or other branches do not pile up and main's are never dropped. Hand edits to manifest.xml in a branch are not kept: make them in the base branch, or use --skip-file-check.
  • Unresolved merge conflicts stop the run, except in deploy.xml/manifest.xml: they are regenerated (take either side, git add them after a passing run). With merge=ours for both files in .gitattributes those conflicts never happen.

Exit codes: 0 ok or nothing to deploy, 1 failed, 2 invalid arguments, 130 interrupted.

A run killed hard leaves its backup in temp/: the next run restores it when it is on the same branch and commit, discards it otherwise, and refuses to start while the run that made it is still alive.

Troubleshooting

  • "SuiteCloud CLI not found": install it with npm (see Install). A suitecloud installed another way (pnpm global, volta) is named in the message but not used.
  • "SuiteCloud CLI ... is incomplete" / Cannot find module '@oracle/suitecloud-sdk-core': the CLI was installed with pnpm. Remove it and install it with npm.
  • ERR_PNPM_IGNORED_BUILDS for @oracle/suitecloud-cli: the project lists the CLI in its own dependencies. Remove it (pnpm remove @oracle/suitecloud-cli) and use the global one.
  • "Java is not installed on this machine" while Java is installed: run java -version. A malformed JAVA_TOOL_OPTIONS (e.g. without the leading -) stops Java from starting, and the CLI reports it this way.
  • Generic SuiteCloud "Server error" behind an antivirus that intercepts HTTPS: set JAVA_TOOL_OPTIONS=-Djavax.net.ssl.trustStoreType=Windows-ROOT.