@quenty/nevermore-cli 4.42.0 → 4.42.1-canary.783.30683606415.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.
Files changed (172) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/args/global-args.d.ts +13 -0
  3. package/dist/args/global-args.d.ts.map +1 -1
  4. package/dist/commands/batch-command/batch-deploy-command.d.ts +3 -0
  5. package/dist/commands/batch-command/batch-deploy-command.d.ts.map +1 -1
  6. package/dist/commands/batch-command/batch-deploy-command.js +90 -1
  7. package/dist/commands/batch-command/batch-deploy-command.js.map +1 -1
  8. package/dist/commands/batch-command/batch-test-command.d.ts.map +1 -1
  9. package/dist/commands/batch-command/batch-test-command.js +7 -2
  10. package/dist/commands/batch-command/batch-test-command.js.map +1 -1
  11. package/dist/commands/deploy-command/deploy-init.js +1 -1
  12. package/dist/commands/deploy-command/deploy-init.js.map +1 -1
  13. package/dist/commands/deploy-command/index.d.ts +3 -0
  14. package/dist/commands/deploy-command/index.d.ts.map +1 -1
  15. package/dist/commands/deploy-command/index.js +301 -60
  16. package/dist/commands/deploy-command/index.js.map +1 -1
  17. package/dist/commands/deploy-command/select-target.js +1 -1
  18. package/dist/commands/deploy-command/select-target.js.map +1 -1
  19. package/dist/commands/deploy-command/version-command.d.ts.map +1 -1
  20. package/dist/commands/deploy-command/version-command.js +138 -12
  21. package/dist/commands/deploy-command/version-command.js.map +1 -1
  22. package/dist/commands/test-command/test-command.d.ts.map +1 -1
  23. package/dist/commands/test-command/test-command.js +17 -7
  24. package/dist/commands/test-command/test-command.js.map +1 -1
  25. package/dist/nevermore.js +17 -0
  26. package/dist/nevermore.js.map +1 -1
  27. package/dist/utils/batch/changed-packages-utils.d.ts +1 -1
  28. package/dist/utils/batch/changed-packages-utils.d.ts.map +1 -1
  29. package/dist/utils/batch/changed-packages-utils.js +1 -1
  30. package/dist/utils/batch/changed-packages-utils.js.map +1 -1
  31. package/dist/utils/build/base-place-resolver-factory.d.ts +25 -0
  32. package/dist/utils/build/base-place-resolver-factory.d.ts.map +1 -0
  33. package/dist/utils/build/base-place-resolver-factory.js +40 -0
  34. package/dist/utils/build/base-place-resolver-factory.js.map +1 -0
  35. package/dist/utils/build/build.d.ts +13 -2
  36. package/dist/utils/build/build.d.ts.map +1 -1
  37. package/dist/utils/build/build.js.map +1 -1
  38. package/dist/utils/build/upload.d.ts +1 -1
  39. package/dist/utils/build/upload.d.ts.map +1 -1
  40. package/dist/utils/deploy/deploy-metadata.d.ts +1 -1
  41. package/dist/utils/deploy/deploy-metadata.d.ts.map +1 -1
  42. package/dist/utils/job-context/base-job-context.d.ts +3 -1
  43. package/dist/utils/job-context/base-job-context.d.ts.map +1 -1
  44. package/dist/utils/job-context/base-job-context.js +45 -6
  45. package/dist/utils/job-context/base-job-context.js.map +1 -1
  46. package/dist/utils/job-context/batch-script-job-context.d.ts +6 -0
  47. package/dist/utils/job-context/batch-script-job-context.d.ts.map +1 -1
  48. package/dist/utils/job-context/batch-script-job-context.js +13 -0
  49. package/dist/utils/job-context/batch-script-job-context.js.map +1 -1
  50. package/dist/utils/job-context/cloud-job-context.d.ts +2 -1
  51. package/dist/utils/job-context/cloud-job-context.d.ts.map +1 -1
  52. package/dist/utils/job-context/cloud-job-context.js +2 -2
  53. package/dist/utils/job-context/cloud-job-context.js.map +1 -1
  54. package/dist/utils/job-context/local-job-context.d.ts +2 -1
  55. package/dist/utils/job-context/local-job-context.d.ts.map +1 -1
  56. package/dist/utils/job-context/local-job-context.js +2 -2
  57. package/dist/utils/job-context/local-job-context.js.map +1 -1
  58. package/dist/utils/open-cloud/open-cloud-client.d.ts +20 -2
  59. package/dist/utils/open-cloud/open-cloud-client.d.ts.map +1 -1
  60. package/dist/utils/open-cloud/open-cloud-client.js +74 -20
  61. package/dist/utils/open-cloud/open-cloud-client.js.map +1 -1
  62. package/dist/utils/open-cloud/open-cloud-client.test.js +89 -12
  63. package/dist/utils/open-cloud/open-cloud-client.test.js.map +1 -1
  64. package/dist/utils/testing/runner/combined-project-generator.d.ts +1 -1
  65. package/dist/utils/testing/runner/combined-project-generator.d.ts.map +1 -1
  66. package/dist/utils/testing/runner/test-runner.d.ts +1 -1
  67. package/dist/utils/testing/runner/test-runner.d.ts.map +1 -1
  68. package/dist/utils/watch/github-context.d.ts +50 -0
  69. package/dist/utils/watch/github-context.d.ts.map +1 -0
  70. package/dist/utils/watch/github-context.js +125 -0
  71. package/dist/utils/watch/github-context.js.map +1 -0
  72. package/dist/utils/watch/github-context.test.d.ts +2 -0
  73. package/dist/utils/watch/github-context.test.d.ts.map +1 -0
  74. package/dist/utils/watch/github-context.test.js +112 -0
  75. package/dist/utils/watch/github-context.test.js.map +1 -0
  76. package/dist/utils/watch/http-watch-registry.d.ts +40 -0
  77. package/dist/utils/watch/http-watch-registry.d.ts.map +1 -0
  78. package/dist/utils/watch/http-watch-registry.js +262 -0
  79. package/dist/utils/watch/http-watch-registry.js.map +1 -0
  80. package/dist/utils/watch/http-watch-registry.test.d.ts +2 -0
  81. package/dist/utils/watch/http-watch-registry.test.d.ts.map +1 -0
  82. package/dist/utils/watch/http-watch-registry.test.js +211 -0
  83. package/dist/utils/watch/http-watch-registry.test.js.map +1 -0
  84. package/dist/utils/watch/local-watch-loop.d.ts +50 -0
  85. package/dist/utils/watch/local-watch-loop.d.ts.map +1 -0
  86. package/dist/utils/watch/local-watch-loop.js +103 -0
  87. package/dist/utils/watch/local-watch-loop.js.map +1 -0
  88. package/dist/utils/watch/local-watch-loop.test.d.ts +2 -0
  89. package/dist/utils/watch/local-watch-loop.test.d.ts.map +1 -0
  90. package/dist/utils/watch/local-watch-loop.test.js +170 -0
  91. package/dist/utils/watch/local-watch-loop.test.js.map +1 -0
  92. package/dist/utils/watch/register-notify-watches.d.ts +41 -0
  93. package/dist/utils/watch/register-notify-watches.d.ts.map +1 -0
  94. package/dist/utils/watch/register-notify-watches.js +159 -0
  95. package/dist/utils/watch/register-notify-watches.js.map +1 -0
  96. package/dist/utils/watch/register-notify-watches.test.d.ts +2 -0
  97. package/dist/utils/watch/register-notify-watches.test.d.ts.map +1 -0
  98. package/dist/utils/watch/register-notify-watches.test.js +225 -0
  99. package/dist/utils/watch/register-notify-watches.test.js.map +1 -0
  100. package/dist/utils/watch/register-watches.d.ts +68 -0
  101. package/dist/utils/watch/register-watches.d.ts.map +1 -0
  102. package/dist/utils/watch/register-watches.js +221 -0
  103. package/dist/utils/watch/register-watches.js.map +1 -0
  104. package/dist/utils/watch/register-watches.test.d.ts +2 -0
  105. package/dist/utils/watch/register-watches.test.d.ts.map +1 -0
  106. package/dist/utils/watch/register-watches.test.js +576 -0
  107. package/dist/utils/watch/register-watches.test.js.map +1 -0
  108. package/dist/utils/watch/stream-watch-loop.d.ts +54 -0
  109. package/dist/utils/watch/stream-watch-loop.d.ts.map +1 -0
  110. package/dist/utils/watch/stream-watch-loop.js +282 -0
  111. package/dist/utils/watch/stream-watch-loop.js.map +1 -0
  112. package/dist/utils/watch/stream-watch-loop.test.d.ts +2 -0
  113. package/dist/utils/watch/stream-watch-loop.test.d.ts.map +1 -0
  114. package/dist/utils/watch/stream-watch-loop.test.js +392 -0
  115. package/dist/utils/watch/stream-watch-loop.test.js.map +1 -0
  116. package/dist/utils/watch/websocket-watch-stream.d.ts +25 -0
  117. package/dist/utils/watch/websocket-watch-stream.d.ts.map +1 -0
  118. package/dist/utils/watch/websocket-watch-stream.js +306 -0
  119. package/dist/utils/watch/websocket-watch-stream.js.map +1 -0
  120. package/dist/utils/watch/websocket-watch-stream.test.d.ts +2 -0
  121. package/dist/utils/watch/websocket-watch-stream.test.d.ts.map +1 -0
  122. package/dist/utils/watch/websocket-watch-stream.test.js +475 -0
  123. package/dist/utils/watch/websocket-watch-stream.test.js.map +1 -0
  124. package/package.json +7 -4
  125. package/src/args/global-args.ts +13 -0
  126. package/src/commands/batch-command/batch-deploy-command.ts +105 -1
  127. package/src/commands/batch-command/batch-test-command.ts +8 -2
  128. package/src/commands/deploy-command/deploy-init.ts +1 -1
  129. package/src/commands/deploy-command/index.ts +331 -32
  130. package/src/commands/deploy-command/select-target.ts +1 -1
  131. package/src/commands/deploy-command/version-command.ts +215 -21
  132. package/src/commands/test-command/test-command.ts +24 -18
  133. package/src/nevermore.ts +19 -0
  134. package/src/utils/batch/changed-packages-utils.ts +1 -1
  135. package/src/utils/build/base-place-resolver-factory.ts +49 -0
  136. package/src/utils/build/build.ts +13 -2
  137. package/src/utils/build/upload.ts +1 -1
  138. package/src/utils/deploy/deploy-metadata.ts +1 -1
  139. package/src/utils/job-context/base-job-context.ts +68 -6
  140. package/src/utils/job-context/batch-script-job-context.ts +18 -0
  141. package/src/utils/job-context/cloud-job-context.ts +7 -2
  142. package/src/utils/job-context/local-job-context.ts +7 -2
  143. package/src/utils/open-cloud/open-cloud-client.test.ts +133 -14
  144. package/src/utils/open-cloud/open-cloud-client.ts +127 -34
  145. package/src/utils/testing/runner/combined-project-generator.ts +1 -1
  146. package/src/utils/testing/runner/test-runner.ts +1 -1
  147. package/src/utils/watch/github-context.test.ts +154 -0
  148. package/src/utils/watch/github-context.ts +184 -0
  149. package/src/utils/watch/http-watch-registry.test.ts +330 -0
  150. package/src/utils/watch/http-watch-registry.ts +341 -0
  151. package/src/utils/watch/local-watch-loop.test.ts +197 -0
  152. package/src/utils/watch/local-watch-loop.ts +190 -0
  153. package/src/utils/watch/register-notify-watches.test.ts +282 -0
  154. package/src/utils/watch/register-notify-watches.ts +226 -0
  155. package/src/utils/watch/register-watches.test.ts +696 -0
  156. package/src/utils/watch/register-watches.ts +369 -0
  157. package/src/utils/watch/stream-watch-loop.test.ts +625 -0
  158. package/src/utils/watch/stream-watch-loop.ts +411 -0
  159. package/src/utils/watch/websocket-watch-stream.test.ts +581 -0
  160. package/src/utils/watch/websocket-watch-stream.ts +403 -0
  161. package/tsconfig.json +19 -6
  162. package/tsconfig.tsbuildinfo +1 -1
  163. package/dist/utils/build/deploy-config.d.ts +0 -71
  164. package/dist/utils/build/deploy-config.d.ts.map +0 -1
  165. package/dist/utils/build/deploy-config.js +0 -164
  166. package/dist/utils/build/deploy-config.js.map +0 -1
  167. package/dist/utils/build/deploy-config.test.d.ts +0 -2
  168. package/dist/utils/build/deploy-config.test.d.ts.map +0 -1
  169. package/dist/utils/build/deploy-config.test.js +0 -126
  170. package/dist/utils/build/deploy-config.test.js.map +0 -1
  171. package/src/utils/build/deploy-config.test.ts +0 -149
  172. package/src/utils/build/deploy-config.ts +0 -259
