@hypequery/cli 1.15.0 → 1.16.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/README.md CHANGED
@@ -251,6 +251,33 @@ Options:
251
251
 
252
252
  ## Non-interactive Setup
253
253
 
254
+ ### Cloud deployment targets in CI
255
+
256
+ Git branch context is only a default for interactive login. Select a stable
257
+ target explicitly when the same branch or commit deploys to more than one
258
+ environment:
259
+
260
+ ```bash
261
+ npx hypequery login --environment development
262
+ ```
263
+
264
+ For CI, create a target-scoped API key in Cloud for each environment and store
265
+ it as a separate secret. The explicit release target and its matching key make
266
+ the destination independent of the source branch:
267
+
268
+ ```bash
269
+ HYPEQUERY_API_TOKEN="$HYPEQUERY_DEV_TOKEN" npx hypequery deploy analytics/api.ts \
270
+ --project acme:analytics \
271
+ --environment development
272
+
273
+ HYPEQUERY_API_TOKEN="$HYPEQUERY_PROD_TOKEN" npx hypequery deploy analytics/api.ts \
274
+ --project acme:analytics \
275
+ --environment production
276
+ ```
277
+
278
+ Set `HYPEQUERY_DEPLOYMENT_ENDPOINT` for both jobs. A key is scoped to one target,
279
+ so a production key cannot submit a development release or vice versa.
280
+
254
281
  For ClickHouse, `hypequery init --no-interactive` reads:
255
282
 
256
283
  - `CLICKHOUSE_URL` or deprecated `CLICKHOUSE_HOST`
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;AA+ND,OAAO,EAAE,OAAO,EAAE,CAAC"}
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;AAgOD,OAAO,EAAE,OAAO,EAAE,CAAC"}
package/dist/cli.js CHANGED
@@ -34,6 +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; takes precedence over the Git branch')
37
38
  .option('--no-branch', 'Do not send the current Git branch (or HYPEQUERY_CLI_SEND_BRANCH=0)')
38
39
  .action(runCommand(async (options) => {
39
40
  await loginCommand(options);
@@ -3,6 +3,8 @@ export interface LoginOptions {
3
3
  readonly cloudUrl?: string;
4
4
  /** Commander sets this to false for `--no-branch`. */
5
5
  readonly branch?: boolean;
6
+ /** Stable Cloud deployment target. This always takes precedence over Git branch context. */
7
+ readonly environment?: string;
6
8
  }
7
9
  export interface LoginDependencies {
8
10
  readonly fetch?: typeof fetch;
@@ -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;AAiB5C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IAC9B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACrD,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;AAaD,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,iBAkErC;AAED,wBAAsB,aAAa,CAAC,YAAY,GAAE,kBAAuB,iBAoCxE"}
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;AAiB5C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,4FAA4F;IAC5F,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,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACrD,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;AAaD,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,iBAgFrC;AAED,wBAAsB,aAAa,CAAC,YAAY,GAAE,kBAAuB,iBAoCxE"}
@@ -180,6 +180,18 @@ export async function loginCommand(options = {}, dependencies = {}) {
180
180
  const branch = branchContextEnabled(options)
181
181
  ? await (dependencies.getGitBranch ?? currentGitBranch)()
182
182
  : null;
183
+ let environment;
184
+ if (options.environment !== undefined) {
185
+ try {
186
+ environment = validateProtocolDeploymentReleaseTarget({
187
+ project: 'target',
188
+ environment: options.environment,
189
+ }).environment;
190
+ }
191
+ catch {
192
+ throw new Error('Invalid deployment environment. Use letters, numbers, dots, underscores, colons, or hyphens.');
193
+ }
194
+ }
183
195
  const callback = await callbackServer(state, dependencies.timeoutMs ?? LOGIN_TIMEOUT_MS);
184
196
  const authorizeUrl = new URL('/cli/authorize', origin);
185
197
  authorizeUrl.searchParams.set('redirect_uri', callback.redirectUri);
@@ -188,6 +200,8 @@ export async function loginCommand(options = {}, dependencies = {}) {
188
200
  authorizeUrl.searchParams.set('state', state);
189
201
  if (branch)
190
202
  authorizeUrl.searchParams.set('branch', branch);
203
+ if (environment)
204
+ authorizeUrl.searchParams.set('environment', environment);
191
205
  try {
192
206
  logger.info('Opening your browser to authorize Hypequery CLI…');
193
207
  await (dependencies.openBrowser ?? open)(authorizeUrl.toString());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hypequery/cli",
3
- "version": "1.15.0",
3
+ "version": "1.16.0",
4
4
  "description": "Command-line interface for hypequery",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",