Files
mesh-catalog/modules/mesh-build-node/cmd/mesh-build-node/registry.go
T
jschoubben af280050d6 CAT-BN3: mesh-build-node publishes through the registry seats and holds no registry credential
Bundles go through oci-artifact-registry and answer the seat's reference;
a trunk package is packed under the builder's version and published through
npm-package-registry, so the holder can check it with the builder. Reads are
anonymous, so the write pair, the sealed secret and the store's address go.
The one-part sender moves into buildstep for both build modules, so the move
to the registry clients is made in one place.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
2026-11-04 15:30:06 +01:00

65 lines
2.3 KiB
Go

package main
// How the toolchain's install reaches the mesh's package registry (novox/hq ADR 0405 §5, ADR 0336; issue 1488).
// The lock names @novox/mesh-sdk at the registry's public address, and npm installs a locked tarball only from the
// registry it is configured with, so the install is told that registry for the @novox scope and nothing else: every
// other package resolves from the public one. The address is read from the module's npm-package-registry binding
// (module.json `binds`). Reads are anonymous (ADR 0346; the provision's form none, CAT-BN3): this module holds no
// credential for the registry, and publishes only through the seat's verbs (publish.go).
import (
"encoding/json"
"fmt"
"os"
"strings"
)
// Scope is the npm scope the mesh's registry answers for.
const Scope = "@novox"
// Registry is the mesh's package registry as the binding names it.
type Registry struct {
URL string
}
// ReadRegistry reads the npm-package-registry binding. The registry is the binding's
// `public-root` when it has one (the address the lock holds), and otherwise scheme://at:port plus `npm-path`.
func ReadRegistry(bindingPath string) (Registry, error) {
raw, err := os.ReadFile(bindingPath)
if err != nil {
return Registry{}, fmt.Errorf("no package registry is bound to this module: %w", err)
}
var b struct {
At string `json:"at"`
Serves struct {
Scheme string `json:"scheme"`
Port int `json:"port"`
NpmPath string `json:"npm-path"`
PublicRoot string `json:"public-root"`
} `json:"serves"`
}
if err := json.Unmarshal(raw, &b); err != nil {
return Registry{}, fmt.Errorf("the package registry binding is not JSON: %w", err)
}
url := b.Serves.PublicRoot
if url == "" && b.At != "" && b.Serves.NpmPath != "" {
scheme := b.Serves.Scheme
if scheme == "" {
scheme = "http"
}
url = fmt.Sprintf("%s://%s:%d%s", scheme, b.At, b.Serves.Port, b.Serves.NpmPath)
}
if url == "" {
return Registry{}, fmt.Errorf("the package registry binding names no address")
}
if !strings.HasSuffix(url, "/") {
url += "/"
}
return Registry{URL: url}, nil
}
// Npmrc is the npm configuration text for the install: the @novox scope at the registry, read anonymously.
func (r Registry) Npmrc() string {
return fmt.Sprintf("%s:registry=%s\n", Scope, r.URL)
}