@quantum-hub/qhubctl 2.2.2-next.1 → 2.2.2

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 (74) hide show
  1. package/README.md +4 -2
  2. package/dist/commands/compress.d.ts +1 -1
  3. package/dist/commands/compress.js +15 -15
  4. package/dist/commands/datapool-upload.d.ts +1 -1
  5. package/dist/commands/datapool-upload.js +35 -35
  6. package/dist/commands/get-context.d.ts +1 -1
  7. package/dist/commands/get-context.js +5 -5
  8. package/dist/commands/init.d.ts +1 -1
  9. package/dist/commands/init.js +33 -29
  10. package/dist/commands/list-contexts.d.ts +1 -1
  11. package/dist/commands/list-contexts.js +21 -13
  12. package/dist/commands/login.d.ts +1 -1
  13. package/dist/commands/login.js +16 -16
  14. package/dist/commands/logout.d.ts +1 -1
  15. package/dist/commands/logout.js +10 -10
  16. package/dist/commands/openapi.d.ts +1 -1
  17. package/dist/commands/openapi.js +112 -94
  18. package/dist/commands/run.d.ts +2 -2
  19. package/dist/commands/run.js +37 -34
  20. package/dist/commands/serve.d.ts +1 -1
  21. package/dist/commands/serve.js +30 -19
  22. package/dist/commands/services-build-logs.d.ts +2 -2
  23. package/dist/commands/services-build-logs.js +26 -26
  24. package/dist/commands/services-build-status.d.ts +1 -1
  25. package/dist/commands/services-build-status.js +21 -21
  26. package/dist/commands/services-list.d.ts +1 -1
  27. package/dist/commands/services-list.js +20 -17
  28. package/dist/commands/set-context.d.ts +1 -1
  29. package/dist/commands/set-context.js +18 -16
  30. package/dist/commands/up.d.ts +1 -1
  31. package/dist/commands/up.js +50 -48
  32. package/dist/index.d.ts +1 -1
  33. package/dist/index.js +1 -1
  34. package/dist/lib/command.js +2 -2
  35. package/dist/lib/config-dir.js +3 -3
  36. package/dist/lib/debug.js +1 -1
  37. package/dist/lib/entrypoint-resolver.js +15 -15
  38. package/dist/lib/error.js +4 -4
  39. package/dist/lib/fetch.js +3 -1
  40. package/dist/lib/init-user-input.d.ts +1 -1
  41. package/dist/lib/init-user-input.js +28 -26
  42. package/dist/lib/output.d.ts +2 -2
  43. package/dist/lib/output.js +3 -3
  44. package/dist/lib/random-name.js +147 -147
  45. package/dist/lib/random-string.js +2 -2
  46. package/dist/lib/repository.js +5 -5
  47. package/dist/lib/stream-to-blob.d.ts +1 -1
  48. package/dist/lib/stream-to-blob.js +5 -5
  49. package/dist/lib/up/get-description.js +8 -8
  50. package/dist/lib/up/ignore.js +8 -8
  51. package/dist/lib/up/qhubignore-help.js +10 -10
  52. package/dist/lib/up/required-files.js +17 -12
  53. package/dist/lib/up/source.d.ts +2 -2
  54. package/dist/lib/up/source.js +7 -7
  55. package/dist/lib/up/zip.js +8 -8
  56. package/dist/main.js +3 -3
  57. package/dist/model/command.d.ts +2 -2
  58. package/dist/model/command.js +9 -9
  59. package/dist/model/managed-service-config.d.ts +1 -1
  60. package/dist/model/user-config.js +1 -1
  61. package/dist/program.d.ts +1 -1
  62. package/dist/program.js +24 -24
  63. package/dist/service/auth-service.d.ts +3 -3
  64. package/dist/service/auth-service.js +11 -9
  65. package/dist/service/command-service.d.ts +1 -1
  66. package/dist/service/quantum-hub-service.d.ts +3 -3
  67. package/dist/service/quantum-hub-service.js +34 -20
  68. package/dist/service/service-config-service.d.ts +1 -1
  69. package/dist/service/service-config-service.js +8 -8
  70. package/dist/service/user-config-service.d.ts +1 -1
  71. package/dist/service/user-config-service.js +7 -7
  72. package/dist/service/user-service.d.ts +2 -2
  73. package/dist/service/user-service.js +4 -4
  74. package/package.json +8 -2
