@crvouga/mockingbird-service-oauth 3.0.0 → 3.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog — @crvouga/mockingbird-service-oauth
2
2
 
3
+ ## 3.2.0 (2026-10-09)
4
+
5
+ ### Features
6
+
7
+ - match Emulate provider coverage ([16b65ce](https://github.com/crvouga/mockingbird/commit/16b65ce791fa216f28ec1521df636f57771d9c5e))
8
+
9
+ ### Dependencies
10
+
11
+ - `@crvouga/mockingbird-service-sqlite`
12
+
13
+ ## 3.1.0 (2026-10-08)
14
+
15
+ ### Features
16
+
17
+ - redesign emulator experience ([d6038c2](https://github.com/crvouga/mockingbird/commit/d6038c27eebbaa1751f02bc9305002a5b1304779))
18
+
3
19
  ## 3.0.0 (2026-10-07)
4
20
 
5
21
  ### ⚠️ Breaking changes
@@ -14,10 +30,6 @@
14
30
  - typecheck the brand gate before builds ([fc36095](https://github.com/crvouga/mockingbird/commit/fc3609514de70ffe3170a5d216fb8a49f9ce7cbb))
15
31
  - format the emulates records query ([8698872](https://github.com/crvouga/mockingbird/commit/8698872509d06002be5a8fcdc85d79f8462320c3))
16
32
 
17
- ### Dependencies
18
-
19
- - `@crvouga/mockingbird-service-sqlite`
20
-
21
33
  ## 2.3.0 (2026-10-04)
22
34
 
23
35
  ### Features
package/DISCOVERY.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @crvouga/mockingbird-service-oauth discovery
2
2
 
3
3
  This is the installed-package index for coding agents and tooling. All relative links resolve
4
- inside `node_modules/@crvouga/mockingbird-service-oauth/`; no repository checkout is needed to discover the mock's
4
+ inside `node_modules/@crvouga/mockingbird-service-oauth/`; no repository checkout is needed to discover the emulator's
5
5
  supported surface or documented behavior.
6
6
 
7
7
  ## Capability and behavior sources
@@ -48,7 +48,7 @@ designed for assertions and diagnosis by consuming test suites.
48
48
  ## Report a mismatch or missing capability
49
49
 
50
50
  Follow the [agent reporting contract](https://github.com/crvouga/mockingbird/blob/main/docs/REPORTING_ISSUES.md). Include package version,
51
- operation/command, a minimal redacted request, actual mock result, expected oracle result or vendor
51
+ operation/command, a minimal redacted request, actual emulator result, expected oracle result or vendor
52
52
  documentation, and whether the mismatch appears in the matrix. Never include keys, tokens,
53
53
  customer data, prompts, PHI, card data, or unredacted recordings.
54
54
 
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @crvouga/mockingbird-service-oauth
2
2
 
3
- > Familiar calls. Faithful echoes. Part of [Mockingbird](https://github.com/crvouga/mockingbird).
3
+ > Local emulators. Real API contracts. Part of [Mockingbird](https://github.com/crvouga/mockingbird).
4
4
 
5
5
  A stateful OAuth 2.0 / OpenID Connect identity sandbox. Google, Apple, Microsoft and GitHub wire profiles share a vendor-neutral account chooser, signup and consent UI. Generic OIDC works with other configurable identity clients. Uses real RS256 signatures, discovery, JWKS, authorization codes, S256 PKCE, refresh tokens and revocation.
6
6
 
@@ -55,9 +55,9 @@ await server.close()
55
55
  npx mockingbird-oauth serve --provider google --port 8810
56
56
  ```
57
57
 
58
- ### Point an app at the mock
58
+ ### Point an app at the emulator
59
59
 
60
- Override the authorization, token, userinfo and JWKS endpoints in your application's OAuth provider configuration. Set its expected issuer to the mock's public base URL. Discovery is at `/.well-known/openid-configuration` for OIDC profiles; GitHub uses explicit OAuth endpoints and does not issue ID tokens. Register the **exact** callback URL (including scheme, port, path and query); wildcard callbacks are not accepted. No outgoing requests to a vendor occur.
60
+ Override the authorization, token, userinfo and JWKS endpoints in your application's OAuth provider configuration. Set its expected issuer to the emulator's public base URL. Discovery is at `/.well-known/openid-configuration` for OIDC profiles; GitHub uses explicit OAuth endpoints and does not issue ID tokens. Register the **exact** callback URL (including scheme, port, path and query); wildcard callbacks are not accepted. No outgoing requests to a vendor occur.
61
61
 
62
62
  | Profile | Authorization | Token | JWKS | Userinfo |
63
63
  | --- | --- | --- | --- | --- |
@@ -67,9 +67,9 @@ Override the authorization, token, userinfo and JWKS endpoints in your applicati
67
67
  | `github` | `/login/oauth/authorize` | `/login/oauth/access_token` | Not an OIDC provider | `/user`, `/user/emails` |
68
68
  | `oidc` | `/authorize` | `/token` | `/jwks` | `/userinfo` |
69
69
 
70
- `/authorize`, `/token`, `/jwks`, `/revoke` are common aliases. Google also accepts `/o/oauth2/auth` and `/oauth2/v3/userinfo`; Apple revocation is `/auth/revoke`. Token and revocation requests use `application/x-www-form-urlencoded`. Token client authentication supports Basic, body credentials, and public clients. Public clients must use S256 PKCE; confidential clients can opt in with `requirePkce: true`. Google mock client secrets are fixture strings configured on the client. Apple clients can use either a fixture string or `apple: { teamId, keyId, publicKey }`, where `publicKey` is an EC P-256 public JWK. In JWT mode the mock verifies the ES256 signature, key ID, team, subject, Apple audience, issue/expiry times and maximum lifetime. The application can keep generating its usual Apple client-secret JWTs with the corresponding test private key.
70
+ `/authorize`, `/token`, `/jwks`, `/revoke` are common aliases. Google also accepts `/o/oauth2/auth` and `/oauth2/v3/userinfo`; Apple revocation is `/auth/revoke`. Token and revocation requests use `application/x-www-form-urlencoded`. Token client authentication supports Basic, body credentials, and public clients. Public clients must use S256 PKCE; confidential clients can opt in with `requirePkce: true`. Google emulator client secrets are fixture strings configured on the client. Apple clients can use either a fixture string or `apple: { teamId, keyId, publicKey }`, where `publicKey` is an EC P-256 public JWK. In JWT mode the emulator verifies the ES256 signature, key ID, team, subject, Apple audience, issue/expiry times and maximum lifetime. The application can keep generating its usual Apple client-secret JWTs with the corresponding test private key.
71
71
 
72
- For example, an Auth.js-style OIDC provider can use `type: "oidc"`, `issuer: "http://localhost:8810"`, `clientId`, `clientSecret`, and `checks: ["pkce", "state"]`. For existing Google/Apple presets, override **all** remote endpoints and issuer validation; changing the authorization URL alone is insufficient. In-process HTTP clients can route requests to `identity.fetch`. Browser navigation must reach a served mock or a service worker that routes those requests.
72
+ For example, an Auth.js-style OIDC provider can use `type: "oidc"`, `issuer: "http://localhost:8810"`, `clientId`, `clientSecret`, and `checks: ["pkce", "state"]`. For existing Google/Apple presets, override **all** remote endpoints and issuer validation; changing the authorization URL alone is insufficient. In-process HTTP clients can route requests to `identity.fetch`. Browser navigation must reach a served emulator or a service worker that routes those requests.
73
73
 
74
74
  The issuer defaults to the incoming origin (and `/__admin/ns/<name>` when used). Set `issuer` to the public URL behind a reverse proxy; it may include a mount path. Avoid a fixed issuer shared across namespaces: use the namespace URL and its own discovery/JWKS so each namespace remains an independent issuer.
75
75
 
@@ -146,7 +146,7 @@ tapping `oauth-mock-form-post-continue`; with scripts, the page submits the form
146
146
 
147
147
  - Authorization-code flow with exact redirect matching, including explicitly registered private-use URI schemes for native apps, state and nonce; duplicate parameters rejected. Invalid clients/callbacks never redirect. Public native clients require S256 PKCE.
148
148
  - Real RSA-2048 / RS256 ID tokens and independent public JWKS; correct issuer, audience, expiry, auth time and scope-filtered claims. Keys remain stable until explicitly rotated.
149
- - Codes expire after 5 minutes and are consumed atomically, including concurrent PKCE redemption. Access/ID tokens last 1 hour. Generic OIDC refresh tokens default to 30 days; Microsoft defaults to 90 days. Apple/Google refresh tokens have no fixed deadline by default; Google inactivity, testing mode and issuance limits still apply. GitHub OAuth app access tokens have no fixed deadline in the mock. The injected mock clock controls expiry.
149
+ - Codes expire after 5 minutes and are consumed atomically, including concurrent PKCE redemption. Access/ID tokens last 1 hour. Generic OIDC refresh tokens default to 30 days; Microsoft defaults to 90 days. Apple/Google refresh tokens have no fixed deadline by default; Google inactivity, testing mode and issuance limits still apply. GitHub OAuth app access tokens have no fixed deadline in the emulator. The injected emulator clock controls expiry.
150
150
  - Google `access_type=offline` issues refresh tokens on first consent or `prompt=consent`; generic/Microsoft `offline_access` and Apple issue refresh tokens. Refresh cannot expand scopes. Revocation invalidates related access and refresh tokens; unknown tokens succeed idempotently. Refresh tokens are reusable by default; Microsoft returns a replacement without invalidating the old token. Opt-in strict rotation detects reuse and revokes the token family.
151
151
  - `prompt=none` returns `login_required` or `consent_required`; `login`, `consent`, `select_account`, `login_hint` and `max_age` are supported. HttpOnly, SameSite=Lax browser sessions last 24 hours. Cancel returns `access_denied` with state.
152
152
  - Apple supports `code id_token`, `c_hash`, `form_post` with an automatic POST and a no-JavaScript Continue button, string `email_verified` / `is_private_email`, no userinfo endpoint, and first-consent-only `user` data. `name` / `email` scopes require `form_post`.
@@ -218,7 +218,7 @@ These routes use the shared admin-key and namespace controls. `revokeConsent(cli
218
218
 
219
219
  ### Sign in with Apple server-to-server notifications
220
220
 
221
- Register an Apple client with `apple.notificationUrl` (an HTTP(S) URL; requires the JWT `apple` client form) and the mock behaves like Apple's [server-to-server notification endpoint](https://developer.apple.com/documentation/signinwithapplerestapi/processing-changes-for-sign-in-with-apple-accounts): it POSTs `{"payload": "<JWS>"}` as JSON. The JWS is signed by the current signing key (verify it against the JWKS) with `iss` = the issuer, `aud` = the client id, `iat` from the mock clock and a random `jti`. `events` is a JSON string of `{ type, sub, event_time }`, where `sub` is the client's identity for the account and `event_time` is milliseconds from the mock clock.
221
+ Register an Apple client with `apple.notificationUrl` (an HTTP(S) URL; requires the JWT `apple` client form) and the emulator behaves like Apple's [server-to-server notification endpoint](https://developer.apple.com/documentation/signinwithapplerestapi/processing-changes-for-sign-in-with-apple-accounts): it POSTs `{"payload": "<JWS>"}` as JSON. The JWS is signed by the current signing key (verify it against the JWKS) with `iss` = the issuer, `aud` = the client id, `iat` from the emulator clock and a random `jti`. `events` is a JSON string of `{ type, sub, event_time }`, where `sub` is the client's identity for the account and `event_time` is milliseconds from the emulator clock.
222
222
 
223
223
  | Trigger | Event `type` | Sent to |
224
224
  | --- | --- | --- |
@@ -250,7 +250,7 @@ const runtime = createRuntime({
250
250
 
251
251
  ### Shared service controls
252
252
 
253
- The runtime supplies `/__admin/health`, `/__admin/reset`, snapshots, mock clock, request journal, metrics, fault injection and namespace isolation. Use `x-mockingbird-namespace` for in-process tests or `/__admin/ns/<name>/…` for complete browser flows. Header-selected namespaces alone cannot persist across ordinary browser navigation. State, grants, sessions and consent live in the shared SQLite abstraction; there are no filesystem or Node imports in the main entry.
253
+ The runtime supplies `/__admin/health`, `/__admin/reset`, snapshots, emulator clock, request journal, metrics, fault injection and namespace isolation. Use `x-mockingbird-namespace` for in-process tests or `/__admin/ns/<name>/…` for complete browser flows. Header-selected namespaces alone cannot persist across ordinary browser navigation. State, grants, sessions and consent live in the shared SQLite abstraction; there are no filesystem or Node imports in the main entry.
254
254
 
255
255
  `OAUTH_PRESETS` includes `token_unavailable` and `access_denied`. Fault rules can also target a provider-specific path, e.g. `POST /__admin/faults` with `{"pathPrefix":"/auth/token","status":503,"body":{"error":"temporarily_unavailable"}}`. The only outbound requests are the Apple notifications above. Journals contain request metadata, never passwords or request bodies.
256
256
 
@@ -282,7 +282,7 @@ references below.
282
282
 
283
283
  This is a ready-to-use local/test identity provider, **not a production authentication server or a claim that every proprietary provider feature is implemented**. Its ready tier covers the documented OAuth/OIDC login, identity, consent, token, provider-edge-case, and UI surface. Applications should still run a small final check against each real provider before release.
284
284
 
285
- Vendor-hosted Google Identity Services/One Tap, native Apple AuthenticationServices, passkeys, MFA, CAPTCHA, password recovery, email delivery/relay forwarding (only Apple's notification of a forwarding change is sent), app-transfer migration, vendor risk engines, tokeninfo/introspection, logout, GitHub Apps installation/device flows, and Microsoft Graph/tenant administration are not implemented. Other configurable OIDC providers can use the generic profile, but their proprietary scopes and claims are not emulated. Scopes are limited to each profile plus explicitly configured additional scopes. Microsoft uses the configured mock issuer, not real Entra tenant routing. GitHub is the OAuth app login surface, not the full REST API.
285
+ Vendor-hosted Google Identity Services/One Tap, native Apple AuthenticationServices, passkeys, MFA, CAPTCHA, password recovery, email delivery/relay forwarding (only Apple's notification of a forwarding change is sent), app-transfer migration, vendor risk engines, tokeninfo/introspection, logout, GitHub Apps installation/device flows, and Microsoft Graph/tenant administration are not implemented. Other configurable OIDC providers can use the generic profile, but their proprietary scopes and claims are not emulated. Scopes are limited to each profile plus explicitly configured additional scopes. Microsoft uses the configured emulator issuer, not real Entra tenant routing. GitHub is the OAuth app login surface, not the full REST API.
286
286
 
287
287
  No implicit flow, dynamic client registration, wildcard redirect matching, persistent signing-key storage (keys are held in memory; supply them through `signingKeys` or derive them from a seed), or distributed-session coordination is provided. Private-use redirect schemes work only when their complete URI is explicitly registered; executable/local schemes such as `javascript:`, `data:` and `file:` are rejected. Sign-in and consent pages extend CSP `form-action` with the transaction's redirect origin (or custom scheme). Browser navigation responses use a provider-owned handoff document so the callback can relay through another origin without inheriting the consent form's policy; direct programmatic interaction requests retain their HTTP redirect response. Discovery, JWKS, token, userinfo and revoke answer `OPTIONS` preflights and reflect the request `Origin`, so browser (SPA + PKCE) clients can redeem codes directly; the interaction pages send no CORS headers. Snapshot restore is for the same runtime/instance; signing keys are not serialized. The default backing store is in-memory and state disappears when the process exits. A secure browser context and Web Crypto, Fetch and standard Web APIs are required; Node 22+, Bun and modern browsers provide them.
288
288
 
@@ -305,7 +305,7 @@ state.
305
305
  The service-owned source lives in `examples/google-login/`: a real Hono app uses
306
306
  `oauth4webapi` to discover OIDC providers, generate PKCE/state/nonce, exchange the code, verify
307
307
  JWT signatures against JWKS, fetch identity data, and establish a session. GitHub mode uses its
308
- explicit OAuth endpoints, numeric account ID, and `/user/emails` fallback. Popup mode keeps the host app visible while a separate sign-in window renders the mock's
308
+ explicit OAuth endpoints, numeric account ID, and `/user/emails` fallback. Popup mode keeps the host app visible while a separate sign-in window renders the emulator's
309
309
  actual HTML response. Redirect mode replaces the preview with the provider document and
310
310
  returns to the app on callback. The popup closes on callback and the app updates with the result. Browsers that
311
311
  block new windows use a separate modal dialog with its own provider document. Closing the
@@ -324,7 +324,7 @@ standard cookie headers. This mapping is a transport detail, not a browser cooki
324
324
 
325
325
  ### Presentation and account selection
326
326
 
327
- The provider UI is neutral and labelled **OAuth Mock**, with no vendor or product branding.
327
+ The provider UI is neutral and labelled **OAuth Emulator**, with no vendor or product branding.
328
328
  Its **System / Light / Dark** controls work on standalone HTML pages; the selection persists
329
329
  across pages in that browser session. The in-process example bridges the same controls into
330
330
  the pasted pages. System mode follows the operating system, independently of the
@@ -346,7 +346,7 @@ const dispose = await mount(host, {
346
346
 
347
347
  Popup versus redirect is an application presentation choice; both use the same authorization
348
348
  endpoint and callback validation. The demo uses `prompt=select_account` to force the chooser.
349
- For any integrating app, session reuse can also be disabled on the mock itself:
349
+ For any integrating app, session reuse can also be disabled on the emulator itself:
350
350
 
351
351
  ```ts
352
352
  import { OAuthAPI } from "@crvouga/mockingbird-service-oauth"
package/SUPPORT.md CHANGED
@@ -3,16 +3,16 @@
3
3
  Generated from `openapi.yaml`; do not edit by hand.
4
4
 
5
5
  - operations in spec: **32**
6
- - supported by the mock: **32**
6
+ - supported by the emulator: **32**
7
7
  - parity enabled: **4**
8
8
 
9
- | operationId | route | mock | parity | notes |
9
+ | operationId | route | emulator | parity | notes |
10
10
  | --- | --- | --- | --- | --- |
11
11
  | `Discovery` | `GET /.well-known/openid-configuration` | ✅ supported | ✅ | Google, Apple and Microsoft discovery metadata is checked against their public live endpoints by scripts/parity.ts. |
12
12
  | `Jwks` | `GET /jwks` | ✅ supported | ❌ disabled | Interactive OAuth transactions are exercised by protocol and independent JOSE tests. |
13
13
  | `Authorize` | `GET /authorize` | ✅ supported | ❌ disabled | Interactive OAuth transactions are exercised by protocol and independent JOSE tests. |
14
- | `InteractionPage` | `GET /interaction` | ✅ supported | ❌ disabled | Interactive OAuth transactions are exercised by protocol and independent JOSE tests. The pages carry the documented oauth-mock-* data-testid hooks (README, "Test hooks on the interaction pages"). |
15
- | `Interact` | `POST /interaction` | ✅ supported | ❌ disabled | Interactive OAuth transactions are exercised by protocol and independent JOSE tests. The pages carry the documented oauth-mock-* data-testid hooks (README, "Test hooks on the interaction pages"). |
14
+ | `InteractionPage` | `GET /interaction` | ✅ supported | ❌ disabled | Interactive OAuth transactions are exercised by protocol and independent JOSE tests. The pages carry the documented oauth-emulator-* data-testid hooks (README, "Test hooks on the interaction pages"). |
15
+ | `Interact` | `POST /interaction` | ✅ supported | ❌ disabled | Interactive OAuth transactions are exercised by protocol and independent JOSE tests. The pages carry the documented oauth-emulator-* data-testid hooks (README, "Test hooks on the interaction pages"). |
16
16
  | `Token` | `POST /token` | ✅ supported | ❌ disabled | Interactive OAuth transactions are exercised by protocol and independent JOSE tests. |
17
17
  | `UserInfo` | `GET /userinfo` | ✅ supported | ❌ disabled | Interactive OAuth transactions are exercised by protocol and independent JOSE tests. |
18
18
  | `UserInfoPost` | `POST /userinfo` | ✅ supported | ❌ disabled | Interactive OAuth transactions are exercised by protocol and independent JOSE tests. |
@@ -5,7 +5,7 @@ import {
5
5
  createRuntime,
6
6
  parseDuration,
7
7
  resolveAdminPrefix
8
- } from "./chunk-L7GVSS4G.js";
8
+ } from "./chunk-LAL7G624.js";
9
9
 
10
10
  // src/server.ts
11
11
  import { readFile as readFile3 } from "node:fs/promises";
@@ -168,7 +168,9 @@ var httpChild = async (target, entry, options) => {
168
168
  adminPrefix: resolveAdminPrefix(entry.adminPrefix),
169
169
  adminKey: entry.adminKey,
170
170
  seed: entry.seed,
171
- onLog: options.onLog
171
+ onLog: options.onLog,
172
+ ...entry.fixtures !== void 0 ? { fixtures: entry.fixtures } : {},
173
+ ...entry.baseUrl !== void 0 ? { baseUrl: entry.baseUrl } : {}
172
174
  });
173
175
  const adminPrefix = resolveAdminPrefix(entry.adminPrefix);
174
176
  runtime.isolateNamespaces();
@@ -714,7 +716,7 @@ var start = async (target, values, config) => {
714
716
  });
715
717
  const listening = await listen(runtime, { port: config.port, host: config.host });
716
718
  target.listening?.(listening);
717
- console.log(`${target.name} mock listening on ${listening.url}`);
719
+ console.log(`${target.name} emulator listening on ${listening.url}`);
718
720
  console.log(`${target.name} health: GET ${listening.url}${adminPrefix}/health`);
719
721
  console.log(`${target.name} admin: ${listening.url}${adminPrefix} (${config.adminKey ? "x-mockingbird-admin-key required" : "open \u2014 pass --admin-key to lock"})`);
720
722
  console.log(`${target.name} admin ui: ${listening.url}${adminPrefix}/ui`);
@@ -734,7 +736,7 @@ var untilSignal = async (servers) => new Promise((resolve2) => {
734
736
  process.once("SIGTERM", stop);
735
737
  });
736
738
  var serveCommand = (target) => ({
737
- summary: `Serve the ${target.name} mock or a configured fleet`,
739
+ summary: `Serve the ${target.name} emulator or a configured fleet`,
738
740
  options: { ...COMMON_SERVE_OPTIONS, ..."options" in target ? target.options : {} },
739
741
  async run(values) {
740
742
  const log = values["log-requests"] === true ? "json" : asString(values.log) ?? "pretty";
@@ -760,7 +762,7 @@ var serveCommand = (target) => ({
760
762
  console.log(JSON.stringify(manifest));
761
763
  else
762
764
  for (const [name, endpoint] of Object.entries(manifest.services))
763
- console.log(`${name} mock listening on ${endpoint.url}`);
765
+ console.log(`${name} emulator listening on ${endpoint.url}`);
764
766
  }
765
767
  });
766
768
  return untilSignal([fleet]);
@@ -867,4 +869,4 @@ export {
867
869
  createMultiServer,
868
870
  serveTarget
869
871
  };
870
- //# sourceMappingURL=chunk-YNOWCZWB.js.map
872
+ //# sourceMappingURL=chunk-AHMLLR4I.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/server.ts", "../../../adapters/node/src/cli.ts", "../../../adapters/node/src/fleet.ts", "../../../adapters/node/src/serve.ts", "../../../adapters/node/src/listen.ts"],
4
+ "sourcesContent": ["/// <reference types=\"node\" />\nimport { readFile } from \"node:fs/promises\"\nimport { type Listening, listen, type ServeTarget } from \"@crvouga/mockingbird-adapter-node\"\nimport { OAUTH_SCENARIOS, type OAuthScenario } from \"./behavior.js\"\nimport {\n createMultiRuntime,\n type OAuthMount,\n type OAuthMultiRuntime,\n type OAuthMultiRuntimeOptions,\n} from \"./multi.js\"\nimport { createRuntime, type OAuthRuntime, type OAuthRuntimeOptions } from \"./runtime.js\"\nexport const DEFAULT_PORT = 8810\nexport type OAuthServerOptions = OAuthRuntimeOptions & { port?: number; host?: string }\nexport const createServer = async (\n options: OAuthServerOptions = {},\n): Promise<Listening & { runtime: OAuthRuntime }> => {\n const { port, host, ...rest } = options\n const runtime = createRuntime(rest)\n return { ...(await listen(runtime, { port: port ?? 0, ...(host ? { host } : {}) })), runtime }\n}\nexport type OAuthMultiServerOptions = OAuthMultiRuntimeOptions & { port?: number; host?: string }\nexport const createMultiServer = async (\n options: OAuthMultiServerOptions,\n): Promise<Listening & { runtime: OAuthMultiRuntime }> => {\n const { port, host, ...rest } = options\n const runtime = createMultiRuntime(rest)\n return { ...(await listen(runtime, { port: port ?? 0, ...(host ? { host } : {}) })), runtime }\n}\nexport const serveTarget: ServeTarget = {\n name: \"oauth\",\n defaultPort: DEFAULT_PORT,\n options: {\n provider: {\n type: \"string\",\n value: \"<google|apple|microsoft|github|oidc>\",\n description: \"Provider wire profile (default oidc)\",\n },\n scenario: {\n type: \"string\",\n value: \"<name>\",\n description: \"Initial behavior scenario (GET /__admin/scenarios lists all)\",\n },\n issuer: { type: \"string\", value: \"<url>\", description: \"Public issuer URL\" },\n mounts: {\n type: \"string\",\n value: \"<file>\",\n description: \"JSON file with a mounts array; serves every provider on one listener\",\n },\n },\n create: async (values, common) => {\n if (typeof values.mounts === \"string\") {\n const parsed = JSON.parse(await readFile(values.mounts, \"utf8\")) as { mounts?: OAuthMount[] }\n if (!Array.isArray(parsed.mounts))\n throw new Error(\"OAuth mounts file requires a mounts array\")\n return createMultiRuntime({\n mounts: parsed.mounts,\n ...(common.seed !== undefined ? { seed: common.seed } : {}),\n ...(common.adminPrefix !== undefined ? { adminPrefix: common.adminPrefix } : {}),\n ...(common.adminKey !== undefined ? { adminKey: common.adminKey } : {}),\n }) as unknown as OAuthRuntime\n }\n const provider = values.provider ?? \"oidc\"\n if (\n provider !== \"google\" &&\n provider !== \"apple\" &&\n provider !== \"oidc\" &&\n provider !== \"microsoft\" &&\n provider !== \"github\"\n )\n throw new Error(\"provider must be google, apple, microsoft, github or oidc\")\n if (\n values.scenario !== undefined &&\n (typeof values.scenario !== \"string\" || !Object.hasOwn(OAUTH_SCENARIOS, values.scenario))\n )\n throw new Error(\"Unknown OAuth scenario\")\n return createRuntime({\n provider,\n ...(typeof values.scenario === \"string\"\n ? { behavior: { preset: values.scenario as OAuthScenario } }\n : {}),\n ...(common.seed !== undefined ? { seed: common.seed } : {}),\n ...(typeof values.issuer === \"string\" ? { issuer: values.issuer } : {}),\n ...(common.adminPrefix !== undefined ? { adminPrefix: common.adminPrefix } : {}),\n ...(common.adminKey !== undefined ? { adminKey: common.adminKey } : {}),\n })\n },\n banner: () => [\n \"Register clients: POST /__admin/clients; seed identities: POST /__admin/accounts\",\n \"Discovery: /.well-known/openid-configuration\",\n ],\n}\n", "import type { EventEmitter } from \"node:events\"\nimport { readFile } from \"node:fs/promises\"\nimport { createRequire } from \"node:module\"\nimport { resolve } from \"node:path\"\nimport { pathToFileURL } from \"node:url\"\nimport { type ParseArgsConfig, parseArgs } from \"node:util\"\nimport type { RequestLog, ServiceInstance, ServiceRuntime } from \"@crvouga/mockingbird-service\"\nimport { resolveAdminPrefix } from \"@crvouga/mockingbird-service\"\nimport { type FleetTarget, startFleet } from \"./fleet.js\"\nimport { type Listening, listen } from \"./listen.js\"\n\nexport type CliOption = {\n type: \"string\" | \"boolean\"\n description: string\n /** Shown in help; the value placeholder, e.g. `<port>`. */\n value?: string\n default?: string | boolean\n}\n\nexport type CliValues = Record<string, string | boolean | undefined>\n\nexport type CliCommand = {\n summary: string\n usage?: string\n options?: Record<string, CliOption>\n /** Resolves to an exit code; a server command resolves only when it stops. */\n run(values: CliValues, positionals: string[]): Promise<number>\n}\n\nexport type CliSpec = {\n bin: string\n description: string\n commands: Record<string, CliCommand>\n}\n\nconst optionHelp = (options: Record<string, CliOption>): string[] =>\n Object.entries(options).map(([name, option]) => {\n const flag = `--${name}${option.type === \"string\" ? ` ${option.value ?? \"<value>\"}` : \"\"}`\n const fallback = option.default !== undefined ? ` (default: ${String(option.default)})` : \"\"\n return ` ${flag.padEnd(30)} ${option.description}${fallback}`\n })\n\nconst help = (spec: CliSpec): string =>\n [\n `${spec.bin} \u2014 ${spec.description}`,\n \"\",\n \"Usage:\",\n ` ${spec.bin} <command> [options]`,\n \"\",\n \"Commands:\",\n ...Object.entries(spec.commands).map(([name, c]) => ` ${name.padEnd(30)} ${c.summary}`),\n \"\",\n `Run \\`${spec.bin} <command> --help\\` for a command's options.`,\n ].join(\"\\n\")\n\nconst commandHelp = (spec: CliSpec, name: string, command: CliCommand): string =>\n [\n `${spec.bin} ${name} \u2014 ${command.summary}`,\n \"\",\n \"Usage:\",\n ` ${command.usage ?? `${spec.bin} ${name} [options]`}`,\n ...(command.options ? [\"\", \"Options:\", ...optionHelp(command.options)] : []),\n ].join(\"\\n\")\n\n/** Parse `argv` against `spec` and run the chosen command. Resolves to an exit code. */\nexport const runCli = async (spec: CliSpec, argv: string[]): Promise<number> => {\n // Two-word commands (`corpus pull`) win over one-word ones.\n const pair = argv.length >= 2 ? `${argv[0]} ${argv[1]}` : undefined\n const words = pair !== undefined && spec.commands[pair] ? 2 : 1\n const name = words === 2 ? pair : argv[0]\n const rest = argv.slice(words)\n if (name === undefined || name === \"--help\" || name === \"-h\" || name === \"help\") {\n console.log(help(spec))\n return 0\n }\n const command = spec.commands[name]\n if (!command) {\n console.error(`${spec.bin}: unknown command ${JSON.stringify(name)}\\n\\n${help(spec)}`)\n return 2\n }\n if (rest.includes(\"--help\") || rest.includes(\"-h\")) {\n console.log(commandHelp(spec, name, command))\n return 0\n }\n let parsed: { values: CliValues; positionals: string[] }\n try {\n parsed = parseArgs({\n args: rest,\n allowPositionals: true,\n strict: true,\n options: Object.fromEntries(\n Object.entries(command.options ?? {}).map(([key, option]) => [\n key,\n {\n type: option.type,\n ...(option.default !== undefined ? { default: option.default } : {}),\n },\n ]),\n ) as ParseArgsConfig[\"options\"],\n }) as { values: CliValues; positionals: string[] }\n } catch (error) {\n console.error(\n `${spec.bin} ${name}: ${error instanceof Error ? error.message : String(error)}\\n\\n${commandHelp(spec, name, command)}`,\n )\n return 2\n }\n return command.run(parsed.values, parsed.positionals)\n}\n\n// \u2500\u2500 serve \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type LogFormat = \"pretty\" | \"json\" | \"off\"\n\nexport type CommonServeOptions = {\n adminPrefix?: string\n adminKey: string | undefined\n seed: string | undefined\n onLog: ((entry: RequestLog) => void) | undefined\n /** Synthetic provider fixture objects supplied by a fleet entry. */\n fixtures?: Record<string, unknown>\n baseUrl?: string\n}\n\n/**\n * What a service contributes to `serve`: how to build its runtime from CLI flags,\n * and what to say at startup. Every service's `./server` entry exports one as\n * `serveTarget`, which is also how `serve --config` finds services by name.\n */\nexport type ServeTarget = {\n name: string\n defaultPort: number\n /** Serve flags beyond the common ones. */\n options?: Record<string, CliOption>\n create(\n values: CliValues,\n common: CommonServeOptions,\n ): Promise<ServiceRuntime<ServiceInstance>> | ServiceRuntime<ServiceInstance>\n /** Startup lines after the listen address, e.g. the loaded corpus version. */\n banner?(runtime: ServiceRuntime<ServiceInstance>): string[]\n /** After the HTTP server is bound. A service that speaks more than HTTP attaches it here. */\n listening?(server: Listening): void\n}\n\nconst COMMON_SERVE_OPTIONS: Record<string, CliOption> = {\n port: { type: \"string\", value: \"<port>\", description: \"Port to listen on\" },\n host: { type: \"string\", value: \"<host>\", description: \"Interface to bind\", default: \"127.0.0.1\" },\n \"admin-prefix\": {\n type: \"string\",\n value: \"<path>\",\n description: \"Internal API prefix (default /__admin; env MOCKINGBIRD_ADMIN_PREFIX)\",\n },\n \"admin-key\": {\n type: \"string\",\n value: \"<key>\",\n description: \"Require x-mockingbird-admin-key on /__admin/* (env MOCKINGBIRD_ADMIN_KEY)\",\n },\n seed: { type: \"string\", value: \"<seed>\", description: \"Seed for every random choice\" },\n log: {\n type: \"string\",\n value: \"<pretty|json|off>\",\n description: \"Request log format\",\n default: \"pretty\",\n },\n \"log-requests\": {\n type: \"boolean\",\n description:\n \"One JSON line per request: namespace, operationId, status, ids touched (never bodies). Same as --log json\",\n },\n config: {\n type: \"string\",\n value: \"<file>\",\n description: \"Serve every service in a mockingbird.json config instead\",\n },\n \"ready-file\": {\n type: \"string\",\n description: \"Atomically publish fleet endpoint JSON\",\n value: \"<file>\",\n },\n \"connections-file\": {\n type: \"string\",\n description: \"Write private connection URLs with mode 0600\",\n value: \"<file>\",\n },\n \"ready-json\": {\n type: \"boolean\",\n description: \"Emit one public JSON record after fleet readiness\",\n },\n}\n\nconst formatLog = (format: LogFormat) => {\n if (format === \"off\") return undefined\n if (format === \"json\") return (entry: RequestLog) => console.log(JSON.stringify(entry))\n return (entry: RequestLog) => {\n const op = entry.operationId ?? (entry.unmatched ? \"UNMATCHED\" : \"-\")\n const ns = entry.namespace === \"default\" ? \"\" : ` [${entry.namespace}]`\n const fault = entry.faultId ? ` fault=${entry.faultId}` : \"\"\n const adopted = entry.adopted ? \" adopted\" : \"\"\n // A rejection says what arrived (never the body) and why the service refused it.\n const received = entry.request\n ? ` received=${entry.request.bodyBytes === null ? \"?\" : `${entry.request.bodyBytes}B`} ct=${entry.request.contentType ?? \"-\"}${\n entry.request.transferEncoding ? ` te=${entry.request.transferEncoding}` : \"\"\n }`\n : \"\"\n const issues = entry.issues?.length\n ? ` issues=${entry.issues\n .slice(0, 3)\n .map((issue) => `${issue.path || \"$\"}: ${issue.message}`)\n .join(\"; \")}${entry.issues.length > 3 ? ` (+${entry.issues.length - 3})` : \"\"}`\n : \"\"\n console.log(\n `${entry.service} ${entry.method} ${entry.path} ${entry.status} ${op} ${entry.durationMs}ms${ns}${fault}${adopted}${received}${issues}`,\n )\n }\n}\n\nconst asString = (value: string | boolean | undefined): string | undefined =>\n typeof value === \"string\" ? value : undefined\n\n/** A service entry in `mockingbird.json`. */\nexport type ConfigService = {\n protocol?: \"http\" | \"postgres\" | \"redis\"\n port?: number\n host?: string\n adminPrefix?: string\n adminKey?: string\n seed?: string\n fixtures?: Record<string, unknown>\n baseUrl?: string\n password?: string\n user?: string\n database?: string\n /** Protocol namespace selectors: database names for Postgres, logical DB indexes for Redis. */\n namespaces?: Record<string, string | number>\n /** Service-specific serve flags, by long name: `{ \"webhook-url\": \"\u2026\" }`. */\n options?: Record<string, string | boolean>\n}\n\nexport type MockingbirdConfig = {\n /** Keyed by service name: `junction` loads `@crvouga/mockingbird-service-junction`. */\n services: Record<string, ConfigService>\n log?: LogFormat\n adminPrefix?: string\n adminKey?: string\n namespace?: string\n control?: { host?: string; port?: number }\n}\n\nconst loadTarget = async (name: string, own: FleetTarget): Promise<FleetTarget> => {\n if (name === own.name) return own\n const specifier = `@crvouga/mockingbird-service-${name}/server`\n try {\n // A CLI run with npx may live outside the consumer project. Discover its locally\n // installed services as well as siblings of the bundled CLI.\n let mod: { serveTarget?: FleetTarget }\n try {\n mod = (await import(specifier)) as { serveTarget?: FleetTarget }\n } catch {\n const fromProject = createRequire(resolve(process.cwd(), \"package.json\"))\n mod = (await import(pathToFileURL(fromProject.resolve(specifier)).href)) as {\n serveTarget?: FleetTarget\n }\n }\n if (!mod.serveTarget) throw new Error(`${specifier} exports no serveTarget`)\n return mod.serveTarget\n } catch (error) {\n const reason = error instanceof Error ? error.message : String(error)\n throw new Error(\n `cannot load service \"${name}\": ${reason}. Install @crvouga/mockingbird-service-${name}.`,\n )\n }\n}\n\nconst start = async (\n target: ServeTarget,\n values: CliValues,\n config: {\n port: number\n host: string\n adminPrefix?: string\n adminKey?: string\n seed?: string\n log: LogFormat\n },\n): Promise<Listening> => {\n const adminPrefix = resolveAdminPrefix(config.adminPrefix)\n const runtime = await target.create(values, {\n adminPrefix,\n adminKey: config.adminKey,\n seed: config.seed,\n onLog: formatLog(config.log),\n })\n const listening = await listen(runtime, { port: config.port, host: config.host })\n target.listening?.(listening)\n console.log(`${target.name} emulator listening on ${listening.url}`)\n console.log(`${target.name} health: GET ${listening.url}${adminPrefix}/health`)\n console.log(\n `${target.name} admin: ${listening.url}${adminPrefix} (${config.adminKey ? \"x-mockingbird-admin-key required\" : \"open \u2014 pass --admin-key to lock\"})`,\n )\n console.log(`${target.name} admin ui: ${listening.url}${adminPrefix}/ui`)\n for (const line of target.banner?.(runtime) ?? [])\n console.log(`${target.name} ${line.replaceAll(\"/__admin\", adminPrefix)}`)\n return listening\n}\n\nconst untilSignal = async (servers: { close(): Promise<void> }[]): Promise<number> =>\n new Promise((resolve) => {\n const stop = async () => {\n ;(process as EventEmitter).removeListener(\"SIGINT\", stop)\n ;(process as EventEmitter).removeListener(\"SIGTERM\", stop)\n await Promise.allSettled(servers.map((s) => s.close()))\n resolve(0)\n }\n process.once(\"SIGINT\", stop)\n process.once(\"SIGTERM\", stop)\n })\n\n/** The standard `serve` command for a service, including multi-service `--config`. */\nexport const serveCommand = (target: FleetTarget): CliCommand => ({\n summary: `Serve the ${target.name} emulator or a configured fleet`,\n options: { ...COMMON_SERVE_OPTIONS, ...(\"options\" in target ? target.options : {}) },\n async run(values) {\n const log = (\n values[\"log-requests\"] === true ? \"json\" : (asString(values.log) ?? \"pretty\")\n ) as LogFormat\n if (![\"pretty\", \"json\", \"off\"].includes(log)) {\n console.error(`--log must be pretty, json or off (got ${log})`)\n return 2\n }\n const configPath = asString(values.config)\n if (configPath !== undefined) {\n try {\n const config = JSON.parse(await readFile(configPath, \"utf8\")) as MockingbirdConfig\n config.adminPrefix = resolveAdminPrefix(\n config.adminPrefix ??\n asString(values[\"admin-prefix\"]) ??\n process.env.MOCKINGBIRD_ADMIN_PREFIX,\n )\n const adminKey =\n config.adminKey ?? asString(values[\"admin-key\"]) ?? process.env.MOCKINGBIRD_ADMIN_KEY\n if (adminKey !== undefined) config.adminKey = adminKey\n const fleet = await startFleet(config, {\n load: (name) => loadTarget(name, target),\n onLog: formatLog(config.log ?? log),\n ...(asString(values[\"ready-file\"]) ? { readyFile: asString(values[\"ready-file\"]) } : {}),\n ...(asString(values[\"connections-file\"])\n ? { connectionsFile: asString(values[\"connections-file\"]) }\n : {}),\n onReady: (manifest) => {\n if (values[\"ready-json\"]) console.log(JSON.stringify(manifest))\n else\n for (const [name, endpoint] of Object.entries(manifest.services))\n console.log(`${name} emulator listening on ${endpoint.url}`)\n },\n })\n return untilSignal([fleet])\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error))\n return 1\n }\n }\n if (\"start\" in target) {\n console.error(\"Use --config to supervise protocol services with this command\")\n return 2\n }\n const port = asString(values.port)\n const adminKey = asString(values[\"admin-key\"]) ?? process.env.MOCKINGBIRD_ADMIN_KEY\n const seed = asString(values.seed)\n let listening: Listening\n try {\n listening = await start(target, values, {\n adminPrefix: resolveAdminPrefix(\n asString(values[\"admin-prefix\"]) ?? process.env.MOCKINGBIRD_ADMIN_PREFIX,\n ),\n port: port === undefined ? target.defaultPort : Number.parseInt(port, 10),\n host: asString(values.host) ?? \"127.0.0.1\",\n ...(adminKey !== undefined ? { adminKey } : {}),\n ...(seed !== undefined ? { seed } : {}),\n log,\n })\n } catch (error) {\n console.error(error instanceof Error ? error.message : String(error))\n return 1\n }\n return untilSignal([listening])\n },\n})\n", "import { randomUUID } from \"node:crypto\"\nimport { chmod, readFile, rename, rm, writeFile } from \"node:fs/promises\"\nimport type { FetchAPI } from \"@crvouga/mockingbird-core\"\nimport type { Clock, ServiceInstance, ServiceRuntime } from \"@crvouga/mockingbird-service\"\nimport { createClock, parseDuration, resolveAdminPrefix } from \"@crvouga/mockingbird-service\"\nimport type { CommonServeOptions, ConfigService, MockingbirdConfig, ServeTarget } from \"./cli.js\"\nimport type { EndpointManifest } from \"./fleet-manifest.js\"\nimport { type Listening, listen } from \"./listen.js\"\n\nexport type { EndpointManifest } from \"./fleet-manifest.js\"\n\nexport type FleetDiagnostics = {\n activeRequests: number\n activeConnections: number\n blockedCommands: number\n pendingJobs: number\n activeJobs?: number\n pendingWebhooks: number\n unmatchedRequests: number\n}\n\n/** Protocol packages own their state, listeners, credentials and namespace selection. */\nexport type FleetChild = {\n protocol: \"http\" | \"postgres\" | \"redis\"\n url: string\n connection?: string\n connections?: Record<string, string>\n healthUrl?: string\n adminUrl?: string\n namespaces: Record<string, unknown>\n ready(): Promise<boolean>\n close(): Promise<void>\n /** Fence new work synchronously; diagnostics must also account for work already in flight. */\n lock(namespace: string): () => void\n diagnostics(namespace: string): FleetDiagnostics\n checkpoint(namespace: string): Promise<unknown>\n restore(namespace: string, checkpoint: unknown): Promise<void>\n reset(namespace: string): Promise<void>\n clock(namespace: string): Clock\n settle?(namespace: string): Promise<void>\n}\n\nexport type ProtocolTarget = {\n name: string\n protocol: \"postgres\" | \"redis\"\n defaultPort: number\n start(entry: ConfigService): Promise<FleetChild>\n}\nexport type FleetTarget = ServeTarget | ProtocolTarget\n\nexport type FleetOptions = {\n load(name: string): Promise<FleetTarget>\n onLog?: CommonServeOptions[\"onLog\"]\n readyFile?: string | undefined\n connectionsFile?: string | undefined\n onReady?(manifest: EndpointManifest): void\n}\n\nconst EMPTY: FleetDiagnostics = {\n activeRequests: 0,\n activeConnections: 0,\n blockedCommands: 0,\n pendingJobs: 0,\n pendingWebhooks: 0,\n unmatchedRequests: 0,\n}\nconst NS = /^[A-Za-z0-9_.-]{1,64}$/\nconst json = (status: number, value: unknown) => Response.json(value, { status })\nconst isObject = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\nconst pending = (d: FleetDiagnostics) =>\n d.activeRequests + d.blockedCommands + d.pendingJobs + d.pendingWebhooks\n\nconst publicUrl = (raw: string): string => {\n const url = new URL(raw)\n url.password = \"\"\n return url.href\n}\n\n/** Atomic publication; credentials only go in an explicitly requested 0600 file. */\nconst atomicWrite = async (path: string, value: unknown) => {\n const temp = `${path}.${randomUUID()}.tmp`\n try {\n await writeFile(temp, `${JSON.stringify(value, null, 2)}\\n`, { mode: 0o600, flag: \"wx\" })\n await chmod(temp, 0o600)\n await rename(temp, path)\n } finally {\n await rm(temp, { force: true })\n }\n}\n\nconst removeOwned = async (path: string | undefined, id: string) => {\n if (!path) return\n try {\n const value: unknown = JSON.parse(await readFile(path, \"utf8\"))\n if (isObject(value) && value.id === id) await rm(path, { force: true })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") throw error\n }\n}\n\nconst httpChild = async (\n target: ServeTarget,\n entry: ConfigService,\n options: FleetOptions,\n): Promise<FleetChild> => {\n const runtime: ServiceRuntime<ServiceInstance> = await target.create(entry.options ?? {}, {\n adminPrefix: resolveAdminPrefix(entry.adminPrefix),\n adminKey: entry.adminKey,\n seed: entry.seed,\n onLog: options.onLog,\n ...(entry.fixtures !== undefined ? { fixtures: entry.fixtures } : {}),\n ...(entry.baseUrl !== undefined ? { baseUrl: entry.baseUrl } : {}),\n })\n const adminPrefix = resolveAdminPrefix(entry.adminPrefix)\n runtime.isolateNamespaces()\n const locked = new Set<string>()\n const active = new Map<string, number>()\n const api: FetchAPI = {\n async fetch(request) {\n const namespace = runtime.namespaceOf(request)\n if (locked.has(namespace)) return json(409, { error: \"fleet control in progress\", namespace })\n active.set(namespace, (active.get(namespace) ?? 0) + 1)\n try {\n return await runtime.fetch(request)\n } finally {\n active.set(namespace, (active.get(namespace) ?? 1) - 1)\n }\n },\n }\n let server: Listening | undefined\n try {\n server = await listen(api, {\n port: entry.port ?? target.defaultPort,\n host: entry.host ?? \"127.0.0.1\",\n })\n target.listening?.(server)\n } catch (error) {\n runtime.stop?.()\n await server?.close()\n runtime.webhooks?.clear()\n await runtime.webhooks?.idle()\n throw error\n }\n return {\n protocol: \"http\",\n url: server.url,\n healthUrl: `${server.url}${adminPrefix}/health`,\n adminUrl: `${server.url}${adminPrefix}`,\n namespaces: { header: \"x-mockingbird-namespace\", path: `${adminPrefix}/ns/{name}` },\n ready: async () => {\n try {\n return (\n await fetch(`${server.url}${adminPrefix}/health`, { signal: AbortSignal.timeout(2000) })\n ).ok\n } catch {\n return false\n }\n },\n async close() {\n runtime.stop?.()\n runtime.webhooks?.clear()\n await server.close()\n await runtime.webhooks?.idle()\n },\n lock(namespace) {\n if (locked.has(namespace)) throw new Error(\"namespace already locked\")\n locked.add(namespace)\n return () => locked.delete(namespace)\n },\n diagnostics(namespace) {\n return {\n ...EMPTY,\n activeRequests: active.get(namespace) ?? 0,\n pendingWebhooks: runtime.webhooks?.pending(namespace) ?? 0,\n unmatchedRequests: runtime.metrics\n .report(namespace)\n .unmatched.reduce((n, r) => n + r.count, 0),\n }\n },\n async checkpoint(namespace) {\n return runtime.fleetSnapshot(namespace)\n },\n async restore(namespace, checkpoint) {\n runtime.fleetRestore(checkpoint, namespace)\n },\n reset: (namespace) => runtime.reset(namespace),\n clock: (namespace) => runtime.namespaceClock(namespace),\n async settle(namespace) {\n const instance = runtime.instance(namespace) as ServiceInstance & { tick?(): unknown }\n instance.tick?.()\n await runtime.webhooks?.idle()\n },\n }\n}\n\nexport type Fleet = {\n readonly manifest: EndpointManifest\n readonly children: ReadonlyMap<string, FleetChild>\n fetch(request: Request): Promise<Response>\n close(): Promise<void>\n}\n\n/** Resolves only after every child and the aggregate control listener are healthy. */\nexport async function startFleet(config: MockingbirdConfig, options: FleetOptions): Promise<Fleet> {\n const id = randomUUID()\n const startedAt = new Date().toISOString()\n const children = new Map<string, FleetChild>()\n const clocks = new Map<string, Clock>()\n const checkpoints = new Map<\n string,\n { namespace: string; values: Map<string, unknown>; clock: ReturnType<Clock[\"state\"]> }\n >()\n let supervisor: Listening | undefined\n let stopped = false\n let controlling = false\n const close = async () => {\n if (stopped) return\n stopped = true\n await Promise.allSettled([...children.values()].map((child) => child.close()))\n await supervisor?.close()\n await removeOwned(options.readyFile, id)\n await removeOwned(options.connectionsFile, id)\n }\n // Invalidate a previous process's artifacts before attempting startup.\n if (options.readyFile) await rm(options.readyFile, { force: true })\n if (options.connectionsFile) await rm(options.connectionsFile, { force: true })\n\n const clock = (namespace: string) => {\n let value = clocks.get(namespace)\n if (!value) {\n value = createClock()\n clocks.set(namespace, value)\n }\n return value\n }\n const select = (body: Record<string, unknown>): Map<string, FleetChild> => {\n if (body.services === undefined) return children\n if (!Array.isArray(body.services) || body.services.length === 0)\n throw new Error(\"services must be a nonempty list\")\n const selected = new Map<string, FleetChild>()\n for (const name of body.services) {\n if (typeof name !== \"string\" || !children.has(name))\n throw new Error(\"unknown service in selection\")\n selected.set(name, children.get(name) as FleetChild)\n }\n return selected\n }\n const diagnostics = (namespace: string) =>\n Object.fromEntries([...children].map(([name, child]) => [name, child.diagnostics(namespace)]))\n const transaction = async (\n namespace: string,\n selected: Map<string, FleetChild>,\n run: (name: string, child: FleetChild) => Promise<unknown>,\n ): Promise<Response> => {\n if (controlling) return json(409, { error: \"another fleet operation is in progress\" })\n controlling = true\n const release: (() => void)[] = []\n const before = new Map<string, unknown>()\n const results: Record<string, unknown> = {}\n let failure: string | undefined\n try {\n for (const [name, child] of selected) {\n failure = name\n release.push(child.lock(namespace))\n }\n const busy = Object.fromEntries(\n [...selected]\n .filter(([, child]) => {\n const state = child.diagnostics(namespace)\n return (\n state.activeRequests +\n state.blockedCommands +\n state.pendingWebhooks +\n (state.activeJobs ?? 0) >\n 0\n )\n })\n .map(([name, child]) => [name, child.diagnostics(namespace)]),\n )\n if (Object.keys(busy).length)\n return json(409, { error: \"namespace is not quiescent\", services: busy })\n for (const [name, child] of selected) {\n failure = name\n before.set(name, await child.checkpoint(namespace))\n }\n for (const [name, child] of selected) {\n failure = name\n results[name] = { status: \"ok\", result: await run(name, child) }\n }\n return json(200, { status: \"ok\", namespace, services: results })\n } catch {\n const rollback: Record<string, string> = {}\n // Roll back even the child whose mutation failed; it may have partially changed state.\n for (const [name, point] of before) {\n try {\n await selected.get(name)?.restore(namespace, point)\n rollback[name] = \"restored\"\n } catch {\n rollback[name] = \"failed\"\n }\n }\n return json(500, {\n status: \"failed\",\n namespace,\n failedService: failure,\n services: results,\n rollback,\n rolledBack:\n before.size > 0 && Object.values(rollback).every((value) => value === \"restored\"),\n })\n } finally {\n for (const unlock of release.reverse()) unlock()\n controlling = false\n }\n }\n\n const api: FetchAPI = {\n async fetch(request) {\n const url = new URL(request.url)\n const adminPrefix = resolveAdminPrefix(config.adminPrefix)\n const path = url.pathname.startsWith(`${adminPrefix}/`)\n ? url.pathname.slice(adminPrefix.length)\n : \"\"\n if (path === \"/health\" && request.method === \"GET\") {\n const states = await Promise.all(\n [...children].map(async ([name, child]) => {\n let protocolReady = false\n try {\n protocolReady = await child.ready()\n } catch {\n /* reported as failed */\n }\n return [\n name,\n {\n processReady: !stopped,\n protocolReady,\n status: protocolReady ? \"ready\" : \"failed\",\n url: publicUrl(child.url),\n },\n ]\n }),\n )\n const ready =\n !stopped &&\n states.every(([, state]) => (state as { protocolReady: boolean }).protocolReady)\n return json(ready ? 200 : 503, {\n status: ready ? \"ready\" : \"failed\",\n id,\n services: Object.fromEntries(states),\n })\n }\n if (!path.startsWith(\"/fleet/\")) return json(404, { error: \"not found\" })\n const adminKey = config.adminKey ?? process.env.MOCKINGBIRD_ADMIN_KEY\n if (adminKey !== undefined && request.headers.get(\"x-mockingbird-admin-key\") !== adminKey)\n return json(401, { error: \"admin key required\" })\n const route = /^\\/fleet\\/namespaces\\/([^/]+)\\/(reset|snapshots)(?:\\/([^/]+)\\/restore)?$/.exec(\n path,\n )\n const namespace = route\n ? decodeURIComponent(route[1] as string)\n : (url.searchParams.get(\"namespace\") ??\n request.headers.get(\"x-mockingbird-namespace\") ??\n config.namespace ??\n \"default\")\n if (!NS.test(namespace)) return json(400, { error: \"invalid namespace\" })\n if (request.method === \"GET\" && path === \"/fleet/metrics\")\n return json(200, { namespace, services: diagnostics(namespace) })\n if (request.method === \"GET\" && path === \"/fleet/clock\")\n return json(200, {\n namespace,\n ...clock(namespace).state(),\n services: Object.fromEntries(\n [...children].map(([name, child]) => [name, child.clock(namespace).state()]),\n ),\n })\n if (request.method !== \"POST\") return json(405, { error: \"method not allowed\" })\n let body: Record<string, unknown>\n try {\n const text = await request.text()\n const value: unknown = text ? JSON.parse(text) : {}\n if (!isObject(value)) throw new Error(\"expected object\")\n body = value\n } catch {\n return json(400, { error: \"expected JSON object\" })\n }\n let selected: Map<string, FleetChild>\n try {\n selected = select(body)\n } catch (error) {\n return json(400, { error: error instanceof Error ? error.message : \"bad selection\" })\n }\n if (path === \"/fleet/wait-until-idle\") {\n const services = diagnostics(namespace)\n const idle = Object.values(services).every((d) => pending(d) === 0)\n return json(idle ? 200 : 409, { status: idle ? \"idle\" : \"busy\", namespace, services })\n }\n if (path === \"/fleet/clock\") {\n const current = clock(namespace)\n let target = current.now()\n if (body.set !== undefined) {\n target =\n typeof body.set === \"number\"\n ? body.set\n : typeof body.set === \"string\"\n ? Date.parse(body.set)\n : NaN\n if (!Number.isFinite(target))\n return json(400, { error: \"set must be epoch ms or ISO-8601\" })\n }\n if (body.advance !== undefined) {\n const delta = parseDuration(body.advance)\n if (delta === undefined) return json(400, { error: \"invalid advance\" })\n target += delta\n }\n const frozen = body.freeze === undefined ? current.state().frozen : body.freeze\n if (typeof frozen !== \"boolean\") return json(400, { error: \"freeze must be boolean\" })\n const response = await transaction(namespace, selected, async (_name, child) => {\n const childClock = child.clock(namespace)\n childClock.freeze()\n childClock.set(target)\n if (!frozen) childClock.unfreeze()\n await child.settle?.(namespace)\n return childClock.state()\n })\n if (response.ok) {\n current.freeze()\n current.set(target)\n if (!frozen) current.unfreeze()\n }\n return response\n }\n if (!route) return json(404, { error: \"not found\" })\n if (route[2] === \"reset\") {\n if (route[3]) return json(404, { error: \"not found\" })\n const response = await transaction(namespace, selected, async (_name, child) =>\n child.reset(namespace),\n )\n if (response.ok && selected.size === children.size) clock(namespace).reset()\n return response\n }\n if (route[3]) {\n const point = checkpoints.get(route[3])\n if (!point || point.namespace !== namespace)\n return json(404, { error: \"no snapshot in this namespace\" })\n const restored = new Map(\n [...point.values].map(([name]) => [name, children.get(name) as FleetChild]),\n )\n const response = await transaction(namespace, restored, async (name, child) =>\n child.restore(namespace, point.values.get(name)),\n )\n if (response.ok) {\n const current = clock(namespace)\n current.freeze()\n current.set(point.clock.now)\n if (!point.clock.frozen) current.unfreeze()\n }\n return response\n }\n const snapshotId = randomUUID()\n const values = new Map<string, unknown>()\n const response = await transaction(namespace, selected, async (name, child) => {\n values.set(name, await child.checkpoint(namespace))\n return { checkpoint: `${snapshotId}:${name}` }\n })\n if (!response.ok) return response\n checkpoints.set(snapshotId, { namespace, values, clock: clock(namespace).state() })\n return json(201, {\n ...((await response.json()) as Record<string, unknown>),\n id: snapshotId,\n label: body.label,\n })\n },\n }\n try {\n const adminPrefix = resolveAdminPrefix(config.adminPrefix)\n if (!isObject(config.services) || Object.keys(config.services).length === 0)\n throw new Error(\"config must contain at least one service\")\n for (const [name, entry] of Object.entries(config.services)) {\n if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name)) throw new Error(\"invalid service name\")\n try {\n const target = await options.load(name)\n if (entry.protocol && entry.protocol !== (\"protocol\" in target ? target.protocol : \"http\"))\n throw new Error(\"configured protocol does not match target\")\n const adminKey = entry.adminKey ?? config.adminKey ?? process.env.MOCKINGBIRD_ADMIN_KEY\n const child =\n \"start\" in target\n ? await target.start(entry)\n : await httpChild(\n target,\n {\n ...entry,\n adminPrefix: resolveAdminPrefix(entry.adminPrefix ?? adminPrefix),\n ...(adminKey !== undefined ? { adminKey } : {}),\n },\n options,\n )\n children.set(name, child)\n if (!(await child.ready())) throw new Error(\"protocol readiness failed\")\n } catch {\n throw new Error(`service ${name} failed to start; all started listeners were closed`)\n }\n }\n supervisor = await listen(api, {\n port: config.control?.port ?? 0,\n host: config.control?.host ?? \"127.0.0.1\",\n })\n const manifest: EndpointManifest = {\n version: 1,\n state: \"ready\",\n pid: process.pid,\n id,\n startedAt,\n adminBase: `${supervisor.url}${adminPrefix}/fleet`,\n healthUrl: `${supervisor.url}${adminPrefix}/health`,\n services: Object.fromEntries(\n [...children].map(([name, child]) => [\n name,\n {\n protocol: child.protocol,\n url: publicUrl(child.url),\n healthUrl: child.healthUrl ?? `${supervisor?.url}${adminPrefix}/health`,\n adminUrl: child.adminUrl ?? `${supervisor?.url}${adminPrefix}/fleet`,\n namespaces: child.namespaces,\n processReady: true,\n protocolReady: true,\n },\n ]),\n ),\n }\n if (options.connectionsFile)\n await atomicWrite(options.connectionsFile, {\n version: 1,\n id,\n pid: process.pid,\n services: Object.fromEntries(\n [...children].map(([name, child]) => [\n name,\n { url: child.connection ?? child.url, namespaces: child.connections },\n ]),\n ),\n })\n if (options.readyFile) await atomicWrite(options.readyFile, manifest)\n options.onReady?.(manifest)\n return { manifest, children, fetch: api.fetch, close }\n } catch (error) {\n await close()\n throw error\n }\n}\n", "import { createServer } from \"node:http\"\nimport type { FetchAPI } from \"@crvouga/mockingbird-core\"\n\n/** Options for {@link serve}. */\nexport type NodeServeOptions = {\n port?: number\n host?: string\n}\n\n/**\n * Serve any Mockingbird {@link FetchAPI} over `node:http`.\n * Port defaults to `0`, so the OS assigns an ephemeral port (read from `server.address()`).\n */\nexport const serve = async (api: FetchAPI, options: NodeServeOptions = {}) => {\n const server = createServer(async (req, res) => {\n const chunks: Buffer[] = []\n for await (const chunk of req) {\n chunks.push(Buffer.from(chunk))\n }\n const body = Buffer.concat(chunks)\n const address = server.address()\n const port = typeof address === \"object\" && address !== null ? address.port : undefined\n const base = `http://${req.headers.host ?? `localhost:${port ?? 80}`}`\n const raw = req.url ?? \"/\"\n const url = new URL(raw.replace(/^\\/+/, \"/\"), base)\n const method = req.method ?? \"GET\"\n const init: RequestInit = { method, headers: req.headers as Record<string, string> }\n if (method !== \"GET\" && method !== \"HEAD\" && body.length > 0) {\n init.body = body\n }\n const aborted = new AbortController()\n res.once(\"close\", () => {\n if (!res.writableFinished) aborted.abort()\n })\n init.signal = aborted.signal\n const request = new Request(url, init)\n let response: Response\n try {\n response = await api.fetch(request)\n } catch (error) {\n // A `drop` fault: destroy the socket so the client sees the connection die.\n if ((error as { code?: string }).code === \"MOCKINGBIRD_DROP\") {\n req.socket.destroy()\n return\n }\n res.writeHead(500, { \"content-type\": \"application/json\" })\n res.end(\n JSON.stringify({\n error: {\n type: \"mockingbird_internal\",\n message: error instanceof Error ? error.message : String(error),\n },\n }),\n )\n return\n }\n // Headers#entries() joins repeated headers; Set-Cookie must stay one header per cookie.\n const headers: Record<string, string | string[]> = Object.fromEntries(response.headers)\n const cookies = response.headers.getSetCookie()\n if (cookies.length > 0) headers[\"set-cookie\"] = cookies\n if (!response.body) {\n res.writeHead(response.status, headers)\n res.end()\n return\n }\n // Stream the body chunk by chunk: event streams and long-polls must not be buffered.\n res.writeHead(response.status, headers)\n res.flushHeaders()\n const reader = response.body.getReader()\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (done) break\n if (!res.write(value)) await new Promise<void>((resolve) => res.once(\"drain\", resolve))\n }\n res.end()\n } catch {\n res.destroy()\n } finally {\n reader.releaseLock()\n }\n })\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject)\n server.listen(options.port ?? 0, options.host, resolve)\n })\n return server\n}\n", "import type { Server } from \"node:http\"\nimport type { FetchAPI } from \"@crvouga/mockingbird-core\"\nimport { serve } from \"./serve.js\"\n\nexport type ListenOptions = {\n /** Default `0`: the OS picks a free port. */\n port?: number\n /** Default `127.0.0.1`: a mock should not be reachable off the machine by accident. */\n host?: string\n}\n\n/** A running server, with the address it actually bound. */\nexport type Listening = {\n url: string\n port: number\n host: string\n server: Server\n close(): Promise<void>\n}\n\nexport const listen = async (api: FetchAPI, options: ListenOptions = {}): Promise<Listening> => {\n const host = options.host ?? \"127.0.0.1\"\n const server = await serve(api, { port: options.port ?? 0, host })\n const address = server.address()\n const port = typeof address === \"object\" && address !== null ? address.port : (options.port ?? 0)\n const shown = host.includes(\":\") ? `[${host}]` : host\n return {\n url: `http://${shown}:${port}`,\n port,\n host,\n server,\n close: () =>\n new Promise<void>((resolve, reject) => {\n // Stop accepting first, then drop keep-alive sockets so close() can finish.\n server.close((error) => {\n if (error && (error as { code?: string }).code !== \"ERR_SERVER_NOT_RUNNING\") reject(error)\n else resolve()\n })\n server.closeAllConnections?.()\n }),\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["readFile", "readFile", "resolve", "resolve", "response", "resolve", "readFile", "adminKey", "createServer", "readFile"]
7
+ }