@@ -0,0 +1,576 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import * as fs from 'fs/promises';
3
+ import * as os from 'os';
4
+ import * as path from 'path';
5
+ import { BasePlaceResolver, parseWatchOption, resolveDeployLockPath, saveDeployLockAsync, } from '@quenty/nevermore-deploy';
6
+ import { registerWatchesAsync, } from './register-watches.js';
7
+ /** No endpoint ships with the CLI, so tests supply their own. */
8
+ const REGISTER_BASE = 'https://watch.example.com/v1/register/';
9
+ const watchOption = () => parseWatchOption(`${REGISTER_BASE}7d`);
10
+ /**
11
+ * This path only ever builds dispatching watches, so a recorded action that is
12
+ * anything else is itself the failure — asserted rather than cast past.
13
+ */
14
+ function dispatchAction(request, index = 0) {
15
+ const action = request.watches[index].action;
16
+ expect(action.type).toBe('github-workflow-dispatch');
17
+ return action;
18
+ }
19
+ /** Answers from the lock only; the network source is never the right baseline. */
20
+ function makeResolver() {
21
+ return new BasePlaceResolver({
22
+ source: {
23
+ resolveLatestPlaceVersionAsync: async () => {
24
+ throw new Error('a baseline must come from the lock, not the network');
25
+ },
26
+ },
27
+ });
28
+ }
29
+ let packageDir;
30
+ beforeEach(async () => {
31
+ packageDir = await fs.mkdtemp(path.join(os.tmpdir(), 'register-watches-'));
32
+ vi.stubEnv('GITHUB_REPOSITORY', 'Quenty/egg-hunt-2026');
33
+ vi.stubEnv('GITHUB_REF_NAME', 'release');
34
+ vi.stubEnv('NEVERMORE_WATCH_TOKEN', 'token-value');
35
+ });
36
+ afterEach(async () => {
37
+ vi.unstubAllEnvs();
38
+ await fs.rm(packageDir, { recursive: true, force: true });
39
+ });
40
+ function makePlace(overrides = {}) {
41
+ return {
42
+ name: 'hub',
43
+ universeId: 1,
44
+ placeId: 2,
45
+ project: 'default.project.json',
46
+ watch: '.github/workflows/build.yml',
47
+ basePlace: { universeId: 10, placeId: 20, version: 'published' },
48
+ ...overrides,
49
+ };
50
+ }
51
+ function makeCandidate(overrides = {}) {
52
+ return {
53
+ targetName: 'integration',
54
+ packageName: '@quenty/egg-hunt-hub',
55
+ packagePath: packageDir,
56
+ place: makePlace(),
57
+ ...overrides,
58
+ };
59
+ }
60
+ /** Fills in the parts of the port a given test does not care about. */
61
+ function fakeRegistry(partial) {
62
+ return () => ({
63
+ registerAsync: async () => ({}),
64
+ triggerAsync: async () => ({ results: [] }),
65
+ ...partial,
66
+ });
67
+ }
68
+ function makeRecordingRegistry() {
69
+ const requests = [];
70
+ return {
71
+ requests,
72
+ create: fakeRegistry({
73
+ registerAsync: async (request) => {
74
+ requests.push(request);
75
+ return {
76
+ monitorId: 'mon_1',
77
+ leaseExpiresAt: '2026-08-06T00:00:00Z',
78
+ changed: true,
79
+ };
80
+ },
81
+ }),
82
+ };
83
+ }
84
+ async function writeLockAsync(placeId, version) {
85
+ await saveDeployLockAsync(resolveDeployLockPath(packageDir), {
86
+ lockfileVersion: 1,
87
+ basePlaces: { [String(placeId)]: { version, from: 'published' } },
88
+ });
89
+ }
90
+ describe('registerWatchesAsync', () => {
91
+ it('registers one monitor holding every watch', async () => {
92
+ const registry = makeRecordingRegistry();
93
+ await writeLockAsync(20, 158);
94
+ const result = await registerWatchesAsync({
95
+ option: watchOption(),
96
+ monitorName: 'integration',
97
+ resolver: makeResolver(),
98
+ candidates: [
99
+ makeCandidate({ place: makePlace({ name: 'hub' }) }),
100
+ makeCandidate({ place: makePlace({ name: 'lobby' }) }),
101
+ ],
102
+ createRegistry: registry.create,
103
+ });
104
+ expect(result).toEqual({ registered: 2, changed: true });
105
+ expect(registry.requests).toHaveLength(1);
106
+ const request = registry.requests[0];
107
+ expect(request.monitorName).toBe('integration/release');
108
+ expect(request.repository).toBe('Quenty/egg-hunt-2026');
109
+ expect(request.githubToken).toBe('token-value');
110
+ expect(request.watches).toEqual([
111
+ {
112
+ name: 'quenty/egg-hunt-hub/hub',
113
+ source: {
114
+ type: 'roblox-place',
115
+ universeId: 10,
116
+ placeId: 20,
117
+ versionType: 'published',
118
+ },
119
+ action: {
120
+ type: 'github-workflow-dispatch',
121
+ workflow: '.github/workflows/build.yml',
122
+ ref: 'release',
123
+ inputs: { target: 'integration.places.hub' },
124
+ },
125
+ },
126
+ {
127
+ name: 'quenty/egg-hunt-hub/lobby',
128
+ source: {
129
+ type: 'roblox-place',
130
+ universeId: 10,
131
+ placeId: 20,
132
+ versionType: 'published',
133
+ },
134
+ action: {
135
+ type: 'github-workflow-dispatch',
136
+ workflow: '.github/workflows/build.yml',
137
+ ref: 'release',
138
+ inputs: { target: 'integration.places.lobby' },
139
+ },
140
+ },
141
+ ]);
142
+ });
143
+ // Regression: the selector was previously re-appended to a target name that
144
+ // already carried one, producing `integration.places.hub.places.hub` — which
145
+ // the dispatched `deploy run` then could not resolve, killing the reload.
146
+ it('does not re-append a place to a selector that already names one', async () => {
147
+ const registry = makeRecordingRegistry();
148
+ await registerWatchesAsync({
149
+ option: watchOption(),
150
+ monitorName: 'integration',
151
+ resolver: makeResolver(),
152
+ candidates: [makeCandidate({ targetName: 'integration.places.hub' })],
153
+ createRegistry: registry.create,
154
+ });
155
+ expect(dispatchAction(registry.requests[0]).inputs).toEqual({
156
+ target: 'integration.places.hub',
157
+ });
158
+ });
159
+ it('puts the ref in the monitor name so branches cannot collide', async () => {
160
+ const registry = makeRecordingRegistry();
161
+ await registerWatchesAsync({
162
+ option: watchOption(),
163
+ monitorName: 'integration',
164
+ resolver: makeResolver(),
165
+ candidates: [makeCandidate()],
166
+ createRegistry: registry.create,
167
+ });
168
+ // GITHUB_REF_NAME is stubbed to "release" for these tests.
169
+ expect(registry.requests[0].monitorName).toBe('integration/release');
170
+ expect(dispatchAction(registry.requests[0]).ref).toBe('release');
171
+ });
172
+ it('refuses to register from a pull request merge ref', async () => {
173
+ vi.stubEnv('GITHUB_REF_NAME', '42/merge');
174
+ await expect(registerWatchesAsync({
175
+ option: watchOption(),
176
+ monitorName: 'integration',
177
+ resolver: makeResolver(),
178
+ candidates: [makeCandidate()],
179
+ createRegistry: fakeRegistry({}),
180
+ })).rejects.toThrowError(/pull request merge ref/);
181
+ });
182
+ // Places are only optionally named, so a multi-place target can collide by
183
+ // construction. The service resolves duplicates its own way, which silently
184
+ // drops a watch.
185
+ it('disambiguates watch names that would otherwise collide', async () => {
186
+ const registry = makeRecordingRegistry();
187
+ await registerWatchesAsync({
188
+ option: watchOption(),
189
+ monitorName: 'integration',
190
+ resolver: makeResolver(),
191
+ candidates: [
192
+ makeCandidate({
193
+ place: makePlace({
194
+ name: undefined,
195
+ basePlace: { universeId: 10, placeId: 20, version: 'published' },
196
+ }),
197
+ }),
198
+ makeCandidate({
199
+ place: makePlace({
200
+ name: undefined,
201
+ basePlace: { universeId: 10, placeId: 21, version: 'published' },
202
+ }),
203
+ }),
204
+ ],
205
+ createRegistry: registry.create,
206
+ });
207
+ const names = registry.requests[0].watches.map((w) => w.name);
208
+ expect(names).toEqual([
209
+ 'quenty/egg-hunt-hub/integration/20',
210
+ 'quenty/egg-hunt-hub/integration/21',
211
+ ]);
212
+ expect(new Set(names).size).toBe(2);
213
+ });
214
+ // The service refuses "saved" at registration until it has a credentialed
215
+ // driver. That refusal would fail the whole request — every watch in the
216
+ // monitor — so it has to be filtered before sending, not sent and rejected.
217
+ it('leaves out a "saved" pin without dropping its siblings', async () => {
218
+ const registry = makeRecordingRegistry();
219
+ const result = await registerWatchesAsync({
220
+ option: watchOption(),
221
+ monitorName: 'integration',
222
+ resolver: makeResolver(),
223
+ candidates: [
224
+ makeCandidate({
225
+ place: makePlace({
226
+ name: 'studio',
227
+ basePlace: { universeId: 10, placeId: 20, version: 'saved' },
228
+ }),
229
+ }),
230
+ makeCandidate({ place: makePlace({ name: 'hub' }) }),
231
+ ],
232
+ createRegistry: registry.create,
233
+ });
234
+ expect(result.registered).toBe(1);
235
+ expect(registry.requests[0].watches.map((w) => w.name)).toEqual([
236
+ 'quenty/egg-hunt-hub/hub',
237
+ ]);
238
+ });
239
+ it('sends the version type an omitted pin resolves to', async () => {
240
+ const registry = makeRecordingRegistry();
241
+ await registerWatchesAsync({
242
+ option: watchOption(),
243
+ monitorName: 'integration',
244
+ resolver: makeResolver(),
245
+ candidates: [
246
+ makeCandidate({
247
+ place: makePlace({ basePlace: { universeId: 10, placeId: 20 } }),
248
+ }),
249
+ ],
250
+ createRegistry: registry.create,
251
+ });
252
+ expect(registry.requests[0].watches[0].source.versionType).toBe('published');
253
+ });
254
+ it('leaves distinct watch names untouched', async () => {
255
+ const registry = makeRecordingRegistry();
256
+ await registerWatchesAsync({
257
+ option: watchOption(),
258
+ monitorName: 'integration',
259
+ resolver: makeResolver(),
260
+ candidates: [
261
+ makeCandidate({ place: makePlace({ name: 'hub' }) }),
262
+ makeCandidate({ place: makePlace({ name: 'lobby' }) }),
263
+ ],
264
+ createRegistry: registry.create,
265
+ });
266
+ expect(registry.requests[0].watches.map((w) => w.name)).toEqual([
267
+ 'quenty/egg-hunt-hub/hub',
268
+ 'quenty/egg-hunt-hub/lobby',
269
+ ]);
270
+ });
271
+ it('strips the npm scope marker from names the service would reject', async () => {
272
+ const registry = makeRecordingRegistry();
273
+ await registerWatchesAsync({
274
+ option: watchOption(),
275
+ monitorName: '@quenty/egg-hunt-hub/integration',
276
+ resolver: makeResolver(),
277
+ candidates: [makeCandidate()],
278
+ createRegistry: registry.create,
279
+ });
280
+ expect(registry.requests[0].monitorName).toBe('quenty/egg-hunt-hub/integration/release');
281
+ expect(registry.requests[0].watches[0].name).toBe('quenty/egg-hunt-hub/hub');
282
+ });
283
+ // Reading anonymously, the service compares asset-delivery content hashes, and
284
+ // the lock's Open Cloud version number could only ever look like drift —
285
+ // dispatching a rebuild of what was just built. Omitting makes the first poll
286
+ // adopt what is there.
287
+ it('sends no baseline when no key is shared', async () => {
288
+ const registry = makeRecordingRegistry();
289
+ await writeLockAsync(20, 42);
290
+ await registerWatchesAsync({
291
+ option: watchOption(),
292
+ monitorName: 'integration',
293
+ resolver: makeResolver(),
294
+ candidates: [makeCandidate()],
295
+ createRegistry: registry.create,
296
+ });
297
+ expect(registry.requests[0].watches[0].baselineVersion).toBeUndefined();
298
+ expect(registry.requests[0].watches[0].baselineVersionKind).toBeUndefined();
299
+ });
300
+ // With a key the service reads version history and answers in place versions
301
+ // — the same language the lock is written in — so a baseline finally means
302
+ // what it says.
303
+ it('sends the lock baseline, declared, when a key is shared', async () => {
304
+ const registry = makeRecordingRegistry();
305
+ await writeLockAsync(20, 42);
306
+ await registerWatchesAsync({
307
+ option: watchOption(),
308
+ monitorName: 'integration',
309
+ resolver: makeResolver(),
310
+ robloxApiKey: 'secret',
311
+ candidates: [makeCandidate()],
312
+ createRegistry: registry.create,
313
+ });
314
+ expect(registry.requests[0].watches[0].baselineVersion).toBe('42');
315
+ expect(registry.requests[0].watches[0].baselineVersionKind).toBe('roblox-place-version');
316
+ });
317
+ // This is what a baseline is for in a batch: a package that did not deploy
318
+ // this run still has a lock entry, and without it the first poll would adopt
319
+ // current and never notice the change that already happened.
320
+ it('takes the baseline from the lock, never the network', async () => {
321
+ const registry = makeRecordingRegistry();
322
+ await writeLockAsync(20, 42);
323
+ await registerWatchesAsync({
324
+ option: watchOption(),
325
+ monitorName: 'integration',
326
+ resolver: makeResolver(),
327
+ robloxApiKey: 'secret',
328
+ candidates: [makeCandidate()],
329
+ createRegistry: registry.create,
330
+ });
331
+ // makeResolver throws if anything reaches for the network.
332
+ expect(registry.requests[0].watches[0].baselineVersion).toBe('42');
333
+ });
334
+ it('omits the baseline when the lock has no entry for the place', async () => {
335
+ const registry = makeRecordingRegistry();
336
+ await registerWatchesAsync({
337
+ option: watchOption(),
338
+ monitorName: 'integration',
339
+ resolver: makeResolver(),
340
+ robloxApiKey: 'secret',
341
+ candidates: [makeCandidate()],
342
+ createRegistry: registry.create,
343
+ });
344
+ expect(registry.requests[0].watches[0].baselineVersion).toBeUndefined();
345
+ });
346
+ it('registers nothing when no place is watchable', async () => {
347
+ const registry = makeRecordingRegistry();
348
+ const result = await registerWatchesAsync({
349
+ option: watchOption(),
350
+ monitorName: 'integration',
351
+ resolver: makeResolver(),
352
+ candidates: [makeCandidate({ place: makePlace({ watch: undefined }) })],
353
+ createRegistry: registry.create,
354
+ });
355
+ expect(result).toEqual({ registered: 0 });
356
+ expect(registry.requests).toEqual([]);
357
+ });
358
+ it('leaves out a place whose base place is pinned to an exact version', async () => {
359
+ const registry = makeRecordingRegistry();
360
+ const result = await registerWatchesAsync({
361
+ option: watchOption(),
362
+ monitorName: 'integration',
363
+ resolver: makeResolver(),
364
+ candidates: [
365
+ makeCandidate({
366
+ place: makePlace({
367
+ basePlace: { universeId: 10, placeId: 20, version: 158 },
368
+ }),
369
+ }),
370
+ ],
371
+ createRegistry: registry.create,
372
+ });
373
+ expect(result).toEqual({ registered: 0 });
374
+ expect(registry.requests).toEqual([]);
375
+ });
376
+ it('keeps watchable places when a sibling is not watchable', async () => {
377
+ const registry = makeRecordingRegistry();
378
+ const result = await registerWatchesAsync({
379
+ option: watchOption(),
380
+ monitorName: 'integration',
381
+ resolver: makeResolver(),
382
+ candidates: [
383
+ makeCandidate({ place: makePlace({ name: 'hub' }) }),
384
+ makeCandidate({
385
+ place: makePlace({ name: 'lobby', watch: undefined }),
386
+ }),
387
+ ],
388
+ createRegistry: registry.create,
389
+ });
390
+ expect(result.registered).toBe(1);
391
+ expect(registry.requests[0].watches.map((w) => w.name)).toEqual([
392
+ 'quenty/egg-hunt-hub/hub',
393
+ ]);
394
+ });
395
+ it('shares the Open Cloud key only when given one', async () => {
396
+ const registry = makeRecordingRegistry();
397
+ await registerWatchesAsync({
398
+ option: watchOption(),
399
+ monitorName: 'integration',
400
+ resolver: makeResolver(),
401
+ candidates: [makeCandidate()],
402
+ createRegistry: registry.create,
403
+ });
404
+ expect(registry.requests[0].robloxApiKey).toBeUndefined();
405
+ await registerWatchesAsync({
406
+ option: watchOption(),
407
+ monitorName: 'integration',
408
+ resolver: makeResolver(),
409
+ robloxApiKey: 'oc-key',
410
+ candidates: [makeCandidate()],
411
+ createRegistry: registry.create,
412
+ });
413
+ expect(registry.requests[1].robloxApiKey).toBe('oc-key');
414
+ });
415
+ it('reports an unchanged re-apply', async () => {
416
+ const result = await registerWatchesAsync({
417
+ option: watchOption(),
418
+ monitorName: 'integration',
419
+ resolver: makeResolver(),
420
+ candidates: [makeCandidate()],
421
+ createRegistry: fakeRegistry({
422
+ registerAsync: async () => ({ changed: false }),
423
+ }),
424
+ });
425
+ expect(result).toEqual({ registered: 1, changed: false });
426
+ });
427
+ describe('triggerAfterRegister', () => {
428
+ it('fires the monitor after registering', async () => {
429
+ const triggered = [];
430
+ const result = await registerWatchesAsync({
431
+ option: watchOption(),
432
+ monitorName: 'integration',
433
+ resolver: makeResolver(),
434
+ candidates: [makeCandidate()],
435
+ triggerAfterRegister: true,
436
+ createRegistry: fakeRegistry({
437
+ registerAsync: async () => ({ monitorId: 'mon_7' }),
438
+ triggerAsync: async (monitorId, credential) => {
439
+ triggered.push({ monitorId, credential });
440
+ return { results: [{ watchName: 'w', ok: true }] };
441
+ },
442
+ }),
443
+ });
444
+ expect(triggered).toEqual([
445
+ { monitorId: 'mon_7', credential: 'token-value' },
446
+ ]);
447
+ expect(result.triggered).toBe(1);
448
+ });
449
+ it('does not fire unless asked', async () => {
450
+ const trigger = vi.fn(async () => ({ results: [] }));
451
+ const result = await registerWatchesAsync({
452
+ option: watchOption(),
453
+ monitorName: 'integration',
454
+ resolver: makeResolver(),
455
+ candidates: [makeCandidate()],
456
+ createRegistry: fakeRegistry({
457
+ registerAsync: async () => ({ monitorId: 'mon_7' }),
458
+ triggerAsync: trigger,
459
+ }),
460
+ });
461
+ expect(trigger).not.toHaveBeenCalled();
462
+ expect(result.triggered).toBeUndefined();
463
+ });
464
+ // The monitor exists and is worth keeping; only the demonstration failed.
465
+ it('keeps the registration when the forced dispatch fails', async () => {
466
+ const result = await registerWatchesAsync({
467
+ option: watchOption(),
468
+ monitorName: 'integration',
469
+ resolver: makeResolver(),
470
+ candidates: [makeCandidate()],
471
+ triggerAfterRegister: true,
472
+ createRegistry: fakeRegistry({
473
+ registerAsync: async () => ({ monitorId: 'mon_7' }),
474
+ triggerAsync: async () => {
475
+ throw new Error('service said no');
476
+ },
477
+ }),
478
+ });
479
+ expect(result.registered).toBe(1);
480
+ expect(result.triggered).toBeUndefined();
481
+ });
482
+ it('counts only the watches that actually dispatched', async () => {
483
+ const result = await registerWatchesAsync({
484
+ option: watchOption(),
485
+ monitorName: 'integration',
486
+ resolver: makeResolver(),
487
+ candidates: [makeCandidate()],
488
+ triggerAfterRegister: true,
489
+ createRegistry: fakeRegistry({
490
+ registerAsync: async () => ({ monitorId: 'mon_7' }),
491
+ triggerAsync: async () => ({
492
+ results: [
493
+ { watchName: 'a', ok: true },
494
+ { watchName: 'b', ok: false, detail: 'workflow missing' },
495
+ ],
496
+ }),
497
+ }),
498
+ });
499
+ expect(result.triggered).toBe(1);
500
+ });
501
+ });
502
+ it('uses the explicit register URL when one was given', async () => {
503
+ const urls = [];
504
+ await registerWatchesAsync({
505
+ option: parseWatchOption('https://watch.example.com/v1/register/2w/'),
506
+ monitorName: 'integration',
507
+ resolver: makeResolver(),
508
+ candidates: [makeCandidate()],
509
+ createRegistry: (url) => {
510
+ urls.push(url);
511
+ return fakeRegistry({})(url);
512
+ },
513
+ });
514
+ expect(urls).toEqual(['https://watch.example.com/v1/register/2w/']);
515
+ });
516
+ it('fails when there is no repository to dispatch', async () => {
517
+ // An absent GITHUB_REPOSITORY falls back to the "origin" remote, so the
518
+ // only way to have no repository is to also be outside a git checkout.
519
+ // The temp package dir is exactly that.
520
+ const originalCwd = process.cwd();
521
+ vi.stubEnv('GITHUB_REPOSITORY', '');
522
+ process.chdir(packageDir);
523
+ try {
524
+ await expect(registerWatchesAsync({
525
+ option: watchOption(),
526
+ monitorName: 'integration',
527
+ resolver: makeResolver(),
528
+ candidates: [makeCandidate()],
529
+ createRegistry: fakeRegistry({}),
530
+ })).rejects.toThrowError(/GitHub repository/);
531
+ }
532
+ finally {
533
+ process.chdir(originalCwd);
534
+ }
535
+ });
536
+ it('falls back to the origin remote when GITHUB_REPOSITORY is unset', async () => {
537
+ const registry = makeRecordingRegistry();
538
+ vi.stubEnv('GITHUB_REPOSITORY', '');
539
+ await registerWatchesAsync({
540
+ option: watchOption(),
541
+ monitorName: 'integration',
542
+ resolver: makeResolver(),
543
+ candidates: [makeCandidate()],
544
+ createRegistry: registry.create,
545
+ });
546
+ // Resolved from this repo's own remote, whatever it is named.
547
+ expect(registry.requests[0].repository).toMatch(/^[\w.-]+\/[\w.-]+$/);
548
+ });
549
+ // An unset CI secret expands to "" rather than being absent, so the fallback
550
+ // has to treat empty as missing or it never fires.
551
+ it('falls back to GITHUB_TOKEN when the watch token is set but empty', async () => {
552
+ const registry = makeRecordingRegistry();
553
+ vi.stubEnv('NEVERMORE_WATCH_TOKEN', '');
554
+ vi.stubEnv('GITHUB_TOKEN', 'fallback-token');
555
+ await registerWatchesAsync({
556
+ option: watchOption(),
557
+ monitorName: 'integration',
558
+ resolver: makeResolver(),
559
+ candidates: [makeCandidate()],
560
+ createRegistry: registry.create,
561
+ });
562
+ expect(registry.requests[0].githubToken).toBe('fallback-token');
563
+ });
564
+ it('fails when there is no token to dispatch with', async () => {
565
+ vi.stubEnv('NEVERMORE_WATCH_TOKEN', '');
566
+ vi.stubEnv('GITHUB_TOKEN', '');
567
+ await expect(registerWatchesAsync({
568
+ option: watchOption(),
569
+ monitorName: 'integration',
570
+ resolver: makeResolver(),
571
+ candidates: [makeCandidate()],
572
+ createRegistry: fakeRegistry({}),
573
+ })).rejects.toThrowError(/No GitHub token found/);
574
+ });
575
+ });
576
+ //# sourceMappingURL=register-watches.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-watches.test.js","sourceRoot":"","sources":["../../../src/utils/watch/register-watches.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import { type PlaceVersionSource, type WatchStream } from '@quenty/nevermore-deploy';
2
+ import { type LocalWatchEntry } from './local-watch-loop.js';
3
+ /** A locally-watched place, paired with the watch name it was registered under. */
4
+ export interface StreamWatchEntry extends LocalWatchEntry {
5
+ /** `Watch.name` in the registered monitor; how the service refers to it. */
6
+ watchName: string;
7
+ }
8
+ export interface StreamWatchLoopOptions {
9
+ entries: StreamWatchEntry[];
10
+ stream: WatchStream;
11
+ /**
12
+ * Where the version to build from comes from.
13
+ *
14
+ * The service and this CLI do not share a version vocabulary — see the note
15
+ * on `_settleAsync` — so the stream says *that* a place moved and this says
16
+ * *what* it moved to.
17
+ */
18
+ source: PlaceVersionSource;
19
+ monitorId: string;
20
+ /** Bearer token; the same one registration used. */
21
+ credential: string;
22
+ /** Rebuild and redeploy. Errors are reported and the stream stays up. */
23
+ redeployAsync: (entry: StreamWatchEntry, version: number) => Promise<void>;
24
+ /** Lets a caller stop the loop; SIGINT is wired to one by default. */
25
+ signal?: AbortSignal;
26
+ }
27
+ export interface StreamWatchLoopResult {
28
+ redeploys: number;
29
+ failures: number;
30
+ reconnects: number;
31
+ /** True when the monitor went away rather than the user stopping. */
32
+ monitorGone: boolean;
33
+ /** True when the service refused the handshake for good. */
34
+ rejected: boolean;
35
+ /**
36
+ * True when the service cannot observe any of these places, so holding the
37
+ * stream would wait forever. The caller should fall back to polling.
38
+ */
39
+ unobservable: boolean;
40
+ }
41
+ /**
42
+ * Watch by being told, and rebuild here.
43
+ *
44
+ * The service polls the base place and pushes a `notify` when it moves, so this
45
+ * side holds a socket instead of a poll timer — no Open Cloud quota spent per
46
+ * developer, and the rebuild starts when the change happens rather than up to
47
+ * an interval later.
48
+ *
49
+ * There is no session length. A held connection renews the monitor's lease, so
50
+ * the lease passed to `--watch` is a floor for how long the monitor outlives a
51
+ * dropped link, not a clock on the terminal: this runs until Ctrl-C.
52
+ */
53
+ export declare function runStreamWatchLoopAsync(options: StreamWatchLoopOptions): Promise<StreamWatchLoopResult>;
54
+ //# sourceMappingURL=stream-watch-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-watch-loop.d.ts","sourceRoot":"","sources":["../../../src/utils/watch/stream-watch-loop.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAIjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAgB7D,mFAAmF;AACnF,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,4EAA4E;IAC5E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB;;;;;;OAMG;IACH,MAAM,EAAE,kBAAkB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,aAAa,EAAE,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3E,sEAAsE;IACtE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,WAAW,EAAE,OAAO,CAAC;IACrB,4DAA4D;IAC5D,QAAQ,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CA2UhC"}