Skip to content
BETAGuardrails are in beta. The library, the configuration format and the CLI command can still change.

Guardrails / Collectors

Node.js build

The Node.js project in the project directory: its manifest, the Node version and package manager it asks for, every workspace it declares, the dependencies each manifest names and which of them are pinned, and the lock files committed beside them.

Facts keynodejs
Versionv1
Scriptnodejs.py
Timeout30 seconds

Inputs

InputDescriptionDefaultEnvironment
projectDirDirectory holding the project, relative to the directory the CLI runs in..GUARDRAIL_INPUT_PROJECTDIR
maxWorkspacesMost workspace packages to describe. A monorepo past this carries the ones its globs resolve first.200GUARDRAIL_INPUT_MAXWORKSPACES

A guardrail that declares an input of the same name passes it through, so the guardrail's configuration in buildnote.json is what decides these values.

A guardrail asks for these facts by name, and reads them back the same way:

json
{
  "collect": ["nodejs"]
}
python
nodejs = guardrail.facts("nodejs")

Facts

The document nodejs collects. A path carrying [] is an entry of the list before it, and one carrying [path] is a key of the object before it.

FactMeaning
directoryThe projectDir input, as the guardrail configured it.
existsWhether that directory is there. Nothing else is collected when it is not.
manifestPath of the primary manifest, relative to projectDir, always package.json.
sourcesEvery manifest that was read and understood, in the order they were read. A manifest the reader could not handle is in unparsed instead.
declaredThe Node version the project asks for, or null when it asks for none. .nvmrc wins over engines.node, because it is what a developer's shell reads.
declared.versionConstraint exactly as written, such as >=20 or 20.11.1.
declared.sourceFile declaring it, relative to projectDir.
declared.pinnedWhether the constraint names one exact version rather than a range. A >=, a ^, a ~, an x or an * is not pinned.
packageManagerThe packageManager field, such as pnpm@9.1.0, which is what Corepack installs. null when the manifest names none and whatever the runner has is used.
projectsEvery package in the build: the root, followed by every workspace its workspaces globs resolve to.
projects[].pathDirectory of the package, relative to projectDir, . for the project directory itself.
projects[].manifestThat package's package.json, relative to projectDir.
projects[].nameName the manifest declares, or null when it declares none.
dependenciesWhat the manifests declare, split by whether the project asks for it itself.
dependencies.directEvery dependency any manifest declares, in manifest order.
dependencies.direct[].namePackage name, such as react or @acme/widget.
dependencies.direct[].versionConstraint exactly as written, such as ^18.3.0, a workspace:* protocol or a git URL.
dependencies.direct[].scopesWhich of dependencies, devDependencies, peerDependencies and optionalDependencies declare it. A package in two carries both.
dependencies.direct[].sourceManifest declaring it, relative to projectDir.
dependencies.direct[].pinnedWhether the constraint names one exact version. A ^, a ~, a range, a tag, a URL or a workspace: protocol is not pinned.
dependencies.transitiveAlways empty. What a lock file resolves is not read: lockfiles says whether one is committed, and reading a package-lock.json graph is the scanner's job rather than this collector's.
scriptsNames of the scripts the root manifest declares. Names only, because a script body can carry a token.
lockfilesEvery lock file committed, relative to projectDir. More than one means two package managers each believe they own the tree.
droppedWorkspace packages left out because maxWorkspaces was reached. Above zero means projects and dependencies describe part of the build rather than all of it.
unparsedEvery manifest the reader could not handle, so a guardrail can tell a project that declares nothing from one nobody could read.
unparsed[].pathPath of that manifest, relative to projectDir.
unparsed[].reasonWhat stopped the reader.

A collector that cannot finish prints what it had along with an incomplete key saying why, so the facts below the point it stopped are absent. A check that cares reads incomplete before the rest.

Example facts

The example facts collected by nodejs collector:

json
{
  "directory": ".",
  "exists": true,
  "manifest": "package.json",
  "sources": [
    "package.json",
    "packages/core/package.json"
  ],
  "declared": {
    "version": "20.11.1",
    "source": ".nvmrc",
    "pinned": true
  },
  "packageManager": "pnpm@9.1.0",
  "projects": [
    {
      "path": ".",
      "manifest": "package.json",
      "name": "@acme/widget"
    },
    {
      "path": "packages/core",
      "manifest": "packages/core/package.json",
      "name": "@acme/core"
    }
  ],
  "dependencies": {
    "direct": [
      {
        "name": "react",
        "version": "^18.3.1",
        "scopes": [
          "dependencies"
        ],
        "source": "package.json",
        "pinned": false
      },
      {
        "name": "zod",
        "version": "3.23.8",
        "scopes": [
          "dependencies"
        ],
        "source": "package.json",
        "pinned": true
      },
      {
        "name": "typescript",
        "version": "~5.4.5",
        "scopes": [
          "devDependencies"
        ],
        "source": "package.json",
        "pinned": false
      },
      {
        "name": "vitest",
        "version": "^1.6.0",
        "scopes": [
          "devDependencies"
        ],
        "source": "package.json",
        "pinned": false
      },
      {
        "name": "zod",
        "version": "3.23.8",
        "scopes": [
          "dependencies"
        ],
        "source": "packages/core/package.json",
        "pinned": true
      }
    ],
    "transitive": []
  },
  "scripts": [
    "build",
    "test"
  ],
  "lockfiles": [
    "pnpm-lock.yaml"
  ],
  "dropped": 0,
  "unparsed": []
}

Collected for

GuardrailCategoryInputs
nodejs/lockfile-committednodejsprojectDir
nodejs/package-manager-pinnednodejsprojectDir
nodejs/single-package-managernodejsprojectDir
nodejs/version-declarednodejsprojectDir

All collectors

Buildnote Limited
Registered in England and Wales, Reg: 16140412