backend-manager 5.11.1 → 5.11.2

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/CLAUDE.md CHANGED
@@ -183,7 +183,7 @@ Deep references live in `docs/`. **Whenever you make a behavioral change, update
183
183
 
184
184
  ### Testing & CLI
185
185
 
186
- - [docs/test-framework.md](docs/test-framework.md) — running, filtering, log files, test types (standalone/suite/group), context object, assertions, auth levels. **NEVER mock — test against the real emulator.** No `mockManager`/`mockAdmin`/fake `firestore`/stubbed `assistant`; every `run()` gets the real `Manager`/`assistant`/`firestore`/`http`/`accounts` — use them. Pure functions (zero I/O) are the only thing you call directly; anything touching Firestore or an external API runs for real. Real external APIs (OpenAI/PayPal/GitHub/SendGrid/Stripe) are gated behind `TEST_EXTENDED_MODE` in-source (not mocked) — opt in with `--extended` or `TEST_EXTENDED_MODE=true` (shared, unprefixed across BEM/BXM/UJM/EM; propagates to BOTH runner + emulator) — and anything an extended test creates externally must be cleaned up by the test. **Each test file `module.exports` a `{ description, type, tests }` object — NOT raw Mocha (`describe`/`it`/`beforeEach`); those globals are not injected and the file fails to load. Split tests one-file-per-concern under `test/<area>/`, never one giant `test/test.js`.** **All cleanup runs at the START of every run, never at the end** — the runner flushes the ENTIRE emulator Firestore before every run, so there's nothing to register; seed any needed fixtures in `test/_init.js`'s `setup()`, and never add a trailing cleanup step. Marketing providers (SendGrid/Beehiiv) don't need a special exception — `_test.*` emails are blocked at the validation layer so test signups never reach providers. The `_test.allow_*` carve-out exists only for the live-provider lifecycle test (`test/marketing/consent-lifecycle.js`), which manages its own teardown.
186
+ - [docs/test-framework.md](docs/test-framework.md) — running, filtering, log files, test types (standalone/suite/group), context object, assertions, auth levels. **NEVER mock — test against the real emulator.** No `mockManager`/`mockAdmin`/fake `firestore`/stubbed `assistant`; every `run()` gets the real `Manager`/`assistant`/`firestore`/`http`/`accounts` — use them. Pure functions (zero I/O) are the only thing you call directly; anything touching Firestore or an external API runs for real. Real external APIs (OpenAI/PayPal/GitHub/SendGrid/Stripe) are gated behind `TEST_EXTENDED_MODE` in-source (not mocked) — opt in with `--extended` or `TEST_EXTENDED_MODE=true` (shared, unprefixed across BEM/BXM/UJM/EM; propagates to BOTH runner + emulator) — and anything an extended test creates externally must be cleaned up by the test. **Each test file `module.exports` a `{ description, type, tests }` object — NOT raw Mocha (`describe`/`it`/`beforeEach`); those globals are not injected and the file fails to load. The only lifecycle hook is `cleanup` — exported `before`/`after` properties are silently IGNORED (do setup inside the tests via an idempotent helper, or in `test/_init.js`). Split tests one-file-per-concern under `test/<area>/`, never one giant `test/test.js`.** **All cleanup runs at the START of every run, never at the end** — the runner flushes the ENTIRE emulator Firestore before every run, so there's nothing to register; seed any needed fixtures in `test/_init.js`'s `setup()`, and never add a trailing cleanup step. Marketing providers (SendGrid/Beehiiv) don't need a special exception — `_test.*` emails are blocked at the validation layer so test signups never reach providers. The `_test.allow_*` carve-out exists only for the live-provider lifecycle test (`test/marketing/consent-lifecycle.js`), which manages its own teardown.
187
187
  - [docs/test-boot-layer.md](docs/test-boot-layer.md) — the `boot/` smoke layer: framework self-test from the repo via the bundled fixture project + `BEM_TEST_BOOT_PROJECT` (BEM's analog of BXM/UJM `*_TEST_BOOT_PROJECT`)
188
188
  - [docs/cli-firestore-auth.md](docs/cli-firestore-auth.md) — `npx mgr firestore:*` and `auth:*` commands, shared flags, examples
189
189
  - [docs/cli-logs.md](docs/cli-logs.md) — `npx mgr logs:read` / `logs:tail` with full flag reference and built-in Cloud Function names
@@ -236,6 +236,8 @@ Use `bem:` or `project:` prefix to filter by source. **Mirror the source path so
236
236
  ## Test Types
237
237
 
238
238
  > **The runner reads each file's `module.exports` object — it does NOT inject Mocha/Jest globals.** A test file that calls `describe`/`it`/`before`/`beforeEach`/`after` at top level throws `ReferenceError: beforeEach is not defined` and shows as `Failed to load`. There is no global `assert` either — use the `assert` passed into `run({ assert })`. Every test file MUST export one of the shapes below.
239
+ >
240
+ > **The only lifecycle hook is `cleanup`** (per-test and module-level). Exporting `before`/`after`/`beforeEach` properties on the module does NOT error — the runner silently ignores them, so setup they were supposed to do never happens (this bit `helpers/ai-schema-resolve`, which failed for weeks because its fixtures were written in a `before()` that never ran). Seed disk/DB fixtures inside the tests themselves via an idempotent helper, or in `test/_init.js`'s `setup()`.
239
241
 
240
242
  | Type | Use When | Behavior |
241
243
  |------|----------|----------|
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backend-manager",
3
- "version": "5.11.1",
3
+ "version": "5.11.2",
4
4
  "description": "Quick tools for developing Firebase functions",
5
5
  "main": "src/manager/index.js",
6
6
  "files": [
@@ -2,5 +2,5 @@
2
2
  "env": {
3
3
  "TEST_EXTENDED_MODE": ""
4
4
  },
5
- "updatedAt": "2026-07-02T07:46:48.765Z"
5
+ "updatedAt": "2026-07-02T07:57:05.070Z"
6
6
  }
@@ -2,11 +2,11 @@ WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
2
2
  WARNING: sun.misc.Unsafe::objectFieldOffset has been called by akka.util.Unsafe (file:/Users/ian/.cache/firebase/emulators/firebase-database-emulator-v4.11.2.jar)
3
3
  WARNING: Please consider reporting this to the maintainers of class akka.util.Unsafe
4
4
  WARNING: sun.misc.Unsafe::objectFieldOffset will be removed in a future release
5
- 00:46:55.447 [NamespaceSystem-akka.actor.default-dispatcher-5] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
6
- 00:46:55.566 [main] INFO com.firebase.server.forge.App$ - Listening at 127.0.0.1:9000
7
- 00:47:05.782 [NamespaceSystem-akka.actor.default-dispatcher-5] INFO com.firebase.core.namespace.NamespaceActor - demo-backend-manager-default-rtdb successfully activated FBKV (SurveyIdle(0)) wait: 82ms, init: 0ms
8
- 00:47:05.814 [NamespaceSystem-blocking-namespace-operation-dispatcher-7] INFO com.firebase.core.namespace.StateManager - Namespace demo-backend-manager-default-rtdb status Active to Active
9
- 00:47:19.548 [Thread-0] INFO com.firebase.server.forge.App$ - Attempting graceful shutdown.
10
- 00:47:19.556 [NamespaceSystem-akka.actor.default-dispatcher-5] INFO com.firebase.core.namespace.Terminator$Terminator - 1 actors left to terminate: demo-backend-manager-default-rtdb
11
- 00:47:19.561 [NamespaceSystem-akka.actor.default-dispatcher-6] INFO com.firebase.core.namespace.NamespaceActor - stopped namespace actor for demo-backend-manager-default-rtdb
12
- 00:47:19.565 [Thread-0] INFO com.firebase.server.forge.App$ - Graceful shutdown complete.
5
+ 00:57:11.886 [NamespaceSystem-akka.actor.default-dispatcher-4] INFO akka.event.slf4j.Slf4jLogger - Slf4jLogger started
6
+ 00:57:11.979 [main] INFO com.firebase.server.forge.App$ - Listening at 127.0.0.1:9000
7
+ 00:57:21.840 [NamespaceSystem-akka.actor.default-dispatcher-4] INFO com.firebase.core.namespace.NamespaceActor - demo-backend-manager-default-rtdb successfully activated FBKV (SurveyIdle(0)) wait: 71ms, init: 0ms
8
+ 00:57:21.874 [NamespaceSystem-blocking-namespace-operation-dispatcher-6] INFO com.firebase.core.namespace.StateManager - Namespace demo-backend-manager-default-rtdb status Active to Active
9
+ 00:57:32.880 [Thread-0] INFO com.firebase.server.forge.App$ - Attempting graceful shutdown.
10
+ 00:57:32.901 [NamespaceSystem-akka.actor.default-dispatcher-4] INFO com.firebase.core.namespace.Terminator$Terminator - 1 actors left to terminate: demo-backend-manager-default-rtdb
11
+ 00:57:32.922 [NamespaceSystem-akka.actor.default-dispatcher-4] INFO com.firebase.core.namespace.NamespaceActor - stopped namespace actor for demo-backend-manager-default-rtdb
12
+ 00:57:32.926 [Thread-0] INFO com.firebase.server.forge.App$ - Graceful shutdown complete.
@@ -2,7 +2,7 @@ WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
2
2
  WARNING: sun.misc.Unsafe::allocateMemory has been called by io.netty.util.internal.PlatformDependent0$2 (file:/Users/ian/.cache/firebase/emulators/cloud-firestore-emulator-v1.21.0.jar)
3
3
  WARNING: Please consider reporting this to the maintainers of class io.netty.util.internal.PlatformDependent0$2
4
4
  WARNING: sun.misc.Unsafe::allocateMemory will be removed in a future release
5
- Jul 02, 2026 12:46:54 AM com.google.cloud.datastore.emulator.firestore.websocket.WebSocketServer start
5
+ Jul 02, 2026 12:57:10 AM com.google.cloud.datastore.emulator.firestore.websocket.WebSocketServer start
6
6
  INFO: Started WebSocket server on ws://127.0.0.1:9150
7
7
 
8
8
  API endpoint: http://127.0.0.1:8080
@@ -20,105 +20,115 @@ If you are running a Firestore in Datastore Mode project, run:
20
20
  Note: Support for Datastore Mode is in preview. If you encounter any bugs please file at https://github.com/firebase/firebase-tools/issues.
21
21
  Dev App Server is now running.
22
22
 
23
- Jul 02, 2026 12:47:05 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
23
+ Jul 02, 2026 12:57:21 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
24
24
  INFO: Detected non-HTTP/2 connection.
25
- Jul 02, 2026 12:47:05 AM io.grpc.netty.TcpMetrics loadEpollInfo
25
+ Jul 02, 2026 12:57:21 AM io.grpc.netty.TcpMetrics loadEpollInfo
26
26
  INFO: Epoll available during static init of TcpMetrics:false
27
- Jul 02, 2026 12:47:05 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
27
+ Jul 02, 2026 12:57:21 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
28
28
  INFO: Detected HTTP/2 connection.
29
- Jul 02, 2026 12:47:06 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
29
+ Jul 02, 2026 12:57:22 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
30
30
  INFO: Detected HTTP/2 connection.
31
- Jul 02, 2026 12:47:07 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
31
+ Jul 02, 2026 12:57:23 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
32
32
  INFO: Detected HTTP/2 connection.
33
- Jul 02, 2026 12:47:16 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
33
+ Jul 02, 2026 12:57:30 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
34
34
  INFO: Detected HTTP/2 connection.
35
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
35
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
36
36
  INFO: Detected HTTP/2 connection.
37
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
37
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
38
38
  INFO: Detected HTTP/2 connection.
39
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
39
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
40
40
  INFO: Detected HTTP/2 connection.
41
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
41
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
42
42
  INFO: Detected HTTP/2 connection.
43
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
43
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
44
44
  INFO: Detected HTTP/2 connection.
45
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
45
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
46
46
  INFO: Detected HTTP/2 connection.
47
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
47
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
48
48
  INFO: Detected HTTP/2 connection.
49
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
49
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
50
50
  INFO: Detected HTTP/2 connection.
51
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
51
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
52
52
  INFO: Detected HTTP/2 connection.
53
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
53
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
54
54
  INFO: Detected HTTP/2 connection.
55
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
55
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
56
56
  INFO: Detected HTTP/2 connection.
57
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
57
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
58
58
  INFO: Detected HTTP/2 connection.
59
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
59
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
60
60
  INFO: Detected HTTP/2 connection.
61
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
61
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
62
62
  INFO: Detected HTTP/2 connection.
63
- Jul 02, 2026 12:47:17 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
63
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
64
64
  INFO: Detected HTTP/2 connection.
65
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
65
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
66
66
  INFO: Detected HTTP/2 connection.
67
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
67
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
68
68
  INFO: Detected HTTP/2 connection.
69
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
69
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
70
70
  INFO: Detected HTTP/2 connection.
71
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
71
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
72
72
  INFO: Detected HTTP/2 connection.
73
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
73
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
74
74
  INFO: Detected HTTP/2 connection.
75
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
75
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
76
76
  INFO: Detected HTTP/2 connection.
77
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
77
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
78
78
  INFO: Detected HTTP/2 connection.
79
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
79
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
80
80
  INFO: Detected HTTP/2 connection.
81
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
81
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
82
82
  INFO: Detected HTTP/2 connection.
83
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
83
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
84
84
  INFO: Detected HTTP/2 connection.
85
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
85
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
86
86
  INFO: Detected HTTP/2 connection.
87
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
87
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
88
88
  INFO: Detected HTTP/2 connection.
89
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
89
+ Jul 02, 2026 12:57:31 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
90
90
  INFO: Detected HTTP/2 connection.
91
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
91
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
92
92
  INFO: Detected HTTP/2 connection.
93
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
93
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
94
94
  INFO: Detected HTTP/2 connection.
95
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
95
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
96
96
  INFO: Detected HTTP/2 connection.
97
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
97
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
98
98
  INFO: Detected HTTP/2 connection.
99
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
99
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
100
100
  INFO: Detected HTTP/2 connection.
101
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
101
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
102
102
  INFO: Detected HTTP/2 connection.
103
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
103
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
104
104
  INFO: Detected HTTP/2 connection.
105
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
105
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
106
106
  INFO: Detected HTTP/2 connection.
107
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
107
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
108
108
  INFO: Detected HTTP/2 connection.
109
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
109
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
110
110
  INFO: Detected HTTP/2 connection.
111
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
111
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
112
112
  INFO: Detected HTTP/2 connection.
113
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
113
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
114
114
  INFO: Detected HTTP/2 connection.
115
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
115
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
116
116
  INFO: Detected HTTP/2 connection.
117
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
117
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
118
118
  INFO: Detected HTTP/2 connection.
119
- Jul 02, 2026 12:47:18 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
119
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
120
120
  INFO: Detected HTTP/2 connection.
121
- Jul 02, 2026 12:47:19 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
121
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
122
+ INFO: Detected HTTP/2 connection.
123
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
124
+ INFO: Detected HTTP/2 connection.
125
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
126
+ INFO: Detected HTTP/2 connection.
127
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
128
+ INFO: Detected HTTP/2 connection.
129
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
130
+ INFO: Detected HTTP/2 connection.
131
+ Jul 02, 2026 12:57:32 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
122
132
  INFO: Detected HTTP/2 connection.
123
133
  *** shutting down gRPC server since JVM is shutting down
124
134
  *** server shut down
@@ -1,6 +1,6 @@
1
1
  This is the Google Pub/Sub fake.
2
2
  Implementation may be incomplete or differ from the real system.
3
- Jul 02, 2026 12:46:58 AM com.google.cloud.pubsub.testing.v1.Main main
3
+ Jul 02, 2026 12:57:15 AM com.google.cloud.pubsub.testing.v1.Main main
4
4
  INFO: IAM integration is disabled. IAM policy methods and ACL checks are not supported
5
5
  SLF4J(W): No SLF4J providers were found.
6
6
  SLF4J(W): Defaulting to no-operation (NOP) logger implementation
@@ -9,9 +9,9 @@ WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
9
9
  WARNING: sun.misc.Unsafe::allocateMemory has been called by io.netty.util.internal.PlatformDependent0$2 (file:/Users/ian/.cache/firebase/emulators/pubsub-emulator-0.8.33/pubsub-emulator/lib/cloud-pubsub-emulator-0.8.33-all.jar)
10
10
  WARNING: Please consider reporting this to the maintainers of class io.netty.util.internal.PlatformDependent0$2
11
11
  WARNING: sun.misc.Unsafe::allocateMemory will be removed in a future release
12
- Jul 02, 2026 12:46:59 AM com.google.cloud.pubsub.testing.v1.Main main
12
+ Jul 02, 2026 12:57:15 AM com.google.cloud.pubsub.testing.v1.Main main
13
13
  INFO: Server started, listening on 8085
14
- Jul 02, 2026 12:47:05 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
14
+ Jul 02, 2026 12:57:21 AM io.gapi.emulators.netty.HttpVersionRoutingHandler channelRead
15
15
  INFO: Detected HTTP/2 connection.
16
16
  *** shutting down gRPC server since JVM is shutting down
17
17
  *** server shut down
@@ -12,6 +12,7 @@ function noopLog() {}
12
12
 
13
13
  const FIXTURES_DIR = path.join(__dirname, '..', 'fixtures', 'ai-schema');
14
14
  const VALID_SCHEMA_PATH = path.join(FIXTURES_DIR, 'valid.json');
15
+ const INVALID_SCHEMA_PATH = path.join(FIXTURES_DIR, 'invalid.json');
15
16
  const VALID_SCHEMA = {
16
17
  type: 'object',
17
18
  properties: {
@@ -22,20 +23,17 @@ const VALID_SCHEMA = {
22
23
  additionalProperties: false,
23
24
  };
24
25
 
26
+ // The runner has no before/after hooks (module contract: tests[] + cleanup),
27
+ // so each test that reads from disk seeds the fixtures itself (idempotent).
28
+ function ensureFixtures() {
29
+ jetpack.write(VALID_SCHEMA_PATH, VALID_SCHEMA);
30
+ jetpack.write(INVALID_SCHEMA_PATH, '{ not valid json !!!');
31
+ }
32
+
25
33
  module.exports = {
26
34
  description: 'AI schema resolution (inline vs file path)',
27
35
  type: 'group',
28
36
 
29
- before() {
30
- jetpack.dir(FIXTURES_DIR);
31
- jetpack.write(VALID_SCHEMA_PATH, VALID_SCHEMA);
32
- jetpack.write(path.join(FIXTURES_DIR, 'invalid.json'), '{ not valid json !!!');
33
- },
34
-
35
- after() {
36
- jetpack.remove(FIXTURES_DIR);
37
- },
38
-
39
37
  tests: [
40
38
  {
41
39
  name: 'undefined-returns-undefined',
@@ -70,6 +68,7 @@ module.exports = {
70
68
  {
71
69
  name: 'path-loads-json-file',
72
70
  async run({ assert }) {
71
+ ensureFixtures();
73
72
  const result = resolveSchema({ path: VALID_SCHEMA_PATH }, noopLog);
74
73
  assert.deepEqual(result, VALID_SCHEMA, 'loaded schema matches fixture');
75
74
  },
@@ -92,6 +91,7 @@ module.exports = {
92
91
  {
93
92
  name: 'path-to-directory-throws',
94
93
  async run({ assert }) {
94
+ ensureFixtures();
95
95
  let threw = false;
96
96
  try {
97
97
  resolveSchema({ path: FIXTURES_DIR }, noopLog);
@@ -106,9 +106,10 @@ module.exports = {
106
106
  {
107
107
  name: 'invalid-json-throws',
108
108
  async run({ assert }) {
109
+ ensureFixtures();
109
110
  let threw = false;
110
111
  try {
111
- resolveSchema({ path: path.join(FIXTURES_DIR, 'invalid.json') }, noopLog);
112
+ resolveSchema({ path: INVALID_SCHEMA_PATH }, noopLog);
112
113
  } catch (e) {
113
114
  threw = true;
114
115
  }
@@ -116,4 +117,8 @@ module.exports = {
116
117
  },
117
118
  },
118
119
  ],
120
+
121
+ async cleanup() {
122
+ jetpack.remove(FIXTURES_DIR);
123
+ },
119
124
  };