@quenty/nevermore-cli 4.41.1 → 4.42.1-canary.783.30683193716.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 (207) hide show
  1. package/CHANGELOG.md +28 -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 +25 -4
  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 +297 -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 +23 -11
  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 +78 -21
  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/parsers/batch-log-parser.d.ts +13 -5
  65. package/dist/utils/testing/parsers/batch-log-parser.d.ts.map +1 -1
  66. package/dist/utils/testing/parsers/batch-log-parser.js +114 -68
  67. package/dist/utils/testing/parsers/batch-log-parser.js.map +1 -1
  68. package/dist/utils/testing/parsers/batch-log-parser.test.js +57 -5
  69. package/dist/utils/testing/parsers/batch-log-parser.test.js.map +1 -1
  70. package/dist/utils/testing/parsers/traceback-parser.d.ts +31 -0
  71. package/dist/utils/testing/parsers/traceback-parser.d.ts.map +1 -0
  72. package/dist/utils/testing/parsers/traceback-parser.js +91 -0
  73. package/dist/utils/testing/parsers/traceback-parser.js.map +1 -0
  74. package/dist/utils/testing/parsers/traceback-parser.test.d.ts +2 -0
  75. package/dist/utils/testing/parsers/traceback-parser.test.d.ts.map +1 -0
  76. package/dist/utils/testing/parsers/traceback-parser.test.js +45 -0
  77. package/dist/utils/testing/parsers/traceback-parser.test.js.map +1 -0
  78. package/dist/utils/testing/runner/combined-project-generator.d.ts +1 -1
  79. package/dist/utils/testing/runner/combined-project-generator.d.ts.map +1 -1
  80. package/dist/utils/testing/runner/test-runner.d.ts +9 -1
  81. package/dist/utils/testing/runner/test-runner.d.ts.map +1 -1
  82. package/dist/utils/testing/runner/test-runner.js +28 -3
  83. package/dist/utils/testing/runner/test-runner.js.map +1 -1
  84. package/dist/utils/testing/runner/test-runner.test.d.ts +2 -0
  85. package/dist/utils/testing/runner/test-runner.test.d.ts.map +1 -0
  86. package/dist/utils/testing/runner/test-runner.test.js +18 -0
  87. package/dist/utils/testing/runner/test-runner.test.js.map +1 -0
  88. package/dist/utils/testing/test-log-parser.d.ts +32 -1
  89. package/dist/utils/testing/test-log-parser.d.ts.map +1 -1
  90. package/dist/utils/testing/test-log-parser.js +53 -9
  91. package/dist/utils/testing/test-log-parser.js.map +1 -1
  92. package/dist/utils/testing/test-log-parser.test.d.ts +2 -0
  93. package/dist/utils/testing/test-log-parser.test.d.ts.map +1 -0
  94. package/dist/utils/testing/test-log-parser.test.js +56 -0
  95. package/dist/utils/testing/test-log-parser.test.js.map +1 -0
  96. package/dist/utils/watch/github-context.d.ts +50 -0
  97. package/dist/utils/watch/github-context.d.ts.map +1 -0
  98. package/dist/utils/watch/github-context.js +125 -0
  99. package/dist/utils/watch/github-context.js.map +1 -0
  100. package/dist/utils/watch/github-context.test.d.ts +2 -0
  101. package/dist/utils/watch/github-context.test.d.ts.map +1 -0
  102. package/dist/utils/watch/github-context.test.js +112 -0
  103. package/dist/utils/watch/github-context.test.js.map +1 -0
  104. package/dist/utils/watch/http-watch-registry.d.ts +40 -0
  105. package/dist/utils/watch/http-watch-registry.d.ts.map +1 -0
  106. package/dist/utils/watch/http-watch-registry.js +262 -0
  107. package/dist/utils/watch/http-watch-registry.js.map +1 -0
  108. package/dist/utils/watch/http-watch-registry.test.d.ts +2 -0
  109. package/dist/utils/watch/http-watch-registry.test.d.ts.map +1 -0
  110. package/dist/utils/watch/http-watch-registry.test.js +211 -0
  111. package/dist/utils/watch/http-watch-registry.test.js.map +1 -0
  112. package/dist/utils/watch/local-watch-loop.d.ts +50 -0
  113. package/dist/utils/watch/local-watch-loop.d.ts.map +1 -0
  114. package/dist/utils/watch/local-watch-loop.js +103 -0
  115. package/dist/utils/watch/local-watch-loop.js.map +1 -0
  116. package/dist/utils/watch/local-watch-loop.test.d.ts +2 -0
  117. package/dist/utils/watch/local-watch-loop.test.d.ts.map +1 -0
  118. package/dist/utils/watch/local-watch-loop.test.js +170 -0
  119. package/dist/utils/watch/local-watch-loop.test.js.map +1 -0
  120. package/dist/utils/watch/register-notify-watches.d.ts +41 -0
  121. package/dist/utils/watch/register-notify-watches.d.ts.map +1 -0
  122. package/dist/utils/watch/register-notify-watches.js +159 -0
  123. package/dist/utils/watch/register-notify-watches.js.map +1 -0
  124. package/dist/utils/watch/register-notify-watches.test.d.ts +2 -0
  125. package/dist/utils/watch/register-notify-watches.test.d.ts.map +1 -0
  126. package/dist/utils/watch/register-notify-watches.test.js +225 -0
  127. package/dist/utils/watch/register-notify-watches.test.js.map +1 -0
  128. package/dist/utils/watch/register-watches.d.ts +68 -0
  129. package/dist/utils/watch/register-watches.d.ts.map +1 -0
  130. package/dist/utils/watch/register-watches.js +221 -0
  131. package/dist/utils/watch/register-watches.js.map +1 -0
  132. package/dist/utils/watch/register-watches.test.d.ts +2 -0
  133. package/dist/utils/watch/register-watches.test.d.ts.map +1 -0
  134. package/dist/utils/watch/register-watches.test.js +576 -0
  135. package/dist/utils/watch/register-watches.test.js.map +1 -0
  136. package/dist/utils/watch/stream-watch-loop.d.ts +54 -0
  137. package/dist/utils/watch/stream-watch-loop.d.ts.map +1 -0
  138. package/dist/utils/watch/stream-watch-loop.js +282 -0
  139. package/dist/utils/watch/stream-watch-loop.js.map +1 -0
  140. package/dist/utils/watch/stream-watch-loop.test.d.ts +2 -0
  141. package/dist/utils/watch/stream-watch-loop.test.d.ts.map +1 -0
  142. package/dist/utils/watch/stream-watch-loop.test.js +392 -0
  143. package/dist/utils/watch/stream-watch-loop.test.js.map +1 -0
  144. package/dist/utils/watch/websocket-watch-stream.d.ts +25 -0
  145. package/dist/utils/watch/websocket-watch-stream.d.ts.map +1 -0
  146. package/dist/utils/watch/websocket-watch-stream.js +306 -0
  147. package/dist/utils/watch/websocket-watch-stream.js.map +1 -0
  148. package/dist/utils/watch/websocket-watch-stream.test.d.ts +2 -0
  149. package/dist/utils/watch/websocket-watch-stream.test.d.ts.map +1 -0
  150. package/dist/utils/watch/websocket-watch-stream.test.js +475 -0
  151. package/dist/utils/watch/websocket-watch-stream.test.js.map +1 -0
  152. package/package.json +7 -4
  153. package/src/args/global-args.ts +13 -0
  154. package/src/commands/batch-command/batch-deploy-command.ts +105 -1
  155. package/src/commands/batch-command/batch-test-command.ts +86 -60
  156. package/src/commands/deploy-command/deploy-init.ts +1 -1
  157. package/src/commands/deploy-command/index.ts +327 -32
  158. package/src/commands/deploy-command/select-target.ts +1 -1
  159. package/src/commands/deploy-command/version-command.ts +215 -21
  160. package/src/commands/test-command/test-command.ts +31 -22
  161. package/src/nevermore.ts +19 -0
  162. package/src/utils/batch/changed-packages-utils.ts +1 -1
  163. package/src/utils/build/base-place-resolver-factory.ts +49 -0
  164. package/src/utils/build/build.ts +13 -2
  165. package/src/utils/build/upload.ts +1 -1
  166. package/src/utils/deploy/deploy-metadata.ts +1 -1
  167. package/src/utils/job-context/base-job-context.ts +68 -6
  168. package/src/utils/job-context/batch-script-job-context.ts +18 -0
  169. package/src/utils/job-context/cloud-job-context.ts +7 -2
  170. package/src/utils/job-context/local-job-context.ts +7 -2
  171. package/src/utils/open-cloud/open-cloud-client.test.ts +133 -14
  172. package/src/utils/open-cloud/open-cloud-client.ts +131 -35
  173. package/src/utils/testing/parsers/batch-log-parser.test.ts +70 -5
  174. package/src/utils/testing/parsers/batch-log-parser.ts +141 -80
  175. package/src/utils/testing/parsers/traceback-parser.test.ts +64 -0
  176. package/src/utils/testing/parsers/traceback-parser.ts +122 -0
  177. package/src/utils/testing/runner/combined-project-generator.ts +1 -1
  178. package/src/utils/testing/runner/test-runner.test.ts +29 -0
  179. package/src/utils/testing/runner/test-runner.ts +36 -4
  180. package/src/utils/testing/test-log-parser.test.ts +70 -0
  181. package/src/utils/testing/test-log-parser.ts +80 -10
  182. package/src/utils/watch/github-context.test.ts +154 -0
  183. package/src/utils/watch/github-context.ts +184 -0
  184. package/src/utils/watch/http-watch-registry.test.ts +330 -0
  185. package/src/utils/watch/http-watch-registry.ts +341 -0
  186. package/src/utils/watch/local-watch-loop.test.ts +197 -0
  187. package/src/utils/watch/local-watch-loop.ts +190 -0
  188. package/src/utils/watch/register-notify-watches.test.ts +282 -0
  189. package/src/utils/watch/register-notify-watches.ts +226 -0
  190. package/src/utils/watch/register-watches.test.ts +696 -0
  191. package/src/utils/watch/register-watches.ts +369 -0
  192. package/src/utils/watch/stream-watch-loop.test.ts +625 -0
  193. package/src/utils/watch/stream-watch-loop.ts +411 -0
  194. package/src/utils/watch/websocket-watch-stream.test.ts +581 -0
  195. package/src/utils/watch/websocket-watch-stream.ts +403 -0
  196. package/tsconfig.json +19 -6
  197. package/tsconfig.tsbuildinfo +1 -1
  198. package/dist/utils/build/deploy-config.d.ts +0 -71
  199. package/dist/utils/build/deploy-config.d.ts.map +0 -1
  200. package/dist/utils/build/deploy-config.js +0 -164
  201. package/dist/utils/build/deploy-config.js.map +0 -1
  202. package/dist/utils/build/deploy-config.test.d.ts +0 -2
  203. package/dist/utils/build/deploy-config.test.d.ts.map +0 -1
  204. package/dist/utils/build/deploy-config.test.js +0 -126
  205. package/dist/utils/build/deploy-config.test.js.map +0 -1
  206. package/src/utils/build/deploy-config.test.ts +0 -149
  207. package/src/utils/build/deploy-config.ts +0 -259
