Skip to content

Expose the registry as the root package's bin #159

Closed

Description

@lmcorbalan

User story / Problem statement

Nothing in this repository is installable as an npm package. The root manifest
is named canton-token-forge, has no bin, no files, no repository, and
declares "type": "commonjs" while the service it would ship is ESM.
registry/ is private: true and lives in a subdirectory, and neither npm nor
pnpm can install a git dependency from a subdirectory. A consumer has no way to
say "give me this service" in a manifest.

Expected outcome

npm pack at the root produces a tarball carrying the built service, the
OpenAPI specs it reads at runtime, and the environment template. Installing that
tarball links one executable named canton-token-forge-registry.

Acceptance criteria

Package identity

  • Name @bootnodedev/canton-token-forge, version 0.2.0, "type": "module",
    a repository field, and engines.node at >=18
  • bin maps canton-token-forge-registry to registry/dist/index.js
  • registry/src/index.ts starts with #!/usr/bin/env node

Pack contents

  • npm pack produces a tarball containing every file under registry/dist,
    all four registry/openapi/*.yaml, and registry/.env.example
  • package/registry/dist/index.js is present in the archive, since it is the
    bin target
  • Installing that tarball links an executable at
    node_modules/.bin/canton-token-forge-registry

Nothing regresses

  • git check-ignore still reports registry/dist/index.js as ignored, and
    git status lists no build output
  • registry/'s own build, suite typecheck and unit suite still pass
  • daml/canton-token-forge/daml.yaml is untouched

Alternatives considered

  • Commit a prebuilt registry/dist. Rejected: it puts generated output in
    review diffs and goes stale silently. prepare builds it at install time
    instead.
  • Publish registry/ as its own package from the subdirectory. Rejected:
    neither npm nor pnpm can install a git dependency from a subdirectory, which is
    the original blocker.
  • Add a registry/.npmignore instead of moving the ignore rule. Both work
    and both were verified. The root .gitignore was chosen so the repository
    keeps one ignore mechanism rather than two files whose interaction has to be
    explained to every reader.

Technical notes

  • The trap that makes this issue non-obvious. files is an allowlist, but
    npm applies a nested ignore file to the pack walk even for a path the
    allowlist names. registry/.gitignore ignores dist, so
    files: ["registry/dist"] ships zero dist files and the tarball's bin
    target does not exist. The root .gitignore is not applied that way, so
    moving the single line dist out of registry/.gitignore and into the root as
    registry/dist fixes it while leaving git's behaviour identical. Verify both
    halves: tar tzf on the archive, and git check-ignore -v on the path.
  • The tarball is never only what files lists. LICENSE and README.md are
    always included, and the !.env.example negation in registry/.gitignore
    force-includes registry/.env.example regardless of the allowlist. Listing
    registry/.env.example in files makes that deliberate, and matches the
    wallet service's own files: ["dist", ".env.example"].
  • "type": "module" is required, not cosmetic. registry/package.json does
    not travel in the tarball, so the root manifest is the only thing that can tell
    node the shipped dist is ESM. It is safe here because the only JavaScript
    outside registry/ is scripts/seed.mjs, which carries its own extension.
  • tsc emits a shebang as the first line of its output, so the bin needs no
    wrapper file, and npm sets the exec bit when it links it.
  • The npm version and the Daml version are independent and always have been.
    daml/canton-token-forge/daml.yaml stays at 0.0.1, so the DAR filename and
    its sha256 do not move.
  • package-lock.json embeds the package name and version, so it must be
    regenerated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpriority: highMust be addressed in current sprint

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions