@farthershore/backend 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -1
- package/dist/index.js +798 -19
- package/dist/testing/index.js +2716 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/response-metering.d.ts +45 -0
- package/dist/types/testing/devGateway.d.ts +36 -0
- package/dist/types/testing/devRuntime.d.ts +68 -0
- package/dist/types/testing/index.d.ts +8 -0
- package/dist/types/testing/keysFile.d.ts +30 -0
- package/dist/types/testing/personas.d.ts +104 -0
- package/dist/types/testing/prodGuard.d.ts +12 -0
- package/dist/types/testing/signers.d.ts +89 -0
- package/dist/types/testing/traceSink.d.ts +67 -0
- package/dist/types/testing/usageSink.d.ts +31 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ graceful lifecycle (health + shutdown). Everything else — your product, backen
|
|
|
12
12
|
and environment ids, the verification keys, and the metering endpoint — is
|
|
13
13
|
fetched automatically from the token at startup.
|
|
14
14
|
|
|
15
|
-
> **Status: `0.
|
|
15
|
+
> **Status: `0.13.0`.** Pre-1.0: minor releases may include breaking changes, so
|
|
16
16
|
> pin this package to an exact version (or a patch-only range) and upgrade
|
|
17
17
|
> deliberately.
|
|
18
18
|
|
|
@@ -149,6 +149,58 @@ real time.
|
|
|
149
149
|
- `fs.shutdown()` flushes any buffered metering and sends a `stopping` heartbeat.
|
|
150
150
|
Call it on `SIGTERM` / `SIGINT` for graceful shutdown.
|
|
151
151
|
|
|
152
|
+
## Local development & testing — the mode ladder
|
|
153
|
+
|
|
154
|
+
You do not need the platform to test a backend that runs behind it. Pick the
|
|
155
|
+
lowest tier that answers your question — each is a superset of the one below.
|
|
156
|
+
|
|
157
|
+
**Tier 0 — off (needs NOTHING from the SDK).** Unit-test your business logic
|
|
158
|
+
directly. The gateway sits in front of you in production; your pure handlers
|
|
159
|
+
don't import Farther Shore to be tested. There is no SDK step at this tier — see
|
|
160
|
+
`templates/1-unit.test.ts`.
|
|
161
|
+
|
|
162
|
+
**Tier 1 — passthrough.** Run your real app over HTTP with `fs.middleware()`
|
|
163
|
+
mounted but verification OFF, matching the pre-keystone deploy order: the
|
|
164
|
+
middleware passes requests through without attaching a context, so your routes
|
|
165
|
+
run normally. Activate with `FS_DEV_MODE=passthrough`. See
|
|
166
|
+
`templates/2-passthrough-http.test.ts`.
|
|
167
|
+
|
|
168
|
+
**Tier 2 — simulated.** A real runtime wired to an in-process gateway with
|
|
169
|
+
fail-closed verification ON and SIGNED personas driving requests. Assert the
|
|
170
|
+
fail-closed boundary (a persona without a permission gets 403) and that usage is
|
|
171
|
+
metered. Activate with `FS_DEV_MODE=simulated`, or construct explicitly:
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { createDevRuntime, definePersona } from "@farthershore/backend/testing";
|
|
175
|
+
|
|
176
|
+
const rt = createDevRuntime({
|
|
177
|
+
mode: "simulated",
|
|
178
|
+
personas: {
|
|
179
|
+
creator: definePersona({
|
|
180
|
+
name: "creator",
|
|
181
|
+
permissions: ["widgets:create"],
|
|
182
|
+
}),
|
|
183
|
+
},
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// Sign a request as a persona and drive your app (supertest, fetch, or inject):
|
|
187
|
+
const headers = await rt.asPersona("creator").headers({ path: "/v1/widgets" });
|
|
188
|
+
// rt.usage.byMeter() → assert reported usage
|
|
189
|
+
// rt.trace.forRequest(id) → why a request verified / was denied
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
`@farthershore/backend/testing` gives you signed personas (owner / admin /
|
|
193
|
+
member / anonymous, plus your own), an in-process gateway fixture, and
|
|
194
|
+
assertable `usage` + per-request `trace` side channels. It is dev/test tooling
|
|
195
|
+
only — **it throws when `NODE_ENV=production`**, and `FS_DEV_MODE` is never a
|
|
196
|
+
required-at-boot variable. When `FS_DEV_MODE` is set, `initFromEnv()`
|
|
197
|
+
self-constructs the simulator (ephemeral keys, a loud banner, JSONL usage/trace
|
|
198
|
+
logs under `.farthershore/`, and a mode-600 `.farthershore/dev-keys.json` so a
|
|
199
|
+
separate test-runner process can sign against a running service via
|
|
200
|
+
`personaClientFromKeysFile`).
|
|
201
|
+
|
|
202
|
+
See `templates/3-simulated-authz.test.ts` for the full fail-closed + usage flow.
|
|
203
|
+
|
|
152
204
|
## Key exports
|
|
153
205
|
|
|
154
206
|
| Export | Purpose |
|
|
@@ -157,13 +209,26 @@ real time.
|
|
|
157
209
|
| `fs.middleware()` | Express fail-closed verify → `req.fartherShore`. |
|
|
158
210
|
| `fs.verifyRequest({...})` | Framework-neutral request verification. |
|
|
159
211
|
| `withUsage()` / `createUsage()` | Response-bound usage reporting (no network call). |
|
|
212
|
+
| `computeMeteringHeaders()` | Metering headers as a plain map — never throws. |
|
|
160
213
|
| `fs.meter(meter, qty, opts)` | Async/background usage event. |
|
|
161
214
|
| `fs.health()` / `fs.shutdown()` | Health report and graceful shutdown. |
|
|
162
215
|
| `FartherShoreError`, `MeteringError` | Typed errors. |
|
|
216
|
+
| `@farthershore/backend/testing` | Dev-mode + persona test harness (dev/test only). |
|
|
163
217
|
|
|
164
218
|
A subpath export, `@farthershore/backend/express`, exposes the Express adapter
|
|
165
219
|
types directly if you prefer to wire the middleware yourself.
|
|
166
220
|
|
|
221
|
+
## Metering channels
|
|
222
|
+
|
|
223
|
+
Two usage channels exist and are **not** interchangeable:
|
|
224
|
+
|
|
225
|
+
- **Response-bound** (`withUsage` / `createUsage` / `computeMeteringHeaders`) is
|
|
226
|
+
the attested, request-bound settlement channel: the gateway verifies the HMAC
|
|
227
|
+
and settles the reported units against the request's lease in the same
|
|
228
|
+
lifecycle. Wire recipe (any language): [`docs/response-metering-wire.md`](docs/response-metering-wire.md).
|
|
229
|
+
- **Background** (`fs.meter`) is a billing-only, unattested, post-cycle tally for
|
|
230
|
+
usage not tied to a gateway response. It never settles a lease.
|
|
231
|
+
|
|
167
232
|
## Learn more
|
|
168
233
|
|
|
169
234
|
- Platform documentation: https://docs.farthershore.com
|