@@ -1,22 +1,22 @@
1
- import { input } from '@inquirer/prompts';
2
- import { Command } from 'commander';
3
- import { error, spinner, stdout } from '../lib/output.js';
4
- import { requireAuth } from '../model/command.js';
5
- import QuantumHubService from '../service/quantum-hub-service.js';
6
- import { readServiceConfig } from '../service/service-config-service.js';
1
+ import { input } from "@inquirer/prompts";
2
+ import { Command } from "commander";
3
+ import { error, spinner, stdout } from "../lib/output.js";
4
+ import { requireAuth } from "../model/command.js";
5
+ import QuantumHubService from "../service/quantum-hub-service.js";
6
+ import { readServiceConfig } from "../service/service-config-service.js";
7
7
  const SEVERITY_COLUMN_WIDTH = 7;
8
- const COLUMN_GAP = ' ';
9
- const ANSI_RESET = '\x1b[0m';
8
+ const COLUMN_GAP = " ";
9
+ const ANSI_RESET = "\x1b[0m";
10
10
  const ANSI_BY_SEVERITY = {
11
- DEBUG: '\x1b[2m',
12
- WARNING: '\x1b[33m',
13
- ERROR: '\x1b[31m',
11
+ DEBUG: "\x1b[2m",
12
+ WARNING: "\x1b[33m",
13
+ ERROR: "\x1b[31m",
14
14
  };
15
15
  export function formatLogEntry(entry, opts) {
16
- const timestamp = entry.timestamp ?? '-';
17
- const severity = entry.severity ?? 'INFO';
18
- const message = entry.message ?? '';
19
- const paddedSeverity = severity.padEnd(SEVERITY_COLUMN_WIDTH, ' ');
16
+ const timestamp = entry.timestamp ?? "-";
17
+ const severity = entry.severity ?? "INFO";
18
+ const message = entry.message ?? "";
19
+ const paddedSeverity = severity.padEnd(SEVERITY_COLUMN_WIDTH, " ");
20
20
  const ansi = opts.isTTY ? ANSI_BY_SEVERITY[severity] : undefined;
21
21
  const severityCell = ansi ? `${ansi}${paddedSeverity}${ANSI_RESET}` : paddedSeverity;
22
22
  return `${timestamp}${COLUMN_GAP}${severityCell}${COLUMN_GAP}${message}`;
@@ -26,11 +26,11 @@ Examples:
26
26
  $ qhubctl services build-logs
27
27
  $ qhubctl services build-logs --id <serviceId>
28
28
  $ qhubctl services build-logs --id <serviceId> --json`;
29
- export const servicesBuildLogsCommand = new Command('build-logs')
30
- .description('Show the build logs of a service.')
31
- .option('--id <value>', 'The ID of the service (reads from qhub.json if omitted)')
32
- .option('--json', 'Output in JSON format', false)
33
- .addHelpText('after', EXAMPLES)
29
+ export const servicesBuildLogsCommand = new Command("build-logs")
30
+ .description("Show the build logs of a service.")
31
+ .option("--id <value>", "The ID of the service (reads from qhub.json if omitted)")
32
+ .option("--json", "Output in JSON format", false)
33
+ .addHelpText("after", EXAMPLES)
34
34
  .action(async (opts) => {
35
35
  const userConfig = await requireAuth({ printContext: !opts.json });
36
36
  const quantumHubService = new QuantumHubService(userConfig);
@@ -46,7 +46,7 @@ export const servicesBuildLogsCommand = new Command('build-logs')
46
46
  }
47
47
  if (!serviceId) {
48
48
  try {
49
- serviceId = await input({ message: 'Enter the service ID:' });
49
+ serviceId = await input({ message: "Enter the service ID:" });
50
50
  }
51
51
  catch {
52
52
  // user cancelled (Ctrl+C)
@@ -54,25 +54,25 @@ export const servicesBuildLogsCommand = new Command('build-logs')
54
54
  }
55
55
  }
56
56
  if (!serviceId?.trim()) {
57
- error('No service ID provided.');
57
+ error("No service ID provided.");
58
58
  }
59
- const spin = spinner('Loading build logs');
59
+ const spin = spinner("Loading build logs");
60
60
  let logs;
61
61
  try {
62
62
  logs = await quantumHubService.getBuildLogs(serviceId);
63
63
  }
64
64
  catch (err) {
65
- spin.fail('Failed to load build logs');
65
+ spin.fail("Failed to load build logs");
66
66
  error(err instanceof Error ? err.message : String(err));
67
67
  }
68
- spin.succeed('Build logs loaded');
68
+ spin.succeed("Build logs loaded");
69
69
  if (opts.json) {
70
70
  stdout(JSON.stringify(logs, null, 2));
71
71
  return;
72
72
  }
73
73
  if (logs.length === 0) {
74
74
  stdout();
75
- stdout('No build logs available.');
75
+ stdout("No build logs available.");
76
76
  stdout();
77
77
  return;
78
78
  }
@@ -1,2 +1,2 @@
1
- import { Command } from 'commander';
1
+ import { Command } from "commander";
2
2
  export declare const servicesBuildStatusCommand: Command;
@@ -1,19 +1,19 @@
1
- import { input } from '@inquirer/prompts';
2
- import { Command } from 'commander';
3
- import { error, spinner, stdout } from '../lib/output.js';
4
- import { requireAuth } from '../model/command.js';
5
- import QuantumHubService from '../service/quantum-hub-service.js';
6
- import { readServiceConfig } from '../service/service-config-service.js';
1
+ import { input } from "@inquirer/prompts";
2
+ import { Command } from "commander";
3
+ import { error, spinner, stdout } from "../lib/output.js";
4
+ import { requireAuth } from "../model/command.js";
5
+ import QuantumHubService from "../service/quantum-hub-service.js";
6
+ import { readServiceConfig } from "../service/service-config-service.js";
7
7
  const EXAMPLES = `
8
8
  Examples:
9
9
  $ qhubctl services build-status
10
10
  $ qhubctl services build-status --id <serviceId>
11
11
  $ qhubctl services build-status --id <serviceId> --json`;
12
- export const servicesBuildStatusCommand = new Command('build-status')
13
- .description('Show the build status of a service.')
14
- .option('--id <value>', 'The ID of the service (reads from qhub.json if omitted)')
15
- .option('--json', 'Output in JSON format', false)
16
- .addHelpText('after', EXAMPLES)
12
+ export const servicesBuildStatusCommand = new Command("build-status")
13
+ .description("Show the build status of a service.")
14
+ .option("--id <value>", "The ID of the service (reads from qhub.json if omitted)")
15
+ .option("--json", "Output in JSON format", false)
16
+ .addHelpText("after", EXAMPLES)
17
17
  .action(async (opts) => {
18
18
  const userConfig = await requireAuth({ printContext: !opts.json });
19
19
  const quantumHubService = new QuantumHubService(userConfig);
@@ -29,7 +29,7 @@ export const servicesBuildStatusCommand = new Command('build-status')
29
29
  }
30
30
  if (!serviceId) {
31
31
  try {
32
- serviceId = await input({ message: 'Enter the service ID:' });
32
+ serviceId = await input({ message: "Enter the service ID:" });
33
33
  }
34
34
  catch {
35
35
  // user cancelled (Ctrl+C)
@@ -37,31 +37,31 @@ export const servicesBuildStatusCommand = new Command('build-status')
37
37
  }
38
38
  }
39
39
  if (!serviceId?.trim()) {
40
- error('No service ID provided.');
40
+ error("No service ID provided.");
41
41
  }
42
- const spin = spinner('Loading build status');
42
+ const spin = spinner("Loading build status");
43
43
  let buildJob;
44
44
  try {
45
45
  buildJob = await quantumHubService.getBuildJob(serviceId);
46
46
  }
47
47
  catch (err) {
48
- spin.fail('Failed to load build status');
48
+ spin.fail("Failed to load build status");
49
49
  error(err instanceof Error ? err.message : String(err));
50
50
  }
51
- spin.succeed('Build status loaded');
51
+ spin.succeed("Build status loaded");
52
52
  if (opts.json) {
53
53
  stdout(JSON.stringify(buildJob, null, 2));
54
54
  return;
55
55
  }
56
56
  stdout();
57
57
  stdout(`Service ID: ${serviceId}`);
58
- stdout(`Status: ${buildJob.status ?? 'N/A'}`);
59
- stdout(`Step: ${buildJob.step ?? 'N/A'}`);
60
- stdout(`Started: ${buildJob.createdAt ?? 'N/A'}`);
61
- stdout(`Finished: ${buildJob.finishedAt ?? 'N/A'}`);
58
+ stdout(`Status: ${buildJob.status ?? "N/A"}`);
59
+ stdout(`Step: ${buildJob.step ?? "N/A"}`);
60
+ stdout(`Started: ${buildJob.createdAt ?? "N/A"}`);
61
+ stdout(`Finished: ${buildJob.finishedAt ?? "N/A"}`);
62
62
  if (buildJob.validationResult) {
63
63
  const v = buildJob.validationResult;
64
- stdout(`Validation: ${v.state ?? 'N/A'}`);
64
+ stdout(`Validation: ${v.state ?? "N/A"}`);
65
65
  if (v.summary) {
66
66
  stdout(` Summary: ${v.summary}`);
67
67
  }
@@ -1,2 +1,2 @@
1
- import { Command } from 'commander';
1
+ import { Command } from "commander";
2
2
  export declare const servicesListCommand: Command;
@@ -1,8 +1,8 @@
1
- import { Command } from 'commander';
2
- import Table from 'tty-table';
3
- import { spinner, stdout, warn } from '../lib/output.js';
4
- import { requireAuth } from '../model/command.js';
5
- import QuantumHubService from '../service/quantum-hub-service.js';
1
+ import { Command } from "commander";
2
+ import Table from "tty-table";
3
+ import { spinner, stdout, warn } from "../lib/output.js";
4
+ import { requireAuth } from "../model/command.js";
5
+ import QuantumHubService from "../service/quantum-hub-service.js";
6
6
  const EXAMPLES = `
7
7
  Examples:
8
8
  $ qhubctl services list
@@ -10,27 +10,30 @@ Examples:
10
10
  $ qhubctl services list --name "my-service"
11
11
  $ qhubctl services list --name "my-service" --json
12
12
  $ qhubctl services list --json --all`;
13
- export const servicesListCommand = new Command('list')
14
- .description('List all services of the current context.')
15
- .option('--json', 'Output in JSON format', false)
16
- .option('--name <value>', 'Filter services by name (case-insensitive full match)')
17
- .option('--all', 'Display all service properties (only available with --json)', false)
18
- .addHelpText('after', EXAMPLES)
13
+ export const servicesListCommand = new Command("list")
14
+ .description("List all services of the current context.")
15
+ .option("--json", "Output in JSON format", false)
16
+ .option("--name <value>", "Filter services by name (case-insensitive full match)")
17
+ .option("--all", "Display all service properties (only available with --json)", false)
18
+ .addHelpText("after", EXAMPLES)
19
19
  .action(async (opts) => {
20
20
  // suppress "Current context: ..." line when outputting JSON
21
21
  const userConfig = await requireAuth({ printContext: !opts.json });
22
22
  const quantumHubService = new QuantumHubService(userConfig);
23
23
  if (opts.all && !opts.json) {
24
- warn('The --all flag can only be used with --json output. Continuing without --all.');
24
+ warn("The --all flag can only be used with --json output. Continuing without --all.");
25
25
  }
26
- const spin = spinner('Loading services');
26
+ const spin = spinner("Loading services");
27
27
  let services = await quantumHubService.getServices();
28
- spin.succeed('Services loaded');
28
+ spin.succeed("Services loaded");
29
29
  if (opts.name) {
30
30
  const nameFilter = opts.name.toLowerCase();
31
- services = services.filter(service => service.name?.toLowerCase() === nameFilter);
31
+ services = services.filter((service) => service.name?.toLowerCase() === nameFilter);
32
32
  }
33
- const tableData = services.map(service => ({ id: service.id, name: service.name }));
33
+ const tableData = services.map((service) => ({
34
+ id: service.id,
35
+ name: service.name,
36
+ }));
34
37
  if (opts.json) {
35
38
  stdout(JSON.stringify(opts.all ? services : tableData, null, 2));
36
39
  return;
@@ -41,7 +44,7 @@ export const servicesListCommand = new Command('list')
41
44
  ];
42
45
  const t = Table(header, tableData);
43
46
  const contextName = userConfig.context?.displayName;
44
- const filterInfo = opts.name ? ` (filtered by name: "${opts.name}")` : '';
47
+ const filterInfo = opts.name ? ` (filtered by name: "${opts.name}")` : "";
45
48
  stdout(`Available services for ${contextName}${filterInfo}:`);
46
49
  stdout(t.render());
47
50
  stdout();
@@ -1,2 +1,2 @@
1
- import { Command } from 'commander';
1
+ import { Command } from "commander";
2
2
  export declare const setContextCommand: Command;
@@ -1,12 +1,14 @@
1
- import { select } from '@inquirer/prompts';
2
- import { Command } from 'commander';
3
- import { error, spinner, stdout } from '../lib/output.js';
4
- import { configDir, requireAuth } from '../model/command.js';
5
- import QuantumHubService from '../service/quantum-hub-service.js';
6
- import { writeUserConfig } from '../service/user-config-service.js';
1
+ import { select } from "@inquirer/prompts";
2
+ import { Command } from "commander";
3
+ import { error, spinner, stdout } from "../lib/output.js";
4
+ import { configDir, requireAuth } from "../model/command.js";
5
+ import QuantumHubService from "../service/quantum-hub-service.js";
6
+ import { writeUserConfig } from "../service/user-config-service.js";
7
7
  function getPromptOptions(accounts) {
8
- return accounts.map(account => ({
9
- name: account.isOrganization ? `${account.displayName} (Organization)` : (account.displayName ?? account.id ?? ''),
8
+ return accounts.map((account) => ({
9
+ name: account.isOrganization
10
+ ? `${account.displayName} (Organization)`
11
+ : (account.displayName ?? account.id ?? ""),
10
12
  value: account,
11
13
  }));
12
14
  }
@@ -14,26 +16,26 @@ const EXAMPLES = `
14
16
  Examples:
15
17
  $ qhubctl set-context
16
18
  $ qhubctl set-context <context-id>`;
17
- export const setContextCommand = new Command('set-context')
18
- .description('Set the current context, i.e., the personal or organization account you are currently working with.')
19
- .argument('[contextId]', 'The ID of the context to switch to')
20
- .addHelpText('after', EXAMPLES)
19
+ export const setContextCommand = new Command("set-context")
20
+ .description("Set the current context, i.e., the personal or organization account you are currently working with.")
21
+ .argument("[contextId]", "The ID of the context to switch to")
22
+ .addHelpText("after", EXAMPLES)
21
23
  .action(async (contextId) => {
22
24
  const userConfig = await requireAuth();
23
25
  const quantumHubService = new QuantumHubService(userConfig);
24
26
  if (!contextId) {
25
- const spin = spinner('Loading available contexts');
27
+ const spin = spinner("Loading available contexts");
26
28
  const accounts = await quantumHubService.getAccounts();
27
- spin.succeed('Contexts loaded');
29
+ spin.succeed("Contexts loaded");
28
30
  const response = await select({
29
31
  choices: getPromptOptions(accounts),
30
- message: 'Choose a context',
32
+ message: "Choose a context",
31
33
  default: accounts[0],
32
34
  });
33
35
  contextId = response.id;
34
36
  }
35
37
  const accounts = await quantumHubService.getAccounts();
36
- const selectedContext = accounts.find(account => account.id === contextId);
38
+ const selectedContext = accounts.find((account) => account.id === contextId);
37
39
  if (!selectedContext) {
38
40
  error(`Context with id "${contextId}" not found.`);
39
41
  }
@@ -1,2 +1,2 @@
1
- import { Command } from 'commander';
1
+ import { Command } from "commander";
2
2
  export declare const upCommand: Command;
@@ -1,19 +1,19 @@
1
- import { confirm, input, password } from '@inquirer/prompts';
2
- import { HubPlatform } from '@quantum-hub/qhub-api/platform';
3
- import { waitUntil } from 'async-wait-until';
4
- import { Command } from 'commander';
5
- import fs from 'node:fs';
6
- import path from 'node:path';
7
- import { error, spinner, stdout, warn } from '../lib/output.js';
8
- import { streamToBlob } from '../lib/stream-to-blob.js';
9
- import { getDescriptionText } from '../lib/up/get-description.js';
10
- import { QHUBIGNORE_HELP } from '../lib/up/qhubignore-help.js';
11
- import { enforceRequiredFiles } from '../lib/up/required-files.js';
12
- import { buildServiceSource, isRegistrySource, resolveRegistryCredentials } from '../lib/up/source.js';
13
- import { zipProjectFolder } from '../lib/up/zip.js';
14
- import { requireAuth } from '../model/command.js';
15
- import QuantumHubService from '../service/quantum-hub-service.js';
16
- import { readServiceConfig, writeServiceConfig } from '../service/service-config-service.js';
1
+ import { confirm, input, password } from "@inquirer/prompts";
2
+ import { HubPlatform } from "@quantum-hub/qhub-api/platform";
3
+ import { waitUntil } from "async-wait-until";
4
+ import { Command } from "commander";
5
+ import fs from "node:fs";
6
+ import path from "node:path";
7
+ import { error, spinner, stdout, warn } from "../lib/output.js";
8
+ import { streamToBlob } from "../lib/stream-to-blob.js";
9
+ import { getDescriptionText } from "../lib/up/get-description.js";
10
+ import { QHUBIGNORE_HELP } from "../lib/up/qhubignore-help.js";
11
+ import { enforceRequiredFiles } from "../lib/up/required-files.js";
12
+ import { buildServiceSource, isRegistrySource, resolveRegistryCredentials, } from "../lib/up/source.js";
13
+ import { zipProjectFolder } from "../lib/up/zip.js";
14
+ import { requireAuth } from "../model/command.js";
15
+ import QuantumHubService from "../service/quantum-hub-service.js";
16
+ import { readServiceConfig, writeServiceConfig } from "../service/service-config-service.js";
17
17
  /**
18
18
  * Prints an error message and exits. Service-layer errors already carry a resolved message.
19
19
  */
@@ -21,13 +21,13 @@ function fail(err) {
21
21
  error(err instanceof Error ? err.message : String(err));
22
22
  }
23
23
  async function getOpenapi() {
24
- const openapiYamlPath = path.join(process.cwd(), 'openapi.yaml');
25
- const openapiYmlPath = path.join(process.cwd(), 'openapi.yml');
24
+ const openapiYamlPath = path.join(process.cwd(), "openapi.yaml");
25
+ const openapiYmlPath = path.join(process.cwd(), "openapi.yml");
26
26
  let openapi = undefined;
27
27
  if (fs.existsSync(openapiYamlPath))
28
- openapi = fs.createReadStream(openapiYamlPath, 'utf8');
28
+ openapi = fs.createReadStream(openapiYamlPath, "utf8");
29
29
  else if (fs.existsSync(openapiYmlPath))
30
- openapi = fs.createReadStream(openapiYmlPath, 'utf8');
30
+ openapi = fs.createReadStream(openapiYmlPath, "utf8");
31
31
  if (openapi)
32
32
  return streamToBlob(openapi);
33
33
  return undefined;
@@ -64,19 +64,20 @@ async function buildServiceJob(qhubService, service, silentMode) {
64
64
  if (!silentMode) {
65
65
  if (buildJob.step !== currentStep) {
66
66
  if (buildJob.step === HubPlatform.BuildJobDto.Step.BuildImage) {
67
- spin ??= spinner('Building Image (1/2)');
67
+ spin ??= spinner("Building Image (1/2)");
68
68
  }
69
69
  else if (buildJob.step === HubPlatform.BuildJobDto.Step.PushImage) {
70
70
  if (spin) {
71
71
  spin.succeed();
72
72
  spin = undefined;
73
73
  }
74
- spin = spinner('Pushing Image (2/2)');
74
+ spin = spinner("Pushing Image (2/2)");
75
75
  }
76
76
  currentStep = buildJob.step;
77
77
  }
78
78
  }
79
- return buildJob.status === HubPlatform.BuildJobDto.Status.Success || buildJob.status === HubPlatform.BuildJobDto.Status.Failure;
79
+ return (buildJob.status === HubPlatform.BuildJobDto.Status.Success ||
80
+ buildJob.status === HubPlatform.BuildJobDto.Status.Failure);
80
81
  }, {
81
82
  intervalBetweenAttempts: 5000,
82
83
  timeout: silentMode ? 60 * 60 * 1000 : 20 * 60 * 1000,
@@ -84,7 +85,7 @@ async function buildServiceJob(qhubService, service, silentMode) {
84
85
  }
85
86
  catch (err) {
86
87
  spin?.fail();
87
- throw new Error('Error while waiting for the build job to finish: ' + err, { cause: err });
88
+ throw new Error("Error while waiting for the build job to finish: " + err, { cause: err });
88
89
  }
89
90
  if (spin) {
90
91
  if (buildJob?.status === HubPlatform.BuildJobDto.Status.Success)
@@ -96,7 +97,7 @@ async function buildServiceJob(qhubService, service, silentMode) {
96
97
  return buildJob;
97
98
  }
98
99
  async function createService(qhubService, serviceConfig, source, metadata, sourceCode, silentMode, noSaveId = false, customName) {
99
- const spin = silentMode ? undefined : spinner('Creating service');
100
+ const spin = silentMode ? undefined : spinner("Creating service");
100
101
  const configToUse = { ...serviceConfig };
101
102
  if (customName)
102
103
  configToUse.name = customName;
@@ -109,10 +110,10 @@ async function createService(qhubService, serviceConfig, source, metadata, sourc
109
110
  return service;
110
111
  }
111
112
  async function updateService(qhubService, serviceConfig, source, metadata, sourceCode, silentMode) {
112
- const spin = silentMode ? undefined : spinner('Updating service');
113
+ const spin = silentMode ? undefined : spinner("Updating service");
113
114
  // A registry source is set via the platform's update-source operation; a file
114
115
  // source uploads a fresh code archive. Either way the optional metadata follows.
115
- if (source.type === 'registry') {
116
+ if (source.type === "registry") {
116
117
  await qhubService.updateServiceSource(serviceConfig.serviceId, source);
117
118
  await uploadServiceMetadata(qhubService, serviceConfig, metadata);
118
119
  spin?.succeed();
@@ -133,11 +134,11 @@ async function resolveCredentialsInteractively(opts, silentMode) {
133
134
  if (credentials.username || silentMode) {
134
135
  return credentials;
135
136
  }
136
- const username = await input({ message: 'Registry username (leave blank for a public image)' });
137
+ const username = await input({ message: "Registry username (leave blank for a public image)" });
137
138
  if (!username) {
138
139
  return credentials;
139
140
  }
140
- const registryPassword = await password({ message: 'Registry password' });
141
+ const registryPassword = await password({ message: "Registry password" });
141
142
  return { username, password: registryPassword };
142
143
  }
143
144
  /**
@@ -145,10 +146,10 @@ async function resolveCredentialsInteractively(opts, silentMode) {
145
146
  * names in the project. Purely informational; never throws.
146
147
  */
147
148
  function warnAboutDeprecations(serviceConfig) {
148
- if (!('descriptionFile' in serviceConfig)) {
149
+ if (!("descriptionFile" in serviceConfig)) {
149
150
  stdout('Warning: Since version 2.14.0, the "description" property in qhub.json has changed to "descriptionFile".\nFor more information, visit: https://docs.hub.kipu-quantum.com/qhub-json-reference.html\n');
150
151
  }
151
- const deprecatedOpenapiFile = path.join(process.cwd(), 'openapi-spec.yml');
152
+ const deprecatedOpenapiFile = path.join(process.cwd(), "openapi-spec.yml");
152
153
  if (fs.existsSync(deprecatedOpenapiFile)) {
153
154
  warn('You are having the deprecated file "openapi-spec.yml" in your project. Please consider renaming it to "openapi.yaml".');
154
155
  }
@@ -171,7 +172,7 @@ async function resolveServiceExists(qhubService, serviceConfig) {
171
172
  }
172
173
  if (!serviceExistsInPlatform) {
173
174
  stdout(`We could not find a service with id '${serviceConfig.serviceId}' in the current context!`);
174
- const createNewService = await confirm({ message: 'Do you want to create a new service?' });
175
+ const createNewService = await confirm({ message: "Do you want to create a new service?" });
175
176
  if (!createNewService)
176
177
  process.exit(0);
177
178
  }
@@ -212,18 +213,19 @@ async function resolveServiceSource(serviceConfig, opts, silentMode) {
212
213
  */
213
214
  function reportBuildResult(buildJob, serviceExistsInPlatform) {
214
215
  if (buildJob?.status === HubPlatform.BuildJobDto.Status.Success) {
215
- stdout(`Service ${serviceExistsInPlatform ? 'updated' : 'created'} \u{1F680}`);
216
+ stdout(`Service ${serviceExistsInPlatform ? "updated" : "created"} \u{1F680}`);
216
217
  }
217
218
  else if (buildJob?.status === HubPlatform.BuildJobDto.Status.Failure) {
218
219
  const { validationResult } = buildJob;
219
- let reason = 'Failed creating service';
220
- if (validationResult?.state === HubPlatform.ValidationResult.State.Error && validationResult.summary) {
220
+ let reason = "Failed creating service";
221
+ if (validationResult?.state === HubPlatform.ValidationResult.State.Error &&
222
+ validationResult.summary) {
221
223
  reason = `${reason}: ${validationResult.summary}`;
222
224
  }
223
225
  error(reason);
224
226
  }
225
227
  else {
226
- error('Still pending, please check the platform UI to determine the status');
228
+ error("Still pending, please check the platform UI to determine the status");
227
229
  }
228
230
  }
229
231
  const EXAMPLES = `
@@ -233,15 +235,15 @@ Examples:
233
235
  $ qhubctl up --name "my-custom-service-name"
234
236
  $ qhubctl up --name "test-service" --no-save-id
235
237
  $ qhubctl up --image ghcr.io/acme/my-service:1.2.3`;
236
- export const upCommand = new Command('up')
238
+ export const upCommand = new Command("up")
237
239
  .description(`Creates or updates a service.\n\n${QHUBIGNORE_HELP}`)
238
- .option('--silent', 'Suppresses all outputs, helpful when executed in a CI/CD pipeline.', false)
239
- .option('--no-save-id', 'Prevents storing the created service ID in qhub.json file.')
240
- .option('--name <value>', 'Override the service name from qhub.json with a custom name.')
241
- .option('--image <ref>', 'Deploy a pre-built image from a container registry, given as registry/repo:tag (the tag defaults to "latest").')
242
- .option('--registry-username <value>', 'Username to pull a private registry image. Falls back to the QHUB_REGISTRY_USERNAME environment variable.')
243
- .option('--registry-password <value>', 'Password to pull a private registry image. Falls back to the QHUB_REGISTRY_PASSWORD environment variable.')
244
- .addHelpText('after', EXAMPLES)
240
+ .option("--silent", "Suppresses all outputs, helpful when executed in a CI/CD pipeline.", false)
241
+ .option("--no-save-id", "Prevents storing the created service ID in qhub.json file.")
242
+ .option("--name <value>", "Override the service name from qhub.json with a custom name.")
243
+ .option("--image <ref>", 'Deploy a pre-built image from a container registry, given as registry/repo:tag (the tag defaults to "latest").')
244
+ .option("--registry-username <value>", "Username to pull a private registry image. Falls back to the QHUB_REGISTRY_USERNAME environment variable.")
245
+ .option("--registry-password <value>", "Password to pull a private registry image. Falls back to the QHUB_REGISTRY_PASSWORD environment variable.")
246
+ .addHelpText("after", EXAMPLES)
245
247
  .action(async (opts) => {
246
248
  const userConfig = await requireAuth();
247
249
  const qhubService = new QuantumHubService(userConfig);
@@ -255,10 +257,10 @@ export const upCommand = new Command('up')
255
257
  // Metadata (openapi + description) is independent of the source kind.
256
258
  const metadata = await getServiceMetadata();
257
259
  // Only a file source ships local code; a registry source is pre-built.
258
- const sourceCode = source.type === 'file' ? await zipProjectFolder('./') : undefined;
260
+ const sourceCode = source.type === "file" ? await zipProjectFolder("./") : undefined;
259
261
  // The platform has no rename operation, so --name only takes effect on create.
260
262
  if (serviceExistsInPlatform && opts.name && !silentMode) {
261
- warn('Ignoring --name: the service name cannot be changed on update.');
263
+ warn("Ignoring --name: the service name cannot be changed on update.");
262
264
  }
263
265
  let service;
264
266
  try {
@@ -271,9 +273,9 @@ export const upCommand = new Command('up')
271
273
  }
272
274
  // A registry source is pre-built — the platform runs no build job, so
273
275
  // success is reported immediately. A file source must wait for the build.
274
- if (source.type !== 'file') {
276
+ if (source.type !== "file") {
275
277
  if (!silentMode)
276
- stdout(`Service ${serviceExistsInPlatform ? 'updated' : 'created'} \u{1F680}`);
278
+ stdout(`Service ${serviceExistsInPlatform ? "updated" : "created"} \u{1F680}`);
277
279
  return;
278
280
  }
279
281
  const buildJob = await buildServiceJob(qhubService, service, silentMode);
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export { program } from './program.js';
1
+ export { program } from "./program.js";
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export { program } from './program.js';
1
+ export { program } from "./program.js";
@@ -1,4 +1,4 @@
1
- import { execFile } from 'node:child_process';
2
- import { promisify } from 'node:util';
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
3
  const execFileAsync = promisify(execFile);
4
4
  export const executeAsyncCommand = (file, args) => execFileAsync(file, args);
@@ -1,8 +1,8 @@
1
- import os from 'node:os';
2
- import path from 'node:path';
1
+ import os from "node:os";
2
+ import path from "node:path";
3
3
  /**
4
4
  * Resolves the user-scoped config directory for qhubctl.
5
5
  * Equivalent to oclif's `this.config.configDir` (driven by `oclif.dirname = "qhubctl"`).
6
6
  * On all platforms this follows XDG convention: ~/.config/qhubctl
7
7
  */
8
- export const configDir = path.join(os.homedir(), '.config', 'qhubctl');
8
+ export const configDir = path.join(os.homedir(), ".config", "qhubctl");
package/dist/lib/debug.js CHANGED
@@ -1 +1 @@
1
- export const debugEnabled = () => Boolean(process.env.DEBUG && process.env.DEBUG !== '');
1
+ export const debugEnabled = () => Boolean(process.env.DEBUG && process.env.DEBUG !== "");