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

@voxgig/sdkgen-infrapack

v0.0.18

Published

Infrastructure-provider targets for the Voxgig SDK Generator: Seneca provider.

Readme

@voxgig/sdkgen-infrapack

Infrastructure-provider targets for the Voxgig SDK Generator.

An infrastructure provider is not an SDK. It is a plugin for someone else's system — Seneca, Terraform — that exposes your API's entities in that system's own vocabulary, layered on the SDK generated from the same model. Every target here wraps a language target rather than being one.

npm install --save-dev @voxgig/sdkgen-infrapack
voxgig-sdkgen package add @voxgig/sdkgen-infrapack
npm run generate

Targets

| target | wraps | produces | |---|---|---| | seneca-provider | ts | a Seneca plugin exposing entities as provider/<name>/<entity> |

terraform-provider is designed and not yet built; see the design notes in the sdkgen repository.

Every target here needs the target it wraps

These are consumer targets: they switch every standard generation phase off and emit their whole package from Main, and each one fails without the target it wraps, deliberately. Add ts to your project before seneca-provider. The one exception is a provider that carries its own builder (below), which names the SDK it wraps instead.

There is no manifest field for that requirement. Nothing in sdkgen-package.json says "this target needs that one", so this paragraph and the error at generation are where the requirement lives.

Custom actions reach Seneca as action$

An API definition folds a non-CRUD verb into an ordinary operation as an alternative route — GitHub's PUT /repos/{owner}/{repo}/pulls/{n}/merge is a second point of the pull request's update. The SDK selects one with $action in the call's argument. Seneca has no operation to add it to, so the provider takes it as a directive, spelled the Seneca way:

const pull = seneca.entity('provider/github/pull')

await pull
  .make$({ id: 42, owner: 'voxgig', repo: 'sdkgen',
           commit_title: 'Merge pull request #42' })
  .directive$({ action$: 'merge' })
  .save$()

save$ routes by the operation the action belongs to, not by the command, so an action folded into create is called as a create even on an entity that carries an id. A name the entity does not have throws, naming the valid ones — it never falls back to the plain command. Each generated provider lists its own actions in its README and its reference.

make$({ action$ }) does not work and cannot: seneca-entity's make$ copies only keys without a $, plus the four directives it knows by name, so any other trailing-$ key is dropped before a store sees it. Use directive$, or assign the property to an entity you have already made.

Providers generated before this gain their actions on the next regeneration.

seneca-provider generates into its own repository

Unlike a language target, a Seneca provider is not a folder in the SDK repository. It is an independently released npm package under the @seneca scope, with its own license, workflow and release cadence, and it depends on the SDK as an ordinary published dependency. Point it at that repository from your project model:

main: kit: target: 'seneca-provider': output: path: '../../seneca/seneca-acme-provider'

The path resolves against the SDK repository root. Left unset, the provider generates in-tree under seneca-provider/, which is a usable default for a first look at the output.

Set that in model/project.aontu, not in the target's own file — target add overwrites the latter.

Or the provider carries its own builder

The provider repository can instead hold a .sdk/ of its own, which generates the provider and nothing else, and leaves the SDK repository untouched. Its model/project.aontu says so, and the standard Root that create-sdkgen scaffolds reads it:

main: kit: phase: top: active: false
main: kit: phase: build: active: false
main: kit: doc: active: false
main: kit: target: 'seneca-provider': output: root: true
main: kit: target: 'seneca-provider': sdk: version: '0.0.1'

output: root: true generates the provider at the repository root, and is how this target knows the builder is the provider's own. That builder has no ts target, so it names the SDK itself: sdk.version is required, and sdk.package overrides the derived package name. Both are refused in an SDK project, where the ts target is the SDK.

