@hypequery/cli 1.16.0 → 1.16.1
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/README.md +4 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -2
- package/dist/commands/login.d.ts +1 -4
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +2 -22
- package/dist/utils/deployment-bundle.d.ts +1 -0
- package/dist/utils/deployment-bundle.d.ts.map +1 -1
- package/dist/utils/deployment-source-snapshot.d.ts.map +1 -1
- package/dist/utils/deployment-source-snapshot.js +6 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -253,9 +253,10 @@ Options:
|
|
|
253
253
|
|
|
254
254
|
### Cloud deployment targets in CI
|
|
255
255
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
environment
|
|
256
|
+
Login selects a stable Cloud deployment target. The deployment itself captures
|
|
257
|
+
the checked-out Git branch, commit, and dirty state as source provenance; none
|
|
258
|
+
of those values select or create an environment. Select the destination
|
|
259
|
+
explicitly when the same branch or commit deploys to more than one environment:
|
|
259
260
|
|
|
260
261
|
```bash
|
|
261
262
|
npx hypequery login --environment development
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0BpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAa9B,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;EAKpE;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0BpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AAa9B,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;EAKpE;AA+ND,OAAO,EAAE,OAAO,EAAE,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -34,8 +34,7 @@ program
|
|
|
34
34
|
.command('login')
|
|
35
35
|
.description('Authorize this machine with Hypequery Cloud')
|
|
36
36
|
.option('--cloud-url <url>', 'Cloud origin (or HYPEQUERY_CLOUD_URL)')
|
|
37
|
-
.option('--environment <environment>', 'Stable deployment target
|
|
38
|
-
.option('--no-branch', 'Do not send the current Git branch (or HYPEQUERY_CLI_SEND_BRANCH=0)')
|
|
37
|
+
.option('--environment <environment>', 'Stable deployment target')
|
|
39
38
|
.action(runCommand(async (options) => {
|
|
40
39
|
await loginCommand(options);
|
|
41
40
|
}));
|
package/dist/commands/login.d.ts
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { deleteCloudCredential, loadCloudCredential, saveCloudCredential } from '../utils/cloud-credential-store.js';
|
|
2
2
|
export interface LoginOptions {
|
|
3
3
|
readonly cloudUrl?: string;
|
|
4
|
-
/**
|
|
5
|
-
readonly branch?: boolean;
|
|
6
|
-
/** Stable Cloud deployment target. This always takes precedence over Git branch context. */
|
|
4
|
+
/** Stable Cloud deployment target. */
|
|
7
5
|
readonly environment?: string;
|
|
8
6
|
}
|
|
9
7
|
export interface LoginDependencies {
|
|
10
8
|
readonly fetch?: typeof fetch;
|
|
11
|
-
readonly getGitBranch?: () => Promise<string | null>;
|
|
12
9
|
readonly openBrowser?: (url: string) => Promise<unknown>;
|
|
13
10
|
readonly now?: () => number;
|
|
14
11
|
readonly requestTimeoutMs?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,qBAAqB,EACrB,mBAAmB,EAGnB,mBAAmB,EAEpB,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAMA,OAAO,EAEL,qBAAqB,EACrB,mBAAmB,EAGnB,mBAAmB,EAEpB,MAAM,oCAAoC,CAAC;AAgB5C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,sCAAsC;IACtC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAC9B,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,mBAAmB,CAAC;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAC9B,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,mBAAmB,CAAC;IACrD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,qBAAqB,CAAC;IACzD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAsJD,wBAAsB,YAAY,CAChC,OAAO,GAAE,YAAiB,EAC1B,YAAY,GAAE,iBAAsB,iBAyErC;AAED,wBAAsB,aAAa,CAAC,YAAY,GAAE,kBAAuB,iBAoCxE"}
|
package/dist/commands/login.js
CHANGED
|
@@ -3,7 +3,6 @@ import { createServer } from 'node:http';
|
|
|
3
3
|
import open from 'open';
|
|
4
4
|
import { validateProtocolDeploymentReleaseTarget } from '@hypequery/protocol';
|
|
5
5
|
import { CLOUD_DEPLOYMENT_SCOPE, deleteCloudCredential, loadCloudCredential, normalizeCloudDeploymentEndpoint, normalizeCloudOrigin, saveCloudCredential, } from '../utils/cloud-credential-store.js';
|
|
6
|
-
import { currentGitBranch } from '../utils/git-branch.js';
|
|
7
6
|
import { logger } from '../utils/logger.js';
|
|
8
7
|
const DEFAULT_CLOUD_URL = 'https://cloud.hypequery.com';
|
|
9
8
|
const LOGIN_TIMEOUT_MS = 5 * 60_000;
|
|
@@ -17,17 +16,6 @@ const MAX_TOKEN_LIFETIME_MS = 13 * 60 * 60_000;
|
|
|
17
16
|
// CLI the day Cloud rotates its token format.
|
|
18
17
|
const TOKEN_PATTERN = /^hqdp_[A-Za-z0-9_-]{16,512}$/;
|
|
19
18
|
const utf8Decoder = new TextDecoder('utf-8', { fatal: true });
|
|
20
|
-
/**
|
|
21
|
-
* Branch names carry internal detail (customer names, embargoed identifiers),
|
|
22
|
-
* so both an explicit `--no-branch` and the environment variable suppress the
|
|
23
|
-
* parameter. The flag wins because it is the more specific signal.
|
|
24
|
-
*/
|
|
25
|
-
function branchContextEnabled(options) {
|
|
26
|
-
if (options.branch === false)
|
|
27
|
-
return false;
|
|
28
|
-
const configured = process.env.HYPEQUERY_CLI_SEND_BRANCH?.trim().toLowerCase();
|
|
29
|
-
return configured !== '0' && configured !== 'false' && configured !== 'no';
|
|
30
|
-
}
|
|
31
19
|
function callbackHtml(success) {
|
|
32
20
|
const title = success ? 'CLI authorized' : 'Authorization failed';
|
|
33
21
|
const message = success
|
|
@@ -174,12 +162,6 @@ export async function loginCommand(options = {}, dependencies = {}) {
|
|
|
174
162
|
const state = randomBytes(24).toString('base64url');
|
|
175
163
|
const verifier = randomBytes(32).toString('base64url');
|
|
176
164
|
const challenge = createHash('sha256').update(verifier).digest('base64url');
|
|
177
|
-
// Resolve branch context before the loopback listener opens: shelling out to
|
|
178
|
-
// git should not hold a server socket, and a caller-supplied resolver that
|
|
179
|
-
// rejects must not leak one.
|
|
180
|
-
const branch = branchContextEnabled(options)
|
|
181
|
-
? await (dependencies.getGitBranch ?? currentGitBranch)()
|
|
182
|
-
: null;
|
|
183
165
|
let environment;
|
|
184
166
|
if (options.environment !== undefined) {
|
|
185
167
|
try {
|
|
@@ -198,8 +180,6 @@ export async function loginCommand(options = {}, dependencies = {}) {
|
|
|
198
180
|
authorizeUrl.searchParams.set('code_challenge', challenge);
|
|
199
181
|
authorizeUrl.searchParams.set('code_challenge_method', 'S256');
|
|
200
182
|
authorizeUrl.searchParams.set('state', state);
|
|
201
|
-
if (branch)
|
|
202
|
-
authorizeUrl.searchParams.set('branch', branch);
|
|
203
183
|
if (environment)
|
|
204
184
|
authorizeUrl.searchParams.set('environment', environment);
|
|
205
185
|
try {
|
|
@@ -229,8 +209,8 @@ export async function loginCommand(options = {}, dependencies = {}) {
|
|
|
229
209
|
const credential = tokenResponse(body, origin, (dependencies.now ?? Date.now)());
|
|
230
210
|
await (dependencies.saveCredential ?? saveCloudCredential)(credential);
|
|
231
211
|
logger.success('Logged in to Hypequery Cloud');
|
|
232
|
-
// Cloud resolves the target,
|
|
233
|
-
//
|
|
212
|
+
// Cloud resolves the target, so print what was actually issued rather than
|
|
213
|
+
// what was requested.
|
|
234
214
|
if (credential.target) {
|
|
235
215
|
logger.info(`Deployments target ${credential.target.project} / ${credential.target.environment}`);
|
|
236
216
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployment-bundle.d.ts","sourceRoot":"","sources":["../../src/utils/deployment-bundle.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,KAAK,kCAAkC,EACvC,KAAK,gCAAgC,EACrC,KAAK,0BAA0B,EAChC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAGtE,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,GACvB,CAAC;AACF,YAAY,EAAE,wBAAwB,EAAE,CAAC;AAEzC,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAClB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"deployment-bundle.d.ts","sourceRoot":"","sources":["../../src/utils/deployment-bundle.ts"],"names":[],"mappings":"AAYA,OAAO,EAGL,KAAK,kCAAkC,EACvC,KAAK,gCAAgC,EACrC,KAAK,0BAA0B,EAChC,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAGtE,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,GACvB,CAAC;AACF,YAAY,EAAE,wBAAwB,EAAE,CAAC;AAEzC,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,SAAS,0BAA0B,EAAE,CAAC;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAClB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,gCAAgC,CAAC;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,0BAA0B,CAAC;CAC/C;AA0ID,wBAAsB,qBAAqB,CACzC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,kCAAkC,EAC5C,YAAY,EAAE,SAAS,2BAA2B,EAAE,EACpD,cAAc,CAAC,EAAE,8BAA8B,GAC9C,OAAO,CAAC,uBAAuB,CAAC,CA+FlC;AAoCD,wBAAsB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAMrF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deployment-source-snapshot.d.ts","sourceRoot":"","sources":["../../src/utils/deployment-source-snapshot.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,8BAA8B,EAC/B,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"deployment-source-snapshot.d.ts","sourceRoot":"","sources":["../../src/utils/deployment-source-snapshot.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,8BAA8B,EAC/B,MAAM,wBAAwB,CAAC;AA0EhC,wBAAsB,+BAA+B,CACnD,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,8BAA8B,CAAC,CAkDzC"}
|
|
@@ -3,6 +3,7 @@ import { constants, lstat, open, realpath } from 'node:fs/promises';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { DEFAULT_PROTOCOL_DEPLOYMENT_BUNDLE_LIMITS, } from '@hypequery/protocol';
|
|
5
5
|
import { build } from 'esbuild';
|
|
6
|
+
import { currentGitBranch } from './git-branch.js';
|
|
6
7
|
import { findNearestTsconfig } from './load-api.js';
|
|
7
8
|
function portableProjectPath(projectRoot, absolutePath) {
|
|
8
9
|
const relative = path.relative(projectRoot, absolutePath);
|
|
@@ -47,7 +48,10 @@ function gitOutput(projectRoot, arguments_) {
|
|
|
47
48
|
});
|
|
48
49
|
}
|
|
49
50
|
async function sourceRevision(projectRoot) {
|
|
50
|
-
const commit = await
|
|
51
|
+
const [commit, branch] = await Promise.all([
|
|
52
|
+
gitOutput(projectRoot, ['rev-parse', 'HEAD']),
|
|
53
|
+
currentGitBranch(projectRoot),
|
|
54
|
+
]);
|
|
51
55
|
if (!commit || !/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/.test(commit))
|
|
52
56
|
return undefined;
|
|
53
57
|
const status = await gitOutput(projectRoot, ['status', '--porcelain', '--untracked-files=all']);
|
|
@@ -57,6 +61,7 @@ async function sourceRevision(projectRoot) {
|
|
|
57
61
|
kind: 'git',
|
|
58
62
|
commit,
|
|
59
63
|
dirty: status.length > 0,
|
|
64
|
+
...(branch ? { branch } : {}),
|
|
60
65
|
});
|
|
61
66
|
}
|
|
62
67
|
export async function captureDeploymentSourceSnapshot(apiPath) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypequery/cli",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.1",
|
|
4
4
|
"description": "Command-line interface for hypequery",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"open": "^10.0.0",
|
|
20
20
|
"ora": "^8.0.1",
|
|
21
21
|
"prompts": "^2.4.2",
|
|
22
|
-
"@hypequery/deployment": "0.7.
|
|
23
|
-
"@hypequery/protocol": "0.10.
|
|
22
|
+
"@hypequery/deployment": "0.7.1",
|
|
23
|
+
"@hypequery/protocol": "0.10.1"
|
|
24
24
|
},
|
|
25
25
|
"optionalDependencies": {
|
|
26
26
|
"@napi-rs/keyring": "1.3.0"
|