@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.
- package/CHANGELOG.md +28 -0
- package/dist/args/global-args.d.ts +13 -0
- package/dist/args/global-args.d.ts.map +1 -1
- package/dist/commands/batch-command/batch-deploy-command.d.ts +3 -0
- package/dist/commands/batch-command/batch-deploy-command.d.ts.map +1 -1
- package/dist/commands/batch-command/batch-deploy-command.js +90 -1
- package/dist/commands/batch-command/batch-deploy-command.js.map +1 -1
- package/dist/commands/batch-command/batch-test-command.d.ts.map +1 -1
- package/dist/commands/batch-command/batch-test-command.js +25 -4
- package/dist/commands/batch-command/batch-test-command.js.map +1 -1
- package/dist/commands/deploy-command/deploy-init.js +1 -1
- package/dist/commands/deploy-command/deploy-init.js.map +1 -1
- package/dist/commands/deploy-command/index.d.ts +3 -0
- package/dist/commands/deploy-command/index.d.ts.map +1 -1
- package/dist/commands/deploy-command/index.js +297 -60
- package/dist/commands/deploy-command/index.js.map +1 -1
- package/dist/commands/deploy-command/select-target.js +1 -1
- package/dist/commands/deploy-command/select-target.js.map +1 -1
- package/dist/commands/deploy-command/version-command.d.ts.map +1 -1
- package/dist/commands/deploy-command/version-command.js +138 -12
- package/dist/commands/deploy-command/version-command.js.map +1 -1
- package/dist/commands/test-command/test-command.d.ts.map +1 -1
- package/dist/commands/test-command/test-command.js +23 -11
- package/dist/commands/test-command/test-command.js.map +1 -1
- package/dist/nevermore.js +17 -0
- package/dist/nevermore.js.map +1 -1
- package/dist/utils/batch/changed-packages-utils.d.ts +1 -1
- package/dist/utils/batch/changed-packages-utils.d.ts.map +1 -1
- package/dist/utils/batch/changed-packages-utils.js +1 -1
- package/dist/utils/batch/changed-packages-utils.js.map +1 -1
- package/dist/utils/build/base-place-resolver-factory.d.ts +25 -0
- package/dist/utils/build/base-place-resolver-factory.d.ts.map +1 -0
- package/dist/utils/build/base-place-resolver-factory.js +40 -0
- package/dist/utils/build/base-place-resolver-factory.js.map +1 -0
- package/dist/utils/build/build.d.ts +13 -2
- package/dist/utils/build/build.d.ts.map +1 -1
- package/dist/utils/build/build.js.map +1 -1
- package/dist/utils/build/upload.d.ts +1 -1
- package/dist/utils/build/upload.d.ts.map +1 -1
- package/dist/utils/deploy/deploy-metadata.d.ts +1 -1
- package/dist/utils/deploy/deploy-metadata.d.ts.map +1 -1
- package/dist/utils/job-context/base-job-context.d.ts +3 -1
- package/dist/utils/job-context/base-job-context.d.ts.map +1 -1
- package/dist/utils/job-context/base-job-context.js +45 -6
- package/dist/utils/job-context/base-job-context.js.map +1 -1
- package/dist/utils/job-context/batch-script-job-context.d.ts +6 -0
- package/dist/utils/job-context/batch-script-job-context.d.ts.map +1 -1
- package/dist/utils/job-context/batch-script-job-context.js +13 -0
- package/dist/utils/job-context/batch-script-job-context.js.map +1 -1
- package/dist/utils/job-context/cloud-job-context.d.ts +2 -1
- package/dist/utils/job-context/cloud-job-context.d.ts.map +1 -1
- package/dist/utils/job-context/cloud-job-context.js +2 -2
- package/dist/utils/job-context/cloud-job-context.js.map +1 -1
- package/dist/utils/job-context/local-job-context.d.ts +2 -1
- package/dist/utils/job-context/local-job-context.d.ts.map +1 -1
- package/dist/utils/job-context/local-job-context.js +2 -2
- package/dist/utils/job-context/local-job-context.js.map +1 -1
- package/dist/utils/open-cloud/open-cloud-client.d.ts +20 -2
- package/dist/utils/open-cloud/open-cloud-client.d.ts.map +1 -1
- package/dist/utils/open-cloud/open-cloud-client.js +78 -21
- package/dist/utils/open-cloud/open-cloud-client.js.map +1 -1
- package/dist/utils/open-cloud/open-cloud-client.test.js +89 -12
- package/dist/utils/open-cloud/open-cloud-client.test.js.map +1 -1
- package/dist/utils/testing/parsers/batch-log-parser.d.ts +13 -5
- package/dist/utils/testing/parsers/batch-log-parser.d.ts.map +1 -1
- package/dist/utils/testing/parsers/batch-log-parser.js +114 -68
- package/dist/utils/testing/parsers/batch-log-parser.js.map +1 -1
- package/dist/utils/testing/parsers/batch-log-parser.test.js +57 -5
- package/dist/utils/testing/parsers/batch-log-parser.test.js.map +1 -1
- package/dist/utils/testing/parsers/traceback-parser.d.ts +31 -0
- package/dist/utils/testing/parsers/traceback-parser.d.ts.map +1 -0
- package/dist/utils/testing/parsers/traceback-parser.js +91 -0
- package/dist/utils/testing/parsers/traceback-parser.js.map +1 -0
- package/dist/utils/testing/parsers/traceback-parser.test.d.ts +2 -0
- package/dist/utils/testing/parsers/traceback-parser.test.d.ts.map +1 -0
- package/dist/utils/testing/parsers/traceback-parser.test.js +45 -0
- package/dist/utils/testing/parsers/traceback-parser.test.js.map +1 -0
- package/dist/utils/testing/runner/combined-project-generator.d.ts +1 -1
- package/dist/utils/testing/runner/combined-project-generator.d.ts.map +1 -1
- package/dist/utils/testing/runner/test-runner.d.ts +9 -1
- package/dist/utils/testing/runner/test-runner.d.ts.map +1 -1
- package/dist/utils/testing/runner/test-runner.js +28 -3
- package/dist/utils/testing/runner/test-runner.js.map +1 -1
- package/dist/utils/testing/runner/test-runner.test.d.ts +2 -0
- package/dist/utils/testing/runner/test-runner.test.d.ts.map +1 -0
- package/dist/utils/testing/runner/test-runner.test.js +18 -0
- package/dist/utils/testing/runner/test-runner.test.js.map +1 -0
- package/dist/utils/testing/test-log-parser.d.ts +32 -1
- package/dist/utils/testing/test-log-parser.d.ts.map +1 -1
- package/dist/utils/testing/test-log-parser.js +53 -9
- package/dist/utils/testing/test-log-parser.js.map +1 -1
- package/dist/utils/testing/test-log-parser.test.d.ts +2 -0
- package/dist/utils/testing/test-log-parser.test.d.ts.map +1 -0
- package/dist/utils/testing/test-log-parser.test.js +56 -0
- package/dist/utils/testing/test-log-parser.test.js.map +1 -0
- package/dist/utils/watch/github-context.d.ts +50 -0
- package/dist/utils/watch/github-context.d.ts.map +1 -0
- package/dist/utils/watch/github-context.js +125 -0
- package/dist/utils/watch/github-context.js.map +1 -0
- package/dist/utils/watch/github-context.test.d.ts +2 -0
- package/dist/utils/watch/github-context.test.d.ts.map +1 -0
- package/dist/utils/watch/github-context.test.js +112 -0
- package/dist/utils/watch/github-context.test.js.map +1 -0
- package/dist/utils/watch/http-watch-registry.d.ts +40 -0
- package/dist/utils/watch/http-watch-registry.d.ts.map +1 -0
- package/dist/utils/watch/http-watch-registry.js +262 -0
- package/dist/utils/watch/http-watch-registry.js.map +1 -0
- package/dist/utils/watch/http-watch-registry.test.d.ts +2 -0
- package/dist/utils/watch/http-watch-registry.test.d.ts.map +1 -0
- package/dist/utils/watch/http-watch-registry.test.js +211 -0
- package/dist/utils/watch/http-watch-registry.test.js.map +1 -0
- package/dist/utils/watch/local-watch-loop.d.ts +50 -0
- package/dist/utils/watch/local-watch-loop.d.ts.map +1 -0
- package/dist/utils/watch/local-watch-loop.js +103 -0
- package/dist/utils/watch/local-watch-loop.js.map +1 -0
- package/dist/utils/watch/local-watch-loop.test.d.ts +2 -0
- package/dist/utils/watch/local-watch-loop.test.d.ts.map +1 -0
- package/dist/utils/watch/local-watch-loop.test.js +170 -0
- package/dist/utils/watch/local-watch-loop.test.js.map +1 -0
- package/dist/utils/watch/register-notify-watches.d.ts +41 -0
- package/dist/utils/watch/register-notify-watches.d.ts.map +1 -0
- package/dist/utils/watch/register-notify-watches.js +159 -0
- package/dist/utils/watch/register-notify-watches.js.map +1 -0
- package/dist/utils/watch/register-notify-watches.test.d.ts +2 -0
- package/dist/utils/watch/register-notify-watches.test.d.ts.map +1 -0
- package/dist/utils/watch/register-notify-watches.test.js +225 -0
- package/dist/utils/watch/register-notify-watches.test.js.map +1 -0
- package/dist/utils/watch/register-watches.d.ts +68 -0
- package/dist/utils/watch/register-watches.d.ts.map +1 -0
- package/dist/utils/watch/register-watches.js +221 -0
- package/dist/utils/watch/register-watches.js.map +1 -0
- package/dist/utils/watch/register-watches.test.d.ts +2 -0
- package/dist/utils/watch/register-watches.test.d.ts.map +1 -0
- package/dist/utils/watch/register-watches.test.js +576 -0
- package/dist/utils/watch/register-watches.test.js.map +1 -0
- package/dist/utils/watch/stream-watch-loop.d.ts +54 -0
- package/dist/utils/watch/stream-watch-loop.d.ts.map +1 -0
- package/dist/utils/watch/stream-watch-loop.js +282 -0
- package/dist/utils/watch/stream-watch-loop.js.map +1 -0
- package/dist/utils/watch/stream-watch-loop.test.d.ts +2 -0
- package/dist/utils/watch/stream-watch-loop.test.d.ts.map +1 -0
- package/dist/utils/watch/stream-watch-loop.test.js +392 -0
- package/dist/utils/watch/stream-watch-loop.test.js.map +1 -0
- package/dist/utils/watch/websocket-watch-stream.d.ts +25 -0
- package/dist/utils/watch/websocket-watch-stream.d.ts.map +1 -0
- package/dist/utils/watch/websocket-watch-stream.js +306 -0
- package/dist/utils/watch/websocket-watch-stream.js.map +1 -0
- package/dist/utils/watch/websocket-watch-stream.test.d.ts +2 -0
- package/dist/utils/watch/websocket-watch-stream.test.d.ts.map +1 -0
- package/dist/utils/watch/websocket-watch-stream.test.js +475 -0
- package/dist/utils/watch/websocket-watch-stream.test.js.map +1 -0
- package/package.json +7 -4
- package/src/args/global-args.ts +13 -0
- package/src/commands/batch-command/batch-deploy-command.ts +105 -1
- package/src/commands/batch-command/batch-test-command.ts +86 -60
- package/src/commands/deploy-command/deploy-init.ts +1 -1
- package/src/commands/deploy-command/index.ts +327 -32
- package/src/commands/deploy-command/select-target.ts +1 -1
- package/src/commands/deploy-command/version-command.ts +215 -21
- package/src/commands/test-command/test-command.ts +31 -22
- package/src/nevermore.ts +19 -0
- package/src/utils/batch/changed-packages-utils.ts +1 -1
- package/src/utils/build/base-place-resolver-factory.ts +49 -0
- package/src/utils/build/build.ts +13 -2
- package/src/utils/build/upload.ts +1 -1
- package/src/utils/deploy/deploy-metadata.ts +1 -1
- package/src/utils/job-context/base-job-context.ts +68 -6
- package/src/utils/job-context/batch-script-job-context.ts +18 -0
- package/src/utils/job-context/cloud-job-context.ts +7 -2
- package/src/utils/job-context/local-job-context.ts +7 -2
- package/src/utils/open-cloud/open-cloud-client.test.ts +133 -14
- package/src/utils/open-cloud/open-cloud-client.ts +131 -35
- package/src/utils/testing/parsers/batch-log-parser.test.ts +70 -5
- package/src/utils/testing/parsers/batch-log-parser.ts +141 -80
- package/src/utils/testing/parsers/traceback-parser.test.ts +64 -0
- package/src/utils/testing/parsers/traceback-parser.ts +122 -0
- package/src/utils/testing/runner/combined-project-generator.ts +1 -1
- package/src/utils/testing/runner/test-runner.test.ts +29 -0
- package/src/utils/testing/runner/test-runner.ts +36 -4
- package/src/utils/testing/test-log-parser.test.ts +70 -0
- package/src/utils/testing/test-log-parser.ts +80 -10
- package/src/utils/watch/github-context.test.ts +154 -0
- package/src/utils/watch/github-context.ts +184 -0
- package/src/utils/watch/http-watch-registry.test.ts +330 -0
- package/src/utils/watch/http-watch-registry.ts +341 -0
- package/src/utils/watch/local-watch-loop.test.ts +197 -0
- package/src/utils/watch/local-watch-loop.ts +190 -0
- package/src/utils/watch/register-notify-watches.test.ts +282 -0
- package/src/utils/watch/register-notify-watches.ts +226 -0
- package/src/utils/watch/register-watches.test.ts +696 -0
- package/src/utils/watch/register-watches.ts +369 -0
- package/src/utils/watch/stream-watch-loop.test.ts +625 -0
- package/src/utils/watch/stream-watch-loop.ts +411 -0
- package/src/utils/watch/websocket-watch-stream.test.ts +581 -0
- package/src/utils/watch/websocket-watch-stream.ts +403 -0
- package/tsconfig.json +19 -6
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/build/deploy-config.d.ts +0 -71
- package/dist/utils/build/deploy-config.d.ts.map +0 -1
- package/dist/utils/build/deploy-config.js +0 -164
- package/dist/utils/build/deploy-config.js.map +0 -1
- package/dist/utils/build/deploy-config.test.d.ts +0 -2
- package/dist/utils/build/deploy-config.test.d.ts.map +0 -1
- package/dist/utils/build/deploy-config.test.js +0 -126
- package/dist/utils/build/deploy-config.test.js.map +0 -1
- package/src/utils/build/deploy-config.test.ts +0 -149
- 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 @@
|
|
|
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":"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"}
|
|
@@ -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":"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"}
|
|
@@ -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":""}
|