@quantum-hub/qhubctl 1.17.0 → 1.19.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.
@@ -103,8 +103,8 @@ async function selectExistingDatapool(client) {
103
103
  const selection = await input({
104
104
  message: `Select a data pool (1-${dataPools.length}) or enter the ID directly:`,
105
105
  });
106
- const index = parseInt(selection, 10);
107
- if (!isNaN(index) && index >= 1 && index <= dataPools.length) {
106
+ const index = Number.parseInt(selection, 10);
107
+ if (!Number.isNaN(index) && index >= 1 && index <= dataPools.length) {
108
108
  return dataPools[index - 1].id;
109
109
  }
110
110
  return selection;
@@ -1,8 +1,7 @@
1
1
  import { Command } from 'commander';
2
2
  import { spinner } from '../lib/output.js';
3
- import { configDir } from '../model/command.js';
3
+ import { configDir, getUserConfig } from '../model/command.js';
4
4
  import { writeUserConfig } from '../service/user-config-service.js';
5
- import { getUserConfig } from '../model/command.js';
6
5
  const EXAMPLES = `
7
6
  Examples:
8
7
  $ qhubctl logout`;
@@ -151,13 +151,13 @@ async function generateFromCode(entrypoint) {
151
151
  catch {
152
152
  warn(`Could not load qhub.json configuration. Using default title: ${title}`);
153
153
  }
154
- const safeEntrypoint = entrypoint.replace(/"/g, '\\"');
155
- const safeTitle = title.replace(/"/g, '\\"');
156
- const safeDescription = description ? description.replace(/"/g, '\\"') : 'None';
157
- const pySnippet = `from qhub.commons.openapi.generator import generate_openapi; generate_openapi(entrypoint='${safeEntrypoint}', title='${safeTitle}', description=${safeDescription === 'None' ? 'None' : `'${safeDescription}'`})`;
158
- const command = `uv run --no-sync --project ${process.cwd()} python -c "${pySnippet}"`;
154
+ const pySnippet = 'import sys; from qhub.commons.openapi.generator import generate_openapi; ' +
155
+ 'generate_openapi(entrypoint=sys.argv[1], title=sys.argv[2], description=sys.argv[3] or None)';
159
156
  try {
160
- const result = await executeAsyncCommand(command);
157
+ const result = await executeAsyncCommand('uv', [
158
+ 'run', '--no-sync', '--project', process.cwd(),
159
+ 'python', '-c', pySnippet, entrypoint, title, description ?? '',
160
+ ]);
161
161
  const { stdout: out } = validateCommandResult(result);
162
162
  return out;
163
163
  }
@@ -4,5 +4,5 @@ export interface RunCommandOptions {
4
4
  tag: string[];
5
5
  storeInput: boolean;
6
6
  }
7
- export declare function buildCreateJobRequest(serviceId: string, input: Record<string, never> | undefined, opts: RunCommandOptions): HubPlatform.CreateServiceJobRequest;
7
+ export declare function buildCreateJobRequest(serviceId: string, input: HubPlatform.JsonNode | undefined, opts: RunCommandOptions): HubPlatform.CreateServiceJobRequest;
8
8
  export declare const runCommand: Command;
@@ -21,7 +21,14 @@ export const setContextCommand = new Command('set-context')
21
21
  .action(async (contextId) => {
22
22
  const userConfig = await requireAuth();
23
23
  const quantumHubService = new QuantumHubService(userConfig);
24
- if (!contextId) {
24
+ if (contextId) {
25
+ const accounts = await quantumHubService.getAccounts();
26
+ const selectedContext = accounts.find(account => account.id === contextId);
27
+ if (!selectedContext) {
28
+ error(`Context with id "${contextId}" not found.`);
29
+ }
30
+ }
31
+ else {
25
32
  const spin = spinner('Loading available contexts');
26
33
  const accounts = await quantumHubService.getAccounts();
27
34
  spin.succeed('Contexts loaded');
@@ -32,13 +39,6 @@ export const setContextCommand = new Command('set-context')
32
39
  });
33
40
  contextId = response.id;
34
41
  }
35
- else {
36
- const accounts = await quantumHubService.getAccounts();
37
- const selectedContext = accounts.find(account => account.id === contextId);
38
- if (!selectedContext) {
39
- error(`Context with id "${contextId}" not found.`);
40
- }
41
- }
42
42
  const accounts = await quantumHubService.getAccounts();
43
43
  const selectedContext = accounts.find(account => account.id === contextId);
44
44
  if (!selectedContext) {
@@ -34,8 +34,7 @@ async function buildServiceJob(qhubService, service, silentMode) {
34
34
  if (!silentMode) {
35
35
  if (buildJob.step !== currentStep) {
36
36
  if (buildJob.step === HubPlatform.BuildJobDto.Step.BuildImage) {
37
- if (!spin)
38
- spin = spinner('Building Image (1/2)');
37
+ spin ??= spinner('Building Image (1/2)');
39
38
  }
40
39
  else if (buildJob.step === HubPlatform.BuildJobDto.Step.PushImage) {
41
40
  if (spin) {
@@ -1,6 +1,4 @@
1
- import { StdioOptions } from "node:child_process";
2
- export declare const executeAsyncCommand: (command: string) => Promise<{
3
- stderr: string;
1
+ export declare const executeAsyncCommand: (file: string, args: string[]) => Promise<{
4
2
  stdout: string;
3
+ stderr: string;
5
4
  }>;
6
- export declare const executeCommand: (command: string, stdioOption?: StdioOptions) => void;
@@ -1,16 +1,4 @@
1
- import { exec, execSync } from "node:child_process";
2
- export const executeAsyncCommand = async (command) => {
3
- return new Promise((resolve, reject) => {
4
- exec(command, (error, stdout, stderr) => {
5
- if (error) {
6
- reject(error);
7
- }
8
- else {
9
- resolve({ stderr, stdout });
10
- }
11
- });
12
- });
13
- };
14
- export const executeCommand = (command, stdioOption) => {
15
- execSync(`${command}`, { stdio: stdioOption ?? 'inherit' });
16
- };
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ const execFileAsync = promisify(execFile);
4
+ export const executeAsyncCommand = (file, args) => execFileAsync(file, args);
package/dist/lib/fetch.js CHANGED
@@ -27,11 +27,11 @@ export const getErrorMessage = async (response) => {
27
27
  const httpStatus = response.status && response.statusText ? `${response.status} - ${response.statusText}` : response.status;
28
28
  // message is either in body.errorMessage, body.error or body.detail
29
29
  let errorMessage;
30
- if (body && body.errorMessage)
30
+ if (body?.errorMessage)
31
31
  errorMessage = body.errorMessage;
32
- if (!errorMessage && body && body.error)
32
+ if (!errorMessage && body?.error)
33
33
  errorMessage = body.error;
34
- if (!errorMessage && body && body.detail)
34
+ if (!errorMessage && body?.detail)
35
35
  errorMessage = body.detail;
36
36
  return errorMessage ? `${errorMessage} (${httpStatus})` : `${httpStatus}`;
37
37
  };
@@ -1,5 +1,5 @@
1
1
  import { type Ora } from 'ora';
2
- export type { Ora };
2
+ export type { Ora } from 'ora';
3
3
  /**
4
4
  * Output helpers — replaces oclif's `ux.*` surface.
5
5
  *
@@ -1,6 +1,5 @@
1
- import { configDir } from '../lib/config-dir.js';
2
1
  import UserConfig from './user-config.js';
3
- export { configDir };
2
+ export { configDir } from '../lib/config-dir.js';
4
3
  export declare function getUserConfig(): UserConfig;
5
4
  export declare function getContextDisplayString(userConfig: UserConfig): string;
6
5
  export declare function showCustomBasePathWarning(): void;
@@ -2,7 +2,7 @@ import { configDir } from '../lib/config-dir.js';
2
2
  import { stdout, warn } from '../lib/output.js';
3
3
  import AuthService from '../service/auth-service.js';
4
4
  import { readUserConfig, writeUserConfig } from '../service/user-config-service.js';
5
- export { configDir };
5
+ export { configDir } from '../lib/config-dir.js';
6
6
  export function getUserConfig() {
7
7
  return readUserConfig(configDir);
8
8
  }
@@ -12,9 +12,7 @@ export default class QuantumHubService extends CommandService {
12
12
  this.apiClient = new HubPlatformClient({
13
13
  apiKey,
14
14
  baseUrl: basePath,
15
- headers: {
16
- 'X-OrganizationId': organizationId,
17
- },
15
+ organizationId,
18
16
  });
19
17
  }
20
18
  async getAccounts() {
@@ -149,17 +147,15 @@ export default class QuantumHubService extends CommandService {
149
147
  await this.apiClient.services.updateServiceSummary(serviceId, { summary: serviceConfig.summary });
150
148
  }
151
149
  await this.apiClient.managedServices.updateManagedServiceResourceConfiguration(serviceId, {
152
- body: { type: 'cpu', amount: milliCpus, unit: 'm' },
150
+ type: 'cpu', amount: milliCpus, unit: 'm',
153
151
  });
154
152
  await this.apiClient.managedServices.updateManagedServiceResourceConfiguration(serviceId, {
155
- body: { type: 'memory', amount: memoryInMegabytes, unit: 'M' },
153
+ type: 'memory', amount: memoryInMegabytes, unit: 'M',
156
154
  });
157
155
  await this.apiClient.managedServices.updateManagedServiceResourceConfiguration(serviceId, {
158
- body: {
159
- type: 'gpu',
160
- amount: gpuCount,
161
- accelerator: gpuAccelerator
162
- },
156
+ type: 'gpu',
157
+ amount: gpuCount,
158
+ accelerator: gpuAccelerator,
163
159
  });
164
160
  if (openapi) {
165
161
  await this.apiClient.services.updateServiceOpenApi(serviceId, { file: openapi });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantum-hub/qhubctl",
3
- "version": "1.17.0",
3
+ "version": "1.19.0",
4
4
  "description": "Kipu Quantum Hub CLI",
5
5
  "author": "Kipu Quantum GmbH",
6
6
  "contributors": [
@@ -26,7 +26,7 @@
26
26
  ],
27
27
  "dependencies": {
28
28
  "@inquirer/prompts": "^8",
29
- "@quantum-hub/qhub-api": "^1",
29
+ "@quantum-hub/qhub-api": "^2",
30
30
  "adm-zip": "^0.5.17",
31
31
  "async-wait-until": "^2",
32
32
  "commander": "^14",