@@ -0,0 +1,125 @@
1
+ import { execSync } from 'child_process';
2
+ /**
3
+ * Env var holding the token the watch service dispatches with. Checked before
4
+ * `GITHUB_TOKEN` so a long-lived registration token can be kept separate from
5
+ * the short-lived one a workflow run is handed — an Actions `GITHUB_TOKEN`
6
+ * expires with its job, which would outlive nothing.
7
+ */
8
+ const WATCH_TOKEN_ENV = 'NEVERMORE_WATCH_TOKEN';
9
+ /**
10
+ * A `pull_request` run exposes `GITHUB_REF_NAME` as `42/merge` — a synthetic
11
+ * merge ref that exists only for that check run. It is not a branch, so
12
+ * `workflow_dispatch` cannot run on it, and it disappears when the PR closes.
13
+ */
14
+ const MERGE_REF_PATTERN = /^\d+\/(merge|head)$/;
15
+ /**
16
+ * Read an env var, treating empty as absent.
17
+ *
18
+ * CI sets a variable to the empty string when the secret behind it is missing
19
+ * (`FOO: ${{ secrets.ABSENT }}`), which `??` would accept as a real value —
20
+ * so the documented fallback to the next source would never fire.
21
+ */
22
+ function _env(name) {
23
+ const value = process.env[name];
24
+ return value == null || value === '' ? undefined : value;
25
+ }
26
+ /**
27
+ * Work out which repo and ref a watch should dispatch.
28
+ *
29
+ * Prefers the Actions environment, which is authoritative when we are already
30
+ * running inside the workflow being registered, and falls back to the git
31
+ * remote so `--watch <url>` also works from a developer's machine. Best-effort:
32
+ * outside a git repo with no Actions env there is simply nothing to dispatch.
33
+ */
34
+ export function tryResolveGithubDispatchContext(options = {}) {
35
+ const repository = _env('GITHUB_REPOSITORY') ?? _repositoryFromRemote();
36
+ if (!repository) {
37
+ return { success: false, reason: 'no_repository' };
38
+ }
39
+ const ref = _env('GITHUB_REF_NAME') ?? _git(['rev-parse', '--abbrev-ref', 'HEAD']);
40
+ // A detached HEAD gives "HEAD", which is not a ref a dispatch can run on.
41
+ if (!ref || ref === 'HEAD') {
42
+ return { success: false, reason: 'no_ref' };
43
+ }
44
+ if (MERGE_REF_PATTERN.test(ref)) {
45
+ return { success: false, reason: 'undispatchable_ref' };
46
+ }
47
+ const token = _env(WATCH_TOKEN_ENV) ??
48
+ _env('GITHUB_TOKEN') ??
49
+ (options.useGhAuth ? _githubCliToken() : undefined);
50
+ return { success: true, context: { repository, ref, token } };
51
+ }
52
+ /** Human-facing explanation for a failed context resolution. */
53
+ export function describeGithubContextFailure(reason) {
54
+ if (reason === 'no_repository') {
55
+ return ('Could not determine the GitHub repository to dispatch. Set ' +
56
+ 'GITHUB_REPOSITORY (owner/repo), or run from a clone with a GitHub ' +
57
+ '"origin" remote.');
58
+ }
59
+ if (reason === 'undispatchable_ref') {
60
+ return ('Refusing to register a watch from a pull request merge ref. That ref ' +
61
+ 'exists only for this check run, so a dispatch against it would fail ' +
62
+ 'and it disappears when the PR closes. Register from a branch instead ' +
63
+ '(e.g. on push to main).');
64
+ }
65
+ return ('Could not determine the git ref to dispatch on. Set GITHUB_REF_NAME, or ' +
66
+ 'check out a branch (a detached HEAD has no ref to run a workflow from).');
67
+ }
68
+ /** Hint printed when a cloud registration has no credential to hand over. */
69
+ export function describeMissingWatchToken() {
70
+ return [
71
+ 'No GitHub token found. The watch service identifies you by repository, ' +
72
+ 'so registering needs a token with "actions: write" on it. Either:',
73
+ ` - Set: ${WATCH_TOKEN_ENV} (or GITHUB_TOKEN)`,
74
+ ' - Pass: --watch-use-gh-auth, to use the token `gh` already holds',
75
+ ].join('\n');
76
+ }
77
+ /**
78
+ * Pull `owner/repo` out of a git remote URL. Handles the HTTPS, SCP-style, and
79
+ * ssh:// spellings git hands out, and ignores non-GitHub hosts — a watch
80
+ * registration names a GitHub workflow, so anything else is not dispatchable.
81
+ */
82
+ export function parseGithubRepository(remoteUrl) {
83
+ const trimmed = remoteUrl.trim();
84
+ const match = /^(?:https?:\/\/|ssh:\/\/)?(?:[^@/]+@)?github\.com[:/]+([^/]+)\/(.+?)(?:\.git)?\/?$/i.exec(trimmed);
85
+ if (!match) {
86
+ return undefined;
87
+ }
88
+ return `${match[1]}/${match[2]}`;
89
+ }
90
+ function _repositoryFromRemote() {
91
+ const remote = _git(['remote', 'get-url', 'origin']);
92
+ return remote == null ? undefined : parseGithubRepository(remote);
93
+ }
94
+ /**
95
+ * The token `gh` is already holding, if it is installed and logged in.
96
+ *
97
+ * Only ever called when the caller opted in. Not stored anywhere by us on
98
+ * purpose: `gh` owns its own refresh, and copying a token into `~/.nevermore`
99
+ * would leave a stale duplicate to expire behind everyone's back — the point is
100
+ * reading the live one, for the one run that asked.
101
+ */
102
+ function _githubCliToken() {
103
+ const token = _run('gh', ['auth', 'token']);
104
+ // A logged-out `gh` exits non-zero, but an odd version could print a notice
105
+ // on stdout instead; a token is never whitespace.
106
+ return token == null || /\s/.test(token) ? undefined : token;
107
+ }
108
+ function _git(args) {
109
+ return _run('git', args);
110
+ }
111
+ function _run(command, args) {
112
+ try {
113
+ const output = execSync(`${command} ${args.join(' ')}`, {
114
+ encoding: 'utf-8',
115
+ timeout: 5000,
116
+ stdio: ['pipe', 'pipe', 'pipe'],
117
+ }).trim();
118
+ return output === '' ? undefined : output;
119
+ }
120
+ catch {
121
+ // Not installed, not logged in, or not a repo — all "no answer here".
122
+ return undefined;
123
+ }
124
+ }
125
+ //# sourceMappingURL=github-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-context.js","sourceRoot":"","sources":["../../../src/utils/watch/github-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=github-context.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-context.test.d.ts","sourceRoot":"","sources":["../../../src/utils/watch/github-context.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,112 @@
1
+ import { describe, it, expect, vi, afterEach } from 'vitest';
2
+ import { describeMissingWatchToken, parseGithubRepository, tryResolveGithubDispatchContext, } from './github-context.js';
3
+ // ESM exports cannot be spied on, so the module is mocked outright.
4
+ const execSyncMock = vi.hoisted(() => vi.fn());
5
+ vi.mock('child_process', () => ({ execSync: execSyncMock }));
6
+ afterEach(() => {
7
+ execSyncMock.mockReset();
8
+ vi.unstubAllEnvs();
9
+ });
10
+ /** Answers the subprocesses github-context shells out to. */
11
+ function stubCommands(answers) {
12
+ execSyncMock.mockImplementation((cmd) => {
13
+ for (const [prefix, answer] of Object.entries(answers)) {
14
+ if (cmd.startsWith(prefix)) {
15
+ if (answer instanceof Error) {
16
+ throw answer;
17
+ }
18
+ return answer;
19
+ }
20
+ }
21
+ throw new Error(`unstubbed command: ${cmd}`);
22
+ });
23
+ }
24
+ describe('tryResolveGithubDispatchContext token', () => {
25
+ const REPO_AND_REF = {
26
+ 'git remote get-url origin': 'git@github.com:Quenty/Nevermore.git',
27
+ 'git rev-parse': 'main',
28
+ };
29
+ // Registering ships the token to the watch service, so it has to be one the
30
+ // user handed over. Nearly every dev machine has a logged-in `gh`, so reading
31
+ // it by default would turn a local watch into a silent credential send.
32
+ it('does not consult gh unless asked', () => {
33
+ vi.stubEnv('NEVERMORE_WATCH_TOKEN', '');
34
+ vi.stubEnv('GITHUB_TOKEN', '');
35
+ stubCommands({
36
+ ...REPO_AND_REF,
37
+ 'gh auth token': new Error('gh must not be consulted'),
38
+ });
39
+ const result = tryResolveGithubDispatchContext();
40
+ expect(result.success && result.context.token).toBeUndefined();
41
+ });
42
+ it('reads the GitHub CLI token when explicitly asked', () => {
43
+ vi.stubEnv('NEVERMORE_WATCH_TOKEN', '');
44
+ vi.stubEnv('GITHUB_TOKEN', '');
45
+ stubCommands({ ...REPO_AND_REF, 'gh auth token': 'gho_from_cli' });
46
+ const result = tryResolveGithubDispatchContext({ useGhAuth: true });
47
+ expect(result.success && result.context.token).toBe('gho_from_cli');
48
+ });
49
+ // CI sets the env var, and must never pay for the subprocess.
50
+ it('prefers the env var and does not shell out to gh', () => {
51
+ vi.stubEnv('NEVERMORE_WATCH_TOKEN', 'from-env');
52
+ stubCommands({
53
+ ...REPO_AND_REF,
54
+ 'gh auth token': new Error('gh should not be consulted'),
55
+ });
56
+ const result = tryResolveGithubDispatchContext({ useGhAuth: true });
57
+ expect(result.success && result.context.token).toBe('from-env');
58
+ });
59
+ it('reports no token when gh is missing or logged out', () => {
60
+ vi.stubEnv('NEVERMORE_WATCH_TOKEN', '');
61
+ vi.stubEnv('GITHUB_TOKEN', '');
62
+ stubCommands({
63
+ ...REPO_AND_REF,
64
+ 'gh auth token': new Error('gh: command not found'),
65
+ });
66
+ const result = tryResolveGithubDispatchContext({ useGhAuth: true });
67
+ expect(result.success && result.context.token).toBeUndefined();
68
+ });
69
+ // A logged-out `gh` exits non-zero, but a notice printed to stdout would sail
70
+ // through as a "token" and fail much later as a confusing 401.
71
+ it('refuses output that cannot be a token', () => {
72
+ vi.stubEnv('NEVERMORE_WATCH_TOKEN', '');
73
+ vi.stubEnv('GITHUB_TOKEN', '');
74
+ stubCommands({
75
+ ...REPO_AND_REF,
76
+ 'gh auth token': 'You are not logged in. Run gh auth login',
77
+ });
78
+ const result = tryResolveGithubDispatchContext({ useGhAuth: true });
79
+ expect(result.success && result.context.token).toBeUndefined();
80
+ });
81
+ it('names both ways of supplying a token when none is found', () => {
82
+ expect(describeMissingWatchToken()).toMatch(/NEVERMORE_WATCH_TOKEN/);
83
+ expect(describeMissingWatchToken()).toMatch(/--watch-use-gh-auth/);
84
+ });
85
+ });
86
+ describe('parseGithubRepository', () => {
87
+ it('parses an https remote', () => {
88
+ expect(parseGithubRepository('https://github.com/Quenty/Nevermore.git')).toBe('Quenty/Nevermore');
89
+ });
90
+ it('parses an https remote without the .git suffix', () => {
91
+ expect(parseGithubRepository('https://github.com/Quenty/Nevermore')).toBe('Quenty/Nevermore');
92
+ });
93
+ it('parses an scp-style ssh remote', () => {
94
+ expect(parseGithubRepository('git@github.com:Quenty/Nevermore.git')).toBe('Quenty/Nevermore');
95
+ });
96
+ it('parses an ssh:// remote', () => {
97
+ expect(parseGithubRepository('ssh://git@github.com/Quenty/Nevermore.git')).toBe('Quenty/Nevermore');
98
+ });
99
+ it('parses a remote with credentials embedded', () => {
100
+ expect(parseGithubRepository('https://user:token@github.com/Quenty/Nevermore.git')).toBe('Quenty/Nevermore');
101
+ });
102
+ it('tolerates surrounding whitespace and a trailing slash', () => {
103
+ expect(parseGithubRepository(' https://github.com/Quenty/Nevermore/ ')).toBe('Quenty/Nevermore');
104
+ });
105
+ it('ignores a non-GitHub host', () => {
106
+ expect(parseGithubRepository('https://gitlab.com/Quenty/Nevermore.git')).toBeUndefined();
107
+ });
108
+ it('ignores a local path remote', () => {
109
+ expect(parseGithubRepository('/srv/git/Nevermore.git')).toBeUndefined();
110
+ });
111
+ });
112
+ //# sourceMappingURL=github-context.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-context.test.js","sourceRoot":"","sources":["../../../src/utils/watch/github-context.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAE7B,oEAAoE;AACpE,MAAM,YAAY,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/C,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;AAE7D,SAAS,CAAC,GAAG,EAAE;IACb,YAAY,CAAC,SAAS,EAAE,CAAC;IACzB,EAAE,CAAC,aAAa,EAAE,CAAC;AACrB,CAAC,CAAC,CAAC;AAEH,6DAA6D;AAC7D,SAAS,YAAY,CAAC,OAAuC;IAC3D,YAAY,CAAC,kBAAkB,CAAC,CAAC,GAAW,EAAE,EAAE;QAC9C,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACvD,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC3B,IAAI,MAAM,YAAY,KAAK,EAAE,CAAC;oBAC5B,MAAM,MAAM,CAAC;gBACf,CAAC;gBACD,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACrD,MAAM,YAAY,GAAG;QACnB,2BAA2B,EAAE,qCAAqC;QAClE,eAAe,EAAE,MAAM;KACxB,CAAC;IAEF,4EAA4E;IAC5E,8EAA8E;IAC9E,wEAAwE;IACxE,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,EAAE,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;QACxC,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC/B,YAAY,CAAC;YACX,GAAG,YAAY;YACf,eAAe,EAAE,IAAI,KAAK,CAAC,0BAA0B,CAAC;SACvD,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,+BAA+B,EAAE,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,EAAE,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;QACxC,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC/B,YAAY,CAAC,EAAE,GAAG,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,CAAC,CAAC;QAEnE,MAAM,MAAM,GAAG,+BAA+B,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,8DAA8D;IAC9D,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,EAAE,CAAC,OAAO,CAAC,uBAAuB,EAAE,UAAU,CAAC,CAAC;QAChD,YAAY,CAAC;YACX,GAAG,YAAY;YACf,eAAe,EAAE,IAAI,KAAK,CAAC,4BAA4B,CAAC;SACzD,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,+BAA+B,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,EAAE,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;QACxC,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC/B,YAAY,CAAC;YACX,GAAG,YAAY;YACf,eAAe,EAAE,IAAI,KAAK,CAAC,uBAAuB,CAAC;SACpD,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,+BAA+B,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,+DAA+D;IAC/D,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,EAAE,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;QACxC,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAC/B,YAAY,CAAC;YACX,GAAG,YAAY;YACf,eAAe,EAAE,0CAA0C;SAC5D,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,+BAA+B,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,aAAa,EAAE,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,CAAC,yBAAyB,EAAE,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;QACrE,MAAM,CAAC,yBAAyB,EAAE,CAAC,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;QAChC,MAAM,CACJ,qBAAqB,CAAC,yCAAyC,CAAC,CACjE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,CAAC,qBAAqB,CAAC,qCAAqC,CAAC,CAAC,CAAC,IAAI,CACvE,kBAAkB,CACnB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,CAAC,qBAAqB,CAAC,qCAAqC,CAAC,CAAC,CAAC,IAAI,CACvE,kBAAkB,CACnB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,CACJ,qBAAqB,CAAC,2CAA2C,CAAC,CACnE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,CACJ,qBAAqB,CACnB,oDAAoD,CACrD,CACF,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,CACJ,qBAAqB,CAAC,0CAA0C,CAAC,CAClE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,CACJ,qBAAqB,CAAC,yCAAyC,CAAC,CACjE,CAAC,aAAa,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,qBAAqB,CAAC,wBAAwB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,40 @@
1
+ import { type WatchRegistrationRequest, type WatchRegistrationResult, type WatchRegistry, type WatchTriggerResult } from '@quenty/nevermore-deploy';
2
+ export interface HttpWatchRegistryOptions {
3
+ /** Full register endpoint, ending in the lease — `.../v1/register/7d/`. */
4
+ registerUrl: string;
5
+ timeoutMs?: number;
6
+ /** Injected in tests. Defaults to the global fetch. */
7
+ fetchImpl?: typeof fetch;
8
+ }
9
+ /**
10
+ * `WatchRegistry` over the Roblox Analytics Watch API.
11
+ *
12
+ * One `POST /v1/register/{lease}` per invocation. The endpoint is whatever URL
13
+ * `--watch` resolved to, so nothing here assumes a host, and the lease is
14
+ * already the last path segment of that URL.
15
+ *
16
+ * The endpoint takes no `Authorization` header — the GitHub token travels in
17
+ * `auth.github.token`, because the service holds it to dispatch with later
18
+ * rather than using it to authenticate this call.
19
+ */
20
+ export declare class HttpWatchRegistry implements WatchRegistry {
21
+ private _registerUrl;
22
+ private _timeoutMs;
23
+ private _fetch;
24
+ constructor(options: HttpWatchRegistryOptions);
25
+ registerAsync(request: WatchRegistrationRequest): Promise<WatchRegistrationResult>;
26
+ triggerAsync(monitorId: string, credential: string, options?: {
27
+ watchName?: string;
28
+ }): Promise<WatchTriggerResult>;
29
+ /**
30
+ * The API root, recovered from the register URL.
31
+ *
32
+ * `--watch` names the register endpoint because that is the one a user has to
33
+ * type; every other call is derived from it. The lease-bearing
34
+ * `/v1/register/<lease>/` suffix is the documented shape, so trimming it is
35
+ * how a single flag reaches the rest of the API.
36
+ */
37
+ private _apiBase;
38
+ private _fetchWithTimeoutAsync;
39
+ }
40
+ //# sourceMappingURL=http-watch-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-watch-registry.d.ts","sourceRoot":"","sources":["../../../src/utils/watch/http-watch-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAIlC,MAAM,WAAW,wBAAwB;IACvC,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED;;;;;;;;;;GAUG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IACrD,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,MAAM,CAAe;gBAEjB,OAAO,EAAE,wBAAwB;IAMvC,aAAa,CACjB,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,uBAAuB,CAAC;IAwE7B,YAAY,CAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,GACnC,OAAO,CAAC,kBAAkB,CAAC;IAmC9B;;;;;;;OAOG;IACH,OAAO,CAAC,QAAQ;YAYF,sBAAsB;CAsBrC"}
@@ -0,0 +1,262 @@
1
+ const DEFAULT_TIMEOUT_MS = 30_000;
2
+ /**
3
+ * `WatchRegistry` over the Roblox Analytics Watch API.
4
+ *
5
+ * One `POST /v1/register/{lease}` per invocation. The endpoint is whatever URL
6
+ * `--watch` resolved to, so nothing here assumes a host, and the lease is
7
+ * already the last path segment of that URL.
8
+ *
9
+ * The endpoint takes no `Authorization` header — the GitHub token travels in
10
+ * `auth.github.token`, because the service holds it to dispatch with later
11
+ * rather than using it to authenticate this call.
12
+ */
13
+ export class HttpWatchRegistry {
14
+ _registerUrl;
15
+ _timeoutMs;
16
+ _fetch;
17
+ constructor(options) {
18
+ this._registerUrl = options.registerUrl;
19
+ this._timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
20
+ this._fetch = options.fetchImpl ?? fetch;
21
+ }
22
+ async registerAsync(request) {
23
+ const body = {
24
+ name: request.monitorName,
25
+ auth: {
26
+ github: {
27
+ token: request.githubToken,
28
+ repository: request.repository,
29
+ },
30
+ ...(request.robloxApiKey
31
+ ? { robloxOpenCloud: { apiKey: request.robloxApiKey } }
32
+ : {}),
33
+ },
34
+ watches: request.watches.map((watch) => ({
35
+ name: watch.name,
36
+ source: {
37
+ type: watch.source.type,
38
+ universeId: watch.source.universeId,
39
+ placeId: watch.source.placeId,
40
+ versionType: watch.source.versionType,
41
+ },
42
+ // The kind travels with the value or not at all. Without it the service
43
+ // ignores a baseline outright on the one transition it matters for —
44
+ // the first registration that supplies an Open Cloud key — and the 422
45
+ // that should catch a vocabulary mismatch can never fire.
46
+ ...(watch.baselineVersion == null
47
+ ? {}
48
+ : {
49
+ baselineVersion: watch.baselineVersion,
50
+ ...(watch.baselineVersionKind == null
51
+ ? {}
52
+ : { baselineVersionKind: watch.baselineVersionKind }),
53
+ }),
54
+ action: watch.action,
55
+ })),
56
+ ...(request.cooldownSeconds == null
57
+ ? {}
58
+ : { cooldownSeconds: request.cooldownSeconds }),
59
+ };
60
+ const controller = new AbortController();
61
+ const timeout = setTimeout(() => controller.abort(), this._timeoutMs);
62
+ let response;
63
+ try {
64
+ response = await this._fetch(this._registerUrl, {
65
+ method: 'POST',
66
+ headers: { 'Content-Type': 'application/json' },
67
+ body: JSON.stringify(body),
68
+ signal: controller.signal,
69
+ });
70
+ }
71
+ catch (err) {
72
+ if (controller.signal.aborted) {
73
+ throw new Error(`Watch registration timed out after ${this._timeoutMs}ms: ${this._registerUrl}`);
74
+ }
75
+ throw new Error(`Watch registration could not reach ${this._registerUrl}: ` +
76
+ (err instanceof Error ? err.message : String(err)));
77
+ }
78
+ finally {
79
+ clearTimeout(timeout);
80
+ }
81
+ const text = await _readTextAsync(response);
82
+ if (!response.ok) {
83
+ throw new Error(_describeFailure(response, text, request));
84
+ }
85
+ return _parseResult(text);
86
+ }
87
+ async triggerAsync(monitorId, credential, options = {}) {
88
+ const url = `${this._apiBase()}/v1/monitors/${encodeURIComponent(monitorId)}/trigger`;
89
+ const response = await this._fetchWithTimeoutAsync(url, {
90
+ method: 'POST',
91
+ headers: {
92
+ 'Content-Type': 'application/json',
93
+ // Unlike register, this endpoint authenticates the caller — the token
94
+ // is the identity, so it travels as a bearer rather than in the body.
95
+ Authorization: `Bearer ${credential}`,
96
+ },
97
+ body: JSON.stringify(options.watchName == null ? {} : { watchName: options.watchName }),
98
+ });
99
+ const text = await _readTextAsync(response);
100
+ if (!response.ok) {
101
+ const detail = _extractError(text);
102
+ throw new Error(`Forcing a dispatch failed (${response.status} ${response.statusText})` +
103
+ (detail ? `: ${detail}` : ''));
104
+ }
105
+ try {
106
+ const parsed = JSON.parse(text);
107
+ return { results: Array.isArray(parsed.results) ? parsed.results : [] };
108
+ }
109
+ catch {
110
+ return { results: [] };
111
+ }
112
+ }
113
+ /**
114
+ * The API root, recovered from the register URL.
115
+ *
116
+ * `--watch` names the register endpoint because that is the one a user has to
117
+ * type; every other call is derived from it. The lease-bearing
118
+ * `/v1/register/<lease>/` suffix is the documented shape, so trimming it is
119
+ * how a single flag reaches the rest of the API.
120
+ */
121
+ _apiBase() {
122
+ const marker = '/v1/register/';
123
+ const index = this._registerUrl.indexOf(marker);
124
+ if (index === -1) {
125
+ throw new Error(`Cannot derive the watch API root from "${this._registerUrl}" — ` +
126
+ `expected it to contain "${marker}".`);
127
+ }
128
+ return this._registerUrl.slice(0, index);
129
+ }
130
+ async _fetchWithTimeoutAsync(url, init) {
131
+ const controller = new AbortController();
132
+ const timeout = setTimeout(() => controller.abort(), this._timeoutMs);
133
+ try {
134
+ return await this._fetch(url, { ...init, signal: controller.signal });
135
+ }
136
+ catch (err) {
137
+ if (controller.signal.aborted) {
138
+ throw new Error(`Watch request timed out after ${this._timeoutMs}ms: ${url}`);
139
+ }
140
+ throw new Error(`Watch request could not reach ${url}: ` +
141
+ (err instanceof Error ? err.message : String(err)));
142
+ }
143
+ finally {
144
+ clearTimeout(timeout);
145
+ }
146
+ }
147
+ }
148
+ /**
149
+ * Turn a status code into something actionable. The API documents exactly what
150
+ * each failure means, and every one of them has a different fix — a generic
151
+ * "registration failed (403)" would send someone to the wrong place.
152
+ *
153
+ * The service's own message wins when it has one, since it knows specifics we
154
+ * can only guess at; ours is the fallback for a bare status. Only the remedy is
155
+ * always ours, and it is what the service never supplies.
156
+ */
157
+ function _describeFailure(response, text, request) {
158
+ const detail = _extractError(text);
159
+ const compose = (fallback, remedy) => {
160
+ const head = detail || fallback;
161
+ return remedy ? `${head}\n${remedy}` : head;
162
+ };
163
+ switch (response.status) {
164
+ case 400:
165
+ return compose('The watch service rejected the registration as invalid.', 'This is a bug in how the CLI built the request — please report it.');
166
+ case 401:
167
+ return compose('GitHub rejected the dispatch token.', 'Set NEVERMORE_WATCH_TOKEN to a valid, unexpired token.');
168
+ case 403:
169
+ return compose(`The dispatch token cannot write to ${request.repository}.`, `The token needs "actions: write" on ${request.repository}.`);
170
+ case 409:
171
+ return compose(`Watch quota exceeded for ${request.repository}.`, 'Release monitors you no longer need, or let their leases expire.');
172
+ case 422: {
173
+ // 422 is the service's "your config cannot work" answer, and it covers
174
+ // several unrelated causes now — a missing workflow, an Open Cloud key
175
+ // without universe.place:read, a "saved" watch with no key, a baseline in
176
+ // the wrong vocabulary. Its own message names which, so the only thing
177
+ // worth adding is a remedy that could not already be in it.
178
+ const workflows = [
179
+ ...new Set(request.watches.flatMap((w) => w.action.type === 'github-workflow-dispatch'
180
+ ? [w.action.workflow]
181
+ : [])),
182
+ ];
183
+ // Volunteering a workflow remedy for a monitor that dispatches none once
184
+ // produced "Referenced: ." under a message about an API key scope.
185
+ if (workflows.length === 0) {
186
+ return compose('The watch service rejected the configuration.');
187
+ }
188
+ return compose(`A referenced workflow does not exist in ${request.repository}.`, `Workflows referenced: ${workflows.join(', ')}. A "watch" path in ` +
189
+ 'deploy.nevermore.json must name a workflow that exists on the ' +
190
+ 'dispatched ref.');
191
+ }
192
+ default:
193
+ return compose(`Watch registration failed (${response.status} ${response.statusText}).`);
194
+ }
195
+ }
196
+ /** Pull the API's `{error, errors}` shape out, falling back to raw text. */
197
+ function _extractError(text) {
198
+ if (text === '') {
199
+ return '';
200
+ }
201
+ try {
202
+ const parsed = JSON.parse(text);
203
+ const parts = [];
204
+ if (typeof parsed.error === 'string') {
205
+ parts.push(parsed.error);
206
+ }
207
+ if (Array.isArray(parsed.errors) && parsed.errors.length > 0) {
208
+ parts.push(JSON.stringify(parsed.errors));
209
+ }
210
+ return parts.length > 0 ? parts.join(' ') : text;
211
+ }
212
+ catch {
213
+ return text;
214
+ }
215
+ }
216
+ async function _readTextAsync(response) {
217
+ try {
218
+ return (await response.text()).trim();
219
+ }
220
+ catch {
221
+ return '';
222
+ }
223
+ }
224
+ /**
225
+ * Read back the fields worth reporting. A 2xx whose body we cannot parse still
226
+ * counts as registered — the service accepted it, and failing here would claim
227
+ * otherwise.
228
+ */
229
+ function _parseResult(text) {
230
+ if (text === '') {
231
+ return {};
232
+ }
233
+ let parsed;
234
+ try {
235
+ parsed = JSON.parse(text);
236
+ }
237
+ catch {
238
+ return {};
239
+ }
240
+ if (typeof parsed !== 'object' || parsed === null) {
241
+ return {};
242
+ }
243
+ const record = parsed;
244
+ const result = {};
245
+ if (typeof record['monitorId'] === 'string') {
246
+ result.monitorId = record['monitorId'];
247
+ }
248
+ if (typeof record['revision'] === 'string') {
249
+ result.revision = record['revision'];
250
+ }
251
+ if (typeof record['leaseExpiresAt'] === 'string') {
252
+ result.leaseExpiresAt = record['leaseExpiresAt'];
253
+ }
254
+ if (typeof record['changed'] === 'boolean') {
255
+ result.changed = record['changed'];
256
+ }
257
+ if (Array.isArray(record['watches'])) {
258
+ result.watchCount = record['watches'].length;
259
+ }
260
+ return result;
261
+ }
262
+ //# sourceMappingURL=http-watch-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-watch-registry.js","sourceRoot":"","sources":["../../../src/utils/watch/http-watch-registry.ts"],"names":[],"mappings":"AAOA,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAUlC;;;;;;;;;;GAUG;AACH,MAAM,OAAO,iBAAiB;IACpB,YAAY,CAAS;IACrB,UAAU,CAAS;IACnB,MAAM,CAAe;IAE7B,YAAY,OAAiC;QAC3C,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;QACxC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,IAAI,kBAAkB,CAAC;QAC1D,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,aAAa,CACjB,OAAiC;QAEjC,MAAM,IAAI,GAAG;YACX,IAAI,EAAE,OAAO,CAAC,WAAW;YACzB,IAAI,EAAE;gBACJ,MAAM,EAAE;oBACN,KAAK,EAAE,OAAO,CAAC,WAAW;oBAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;iBAC/B;gBACD,GAAG,CAAC,OAAO,CAAC,YAAY;oBACtB,CAAC,CAAC,EAAE,eAAe,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,YAAY,EAAE,EAAE;oBACvD,CAAC,CAAC,EAAE,CAAC;aACR;YACD,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;gBACvC,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,MAAM,EAAE;oBACN,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI;oBACvB,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU;oBACnC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO;oBAC7B,WAAW,EAAE,KAAK,CAAC,MAAM,CAAC,WAAW;iBACtC;gBACD,wEAAwE;gBACxE,qEAAqE;gBACrE,uEAAuE;gBACvE,0DAA0D;gBAC1D,GAAG,CAAC,KAAK,CAAC,eAAe,IAAI,IAAI;oBAC/B,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC;wBACE,eAAe,EAAE,KAAK,CAAC,eAAe;wBACtC,GAAG,CAAC,KAAK,CAAC,mBAAmB,IAAI,IAAI;4BACnC,CAAC,CAAC,EAAE;4BACJ,CAAC,CAAC,EAAE,mBAAmB,EAAE,KAAK,CAAC,mBAAmB,EAAE,CAAC;qBACxD,CAAC;gBACN,MAAM,EAAE,KAAK,CAAC,MAAM;aACrB,CAAC,CAAC;YACH,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,IAAI;gBACjC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,eAAe,EAAE,CAAC;SAClD,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAEtE,IAAI,QAAkB,CAAC;QACvB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE;gBAC9C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC1B,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CACb,sCAAsC,IAAI,CAAC,UAAU,OAAO,IAAI,CAAC,YAAY,EAAE,CAChF,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,KAAK,CACb,sCAAsC,IAAI,CAAC,YAAY,IAAI;gBACzD,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CACrD,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,YAAY,CAChB,SAAiB,EACjB,UAAkB,EAClB,UAAkC,EAAE;QAEpC,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,QAAQ,EAAE,gBAAgB,kBAAkB,CAC9D,SAAS,CACV,UAAU,CAAC;QAEZ,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,GAAG,EAAE;YACtD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,sEAAsE;gBACtE,sEAAsE;gBACtE,aAAa,EAAE,UAAU,UAAU,EAAE;aACtC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAClE;SACF,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,IAAI,KAAK,CACb,8BAA8B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,GAAG;gBACrE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAChC,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAuB,CAAC;YACtD,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC1E,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACK,QAAQ;QACd,MAAM,MAAM,GAAG,eAAe,CAAC;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CACb,0CAA0C,IAAI,CAAC,YAAY,MAAM;gBAC/D,2BAA2B,MAAM,IAAI,CACxC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAC3C,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAClC,GAAW,EACX,IAAiB;QAEjB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACtE,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CACb,iCAAiC,IAAI,CAAC,UAAU,OAAO,GAAG,EAAE,CAC7D,CAAC;YACJ,CAAC;YACD,MAAM,IAAI,KAAK,CACb,iCAAiC,GAAG,IAAI;gBACtC,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CACrD,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,SAAS,gBAAgB,CACvB,QAAkB,EAClB,IAAY,EACZ,OAAiC;IAEjC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,OAAO,GAAG,CAAC,QAAgB,EAAE,MAAe,EAAU,EAAE;QAC5D,MAAM,IAAI,GAAG,MAAM,IAAI,QAAQ,CAAC;QAChC,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9C,CAAC,CAAC;IAEF,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxB,KAAK,GAAG;YACN,OAAO,OAAO,CACZ,yDAAyD,EACzD,oEAAoE,CACrE,CAAC;QACJ,KAAK,GAAG;YACN,OAAO,OAAO,CACZ,qCAAqC,EACrC,wDAAwD,CACzD,CAAC;QACJ,KAAK,GAAG;YACN,OAAO,OAAO,CACZ,sCAAsC,OAAO,CAAC,UAAU,GAAG,EAC3D,uCAAuC,OAAO,CAAC,UAAU,GAAG,CAC7D,CAAC;QACJ,KAAK,GAAG;YACN,OAAO,OAAO,CACZ,4BAA4B,OAAO,CAAC,UAAU,GAAG,EACjD,kEAAkE,CACnE,CAAC;QACJ,KAAK,GAAG,CAAC,CAAC,CAAC;YACT,uEAAuE;YACvE,uEAAuE;YACvE,0EAA0E;YAC1E,uEAAuE;YACvE,4DAA4D;YAC5D,MAAM,SAAS,GAAG;gBAChB,GAAG,IAAI,GAAG,CACR,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAC5B,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,0BAA0B;oBAC1C,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;oBACrB,CAAC,CAAC,EAAE,CACP,CACF;aACF,CAAC;YACF,yEAAyE;YACzE,mEAAmE;YACnE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,OAAO,OAAO,CAAC,+CAA+C,CAAC,CAAC;YAClE,CAAC;YACD,OAAO,OAAO,CACZ,2CAA2C,OAAO,CAAC,UAAU,GAAG,EAChE,yBAAyB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB;gBACjE,gEAAgE;gBAChE,iBAAiB,CACpB,CAAC;QACJ,CAAC;QACD;YACE,OAAO,OAAO,CACZ,8BAA8B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,IAAI,CACzE,CAAC;IACN,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,SAAS,aAAa,CAAC,IAAY;IACjC,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAG7B,CAAC;QACF,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,QAAkB;IAC9C,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAS,YAAY,CAAC,IAAY;IAChC,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAClD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,MAAM,GAAG,MAAiC,CAAC;IACjD,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,IAAI,OAAO,MAAM,CAAC,WAAW,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC5C,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC3C,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,gBAAgB,CAAC,KAAK,QAAQ,EAAE,CAAC;QACjD,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACnD,CAAC;IACD,IAAI,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,SAAS,EAAE,CAAC;QAC3C,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IACrC,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;IAC/C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=http-watch-registry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-watch-registry.test.d.ts","sourceRoot":"","sources":["../../../src/utils/watch/http-watch-registry.test.ts"],"names":[],"mappings":""}