The builder carries a copy of the SDK's API definition and guide. make regen replaces them with those of the SDK fetched at the tag in sdk-pin.json before generating. Generation then refuses to write when the builder's model and that SDK's compiled model differ in what the SDK was generated from: an entity, an operation's routes, parameters and actions, a field's type or requiredness, the identity, the ancestors, the authentication or the servers. Titles and descriptions are not compared. It also refuses when the package name or version differ from the SDK's own ts/package.json, which is read rather than the name re-derived, because the SDK's generator may name packages by a rule this builder's does not share. Generated without the SDK fetched, it warns that the check did not run.

A symlinked SDK checkout, from make sdk-src SDK_SRC_FROM=<path>, is read as it is: make sdk-src never fetches or checks out a tag inside one.

To move to a newer SDK, set sdk.version and fetch its tag as you regenerate:

make regen SDK_TAG=v0.0.2

An SDK that is not on npm yet

The generated package.json depends on the SDK by version range, which installs only once the SDK is published. Until then, sdk.dep points it elsewhere:

| sdk.dep | The dependency | |---|---| | kind: 'release', ref: 'v1.0.0' | the npm pack tarball attached to that GitHub release | | kind: 'git', ref: '<tag>' | github:<owner>/<repo>#<tag>, installed from the root of that tag's tree | | spec: '<anything>' | the value, verbatim |

npm cannot install a package from a subfolder of a git repository, and an sdkgen SDK keeps its TypeScript package in ts/. A git dependency therefore needs a tag whose tree is that folder, cut in the SDK repository:

git tag ts-v1.0.0 $(git commit-tree HEAD:ts -p HEAD -m "ts/ at v1.0.0")
git push origin ts-v1.0.0

and then sdk: dep: { kind: 'git', ref: 'ts-v1.0.0' }. The tag carries what the folder holds, so an SDK that commits ts/dist needs nothing built on install. The generated CI passes --allow-git=all, which npm 12 needs for a git dependency, and so would anyone installing a published provider that depends on one: publish the SDK to npm before the provider.

Parity

Every target here declares CONSUMER. That is not a coverage tier alongside FULL, MIRRORED and UNCOVERED, which grade a language target against the shared corpus. A consumer target has no utility layer to measure, so it is outside that system — and says so, rather than omitting the field, which cannot be told apart from an author who did not know it existed.

Developing

npm install
npm test          # the comment gate, the dependency gate, then the suite

A committed dependency must name a published npm package or a GitHub reference; local wiring to a sibling checkout is how a change gets tested before its dependency is released, and undoing it is part of finishing. make deps checks that and make deps-test runs its own suite; npm test, the pre-push hook and CI all run the gate, so it cannot be forgotten.

The suite runs on @voxgig/sdkgen/testkit: it installs this package into a staged consumer through the real package add, compiles the components the way a consumer's build does, and generates.

Two tests skip against a published sdkgen whose test kit predates the outside option, which is what lets a suite express out-of-tree generation at all. They report the skip rather than passing quietly, and start running as soon as that release lands.

Validate the package itself with:

npx voxgig-sdkgen package check .

Releasing — OIDC dispatch, never a local publish

NOTHING IS PUBLISHED FROM A WORKSTATION. The release is performed by GitHub Actions over OIDC trusted publishing, and the way you start it is a workflow dispatch:

gh workflow run publish.yml --ref main -f expect_sha=$(git rev-parse HEAD)

Bump the version in both package.json and sdkgen-package.json first, on main, in a reviewable commit — nothing in the workflow commits. The workflow verifies, publishes to npm, then tags v<version>.

Never npm publish from a checkout: it goes out over a stored token with no provenance. The one exception is a package's very first version, which npm gives no way to automate — see release/README.md, which carries the full record, the npm trust registration, and what the 404 at the end of a green run actually means.

Never hand a release back as "run this locally yourself". A release is a dispatch: prepare the commit, then dispatch the workflow.

Provenance

seneca-provider was generated from the same trees that shipped inside @voxgig/sdkgen. Before it moved, its output was compared file by file against the bundled version from the same model: 21 files, 0 differences, identical warnings and an identical placeholder scan. Nothing about a generated provider changed in the move.