Repository navigation
v0.1.13
Keep the dev-dependency alignment, drop the workspace: protocol
The internal ranges had been rewritten to workspace:^. That resolves inside
this monorepo and nowhere else: every package CI checks out its own repository
alone and runs pnpm install, where the protocol has no workspace to point at
and fails with ERR_PNPM_WORKSPACE_PKG_NOT_FOUND before a single test runs. The
concrete ranges are back; the dev-dependency bumps that came with the same edit
are kept, and now match what the lockfile already resolved.
Widen the rune and warden ranges instead of replacing them
"Admit rune 0.2" replaced ^0.1.8 with ^0.2.0, which does not admit 0.2 — it
REQUIRES it and drops 0.1.x. rune 0.2.0 is not published, so the standalone CI,
which installs from the registry, could not resolve the dependency at all and
never reached a single test.
The warden devDependency had drifted the same way, to ^0.2.0 against a
registry at 0.1.27 — a second failure waiting behind the first, since pnpm
stopped at rune. Its own peer range already used the right form.
Both are ^0.1.x || ^0.2.x now, the shape the atlas and warden peer ranges
already use here. Station reaches rune through a lazy import over a structural
surface — rules.string/number/boolean/any, .optional/.nullable/.parse,
schema().validateResult() — and every one of those exists and behaves the
same in the published 0.1.15, which is what makes the wider range honest rather
than merely convenient.
Verified by reproducing the CI: a clean checkout, pnpm install resolving from
the registry, then typecheck, lint, build and 258 tests against rune 0.1.15 and
warden 0.1.27. The workspace still links the local 0.2.0, and passes too.
Correct a justification the coercion work made false, and drop a project name
The schema builder's doc-comment justified its explicit .parse() with "rune
does NOT coerce". rune coerces both booleans and numbers now, so the reason
given was wrong even though the code is still right: a checkbox posts the
values the COLUMN chooses, which is a wider set than a general-purpose
coercion should ever accept. The reason now says that.
Also drops the reference implementation's name from comments and one test
label — parity is shape, never product identity.
fix(deps): admit rune 0.2 — station never touches what changed in it
rune 0.2.0 no longer satisfied ^0.1.8, so pnpm stopped linking the
workspace copy and silently resolved station's rune to the published
0.1.15 instead. Station's tests were then proving nothing about the rune
it ships against.
Station consumes four constructors, three modifiers and
validateResult(). None of them moved in 0.2.0 — what moved is the
locale tables, the two normalisers, the emitted JSON Schema and the
default of mobile(), and station calls none of it. 258 tests green
against the local 0.2.0.
fix(deps): admit warden 0.2 — station never touches what changed in it
Warden 0.2.0 changed the OTP challenge store contract. Station resolves a
duck-typed AuthManager surface through the container and imports warden nowhere,
so it works with both lines, and the range now says so rather than pinning to
one.
The peer-ranges gate caught this, which is what it is for — but it read a
compound range as a failure, so the honest answer looked like the problem. It
now tries each alternative: a package that works with both lines should be able
to declare it instead of narrowing the manifest to please the check.
fix(provider): tell an absent peer from a broken one
isModuleNotFound read the error CODE and nothing else, so
ERR_MODULE_NOT_FOUND from anywhere inside an installed @c9up/atlas -- a
dependency of its own gone, a broken build -- was taken for atlas being absent.
Station then took the degraded-host path and disabled the admin, silently. The
peer was there; something in it was broken; and the one person who could fix it
was told nothing.
Node distinguishes the two in the message: a bare specifier that resolves to
nothing names the PACKAGE ("Cannot find package '@c9up/atlas'"), while a miss
inside an installed package names a path. isPackageMissing requires the first
and re-throws everything else, so a broken peer now surfaces as the error it is.
It also takes the specifier, so a missing rune can no longer read as a missing
atlas — the admin was disabled for a package it does not depend on.
Changes since v0.1.12.