@sanity/cli 8.21.0 → 8.22.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.
Files changed (80) hide show
  1. package/README.md +106 -47
  2. package/codemods/dashboard.js +111 -0
  3. package/dist/actions/build/buildApp.js +1 -1
  4. package/dist/actions/build/buildApp.js.map +1 -1
  5. package/dist/actions/build/buildStudio.js +1 -1
  6. package/dist/actions/build/buildStudio.js.map +1 -1
  7. package/dist/actions/codemods/dashboard.js +113 -0
  8. package/dist/actions/codemods/dashboard.js.map +1 -0
  9. package/dist/actions/codemods/index.js +2 -0
  10. package/dist/actions/codemods/index.js.map +1 -1
  11. package/dist/actions/codemods/types.js.map +1 -1
  12. package/dist/actions/deploy/deployApp.js +13 -6
  13. package/dist/actions/deploy/deployApp.js.map +1 -1
  14. package/dist/actions/deploy/deployChecks.js +12 -7
  15. package/dist/actions/deploy/deployChecks.js.map +1 -1
  16. package/dist/actions/deploy/deployRunner.js +14 -8
  17. package/dist/actions/deploy/deployRunner.js.map +1 -1
  18. package/dist/actions/deploy/deployStudio.js +39 -4
  19. package/dist/actions/deploy/deployStudio.js.map +1 -1
  20. package/dist/actions/deploy/deployStudioSchemasAndManifestsWorker.js +6 -15
  21. package/dist/actions/deploy/deployStudioSchemasAndManifestsWorker.js.map +1 -1
  22. package/dist/actions/deploy/resolveDeployTarget.js +7 -6
  23. package/dist/actions/deploy/resolveDeployTarget.js.map +1 -1
  24. package/dist/actions/init/project/promptForAppTemplateSetup.js +22 -0
  25. package/dist/actions/init/project/promptForAppTemplateSetup.js.map +1 -1
  26. package/dist/actions/schema/deploySchemas.js.map +1 -1
  27. package/dist/actions/schema/extractSchemaWatcher.js +69 -14
  28. package/dist/actions/schema/extractSchemaWatcher.js.map +1 -1
  29. package/dist/actions/schema/listSchemas.js +2 -3
  30. package/dist/actions/schema/listSchemas.js.map +1 -1
  31. package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -1
  32. package/dist/actions/typegen/generateResourceTypes.js +11 -8
  33. package/dist/actions/typegen/generateResourceTypes.js.map +1 -1
  34. package/dist/actions/typegen/watchResourceTypes.js +208 -0
  35. package/dist/actions/typegen/watchResourceTypes.js.map +1 -0
  36. package/dist/actions/undeploy/runUndeploy.js +14 -8
  37. package/dist/actions/undeploy/runUndeploy.js.map +1 -1
  38. package/dist/commands/codemod.js +15 -4
  39. package/dist/commands/codemod.js.map +1 -1
  40. package/dist/commands/context/get.js +3 -8
  41. package/dist/commands/context/get.js.map +1 -1
  42. package/dist/commands/context/imports/download.js +3 -8
  43. package/dist/commands/context/imports/download.js.map +1 -1
  44. package/dist/commands/context/imports/get.js +3 -8
  45. package/dist/commands/context/imports/get.js.map +1 -1
  46. package/dist/commands/context/imports/list.js +3 -8
  47. package/dist/commands/context/imports/list.js.map +1 -1
  48. package/dist/commands/context/jobs/get.js +8 -8
  49. package/dist/commands/context/jobs/get.js.map +1 -1
  50. package/dist/commands/context/list.js +2 -6
  51. package/dist/commands/context/list.js.map +1 -1
  52. package/dist/commands/deploy.js +1 -0
  53. package/dist/commands/deploy.js.map +1 -1
  54. package/dist/commands/doctor.js +2 -1
  55. package/dist/commands/doctor.js.map +1 -1
  56. package/dist/commands/openapi/list.js +2 -4
  57. package/dist/commands/openapi/list.js.map +1 -1
  58. package/dist/commands/projects/create.js +3 -6
  59. package/dist/commands/projects/create.js.map +1 -1
  60. package/dist/commands/schemas/list.js +1 -3
  61. package/dist/commands/schemas/list.js.map +1 -1
  62. package/dist/commands/tokens/create.js +2 -5
  63. package/dist/commands/tokens/create.js.map +1 -1
  64. package/dist/commands/tokens/list.js +2 -6
  65. package/dist/commands/tokens/list.js.map +1 -1
  66. package/dist/commands/tokens/rotate.js +2 -5
  67. package/dist/commands/tokens/rotate.js.map +1 -1
  68. package/dist/commands/typegen/generate.js +83 -45
  69. package/dist/commands/typegen/generate.js.map +1 -1
  70. package/dist/commands/undeploy.js +1 -0
  71. package/dist/commands/undeploy.js.map +1 -1
  72. package/dist/commands/whoami.js +5 -11
  73. package/dist/commands/whoami.js.map +1 -1
  74. package/dist/exports/invokeSanityCli/index.js +26 -6
  75. package/dist/exports/invokeSanityCli/index.js.map +1 -1
  76. package/dist/generated/apiRoutes.js +11 -26
  77. package/dist/generated/apiRoutes.js.map +1 -1
  78. package/dist/telemetry/init.telemetry.js.map +1 -1
  79. package/oclif.manifest.json +2340 -2311
  80. package/package.json +6 -5
@@ -1,7 +1,7 @@
1
1
  import { styleText } from 'node:util';
2
2
  import { CLIError } from '@oclif/core/errors';
3
3
  import { exitCodes, subdebug } from '@sanity/cli-core';
4
- import { getErrorMessage } from '@sanity/cli-core/errors';
4
+ import { getErrorMessage, JsonOutputError } from '@sanity/cli-core/errors';
5
5
  import { confirm, spinner } from '@sanity/cli-core/ux';
6
6
  import { createCollectingReporter, createFailFastReporter } from '../../util/checks.js';
7
7
  import { toStderrOutput } from '../../util/toStderrOutput.js';
@@ -15,7 +15,8 @@ const undeployDebug = subdebug('undeploy');
15
15
  */ export async function runUndeploy(options, adapter) {
16
16
  const { flags, output } = options;
17
17
  const json = !!flags.json;
18
- const emitJson = (payload)=>output.log(JSON.stringify(payload, null, 2));
18
+ const emitJson = (payload)=>output.logJson(payload);
19
+ let failurePayload;
19
20
  // The JSON payload owns stdout, so the run's progress logs go to stderr; only
20
21
  // the final JSON.stringify writes to stdout.
21
22
  const runOptions = json ? {
@@ -32,8 +33,11 @@ const undeployDebug = subdebug('undeploy');
32
33
  target: resolution?.type === 'found' ? resolution.target : null,
33
34
  type: adapter.type
34
35
  };
35
- if (json) emitJson(undeployPlanToJson(plan));
36
- else renderUndeployPlan(plan, output);
36
+ if (json) {
37
+ const payload = undeployPlanToJson(plan);
38
+ if (plan.checks.some((check)=>check.status === 'fail')) failurePayload = payload;
39
+ else emitJson(payload);
40
+ } else renderUndeployPlan(plan, output);
37
41
  // A blocked plan exits like a real (fail-fast) undeploy would.
38
42
  const failed = plan.checks.find((check)=>check.status === 'fail');
39
43
  if (failed) output.error('Undeploy blocked by failing checks.', {
@@ -45,10 +49,9 @@ const undeployDebug = subdebug('undeploy');
45
49
  if (json && result) emitJson(result);
46
50
  } catch (error) {
47
51
  const failure = normalizeFailure(error, adapter.type);
48
- // A blocked dry run reaches this catch too (its exit throws) and already
49
- // printed its plan, so only a real undeploy adds the {undeployed: false} envelope.
52
+ // Preserve the blocked plan or the existing undeployment failure envelope.
50
53
  if (json && !flags['dry-run']) {
51
- emitJson({
54
+ failurePayload = {
52
55
  application: null,
53
56
  error: {
54
57
  message: failure.message
@@ -56,7 +59,10 @@ const undeployDebug = subdebug('undeploy');
56
59
  payload: null,
57
60
  reason: failure.message,
58
61
  undeployed: false
59
- });
62
+ };
63
+ }
64
+ if (json && failurePayload !== undefined) {
65
+ throw new JsonOutputError(failure.message, failurePayload, failure.exit);
60
66
  }
61
67
  output.error(failure.message, {
62
68
  exit: failure.exit
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/undeploy/runUndeploy.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {CLIError} from '@oclif/core/errors'\nimport {exitCodes, type Output, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {\n type UndeployAdapter,\n type UndeployTarget,\n type UndeployTargetResolution,\n} from '@sanity/cli-core/undeploy'\nimport {confirm, spinner} from '@sanity/cli-core/ux'\n\nimport {type UndeployCommand} from '../../commands/undeploy.js'\nimport {\n type CheckReporter,\n createCollectingReporter,\n createFailFastReporter,\n} from '../../util/checks.js'\nimport {toStderrOutput} from '../../util/toStderrOutput.js'\nimport {\n describeUndeployTarget,\n renderUndeployPlan,\n undeployLabel,\n type UndeployPlan,\n undeployPlanToJson,\n} from './undeployPlan.js'\n\nconst undeployDebug = subdebug('undeploy')\n\ntype UndeployFlags = UndeployCommand['flags']\n\nexport interface UndeployOptions {\n flags: UndeployFlags\n isUnattended: boolean\n output: Output\n}\n\n/** What a real undeploy produced — the payload `--json` reports. */\ntype UndeployResult =\n | {application: null; payload: null; reason: string; undeployed: false}\n | {\n application: object | null\n deletes: UndeployTarget['deletes']\n payload: UndeployTarget['payload']\n reason: null\n undeployed: true\n url: string | null\n }\n\n/**\n * Runs an undeploy in the mode the flags select: a real undeploy fails fast,\n * confirms, and deletes; `--dry-run` drives the same target resolution\n * read-only and renders a plan instead. `--json` emits the same information as\n * machine-readable JSON.\n */\nexport async function runUndeploy(\n options: UndeployOptions,\n adapter: UndeployAdapter,\n): Promise<void> {\n const {flags, output} = options\n const json = !!flags.json\n const emitJson = (payload: unknown) => output.log(JSON.stringify(payload, null, 2))\n\n // The JSON payload owns stdout, so the run's progress logs go to stderr; only\n // the final JSON.stringify writes to stdout.\n const runOptions = json ? {...options, output: toStderrOutput(output)} : options\n\n try {\n if (flags['dry-run']) {\n const reporter = createCollectingReporter()\n const resolution = await resolveTarget(adapter, reporter)\n const plan: UndeployPlan = {\n checks: reporter.results,\n reason: resolution?.type === 'none' ? resolution.message : null,\n target: resolution?.type === 'found' ? resolution.target : null,\n type: adapter.type,\n }\n if (json) emitJson(undeployPlanToJson(plan))\n else renderUndeployPlan(plan, output)\n // A blocked plan exits like a real (fail-fast) undeploy would.\n const failed = plan.checks.find((check) => check.status === 'fail')\n if (failed) output.error('Undeploy blocked by failing checks.', {exit: failed.exitCode ?? 1})\n return\n }\n\n const result = await undeployApp(runOptions, adapter)\n if (json && result) emitJson(result)\n } catch (error) {\n const failure = normalizeFailure(error, adapter.type)\n // A blocked dry run reaches this catch too (its exit throws) and already\n // printed its plan, so only a real undeploy adds the {undeployed: false} envelope.\n if (json && !flags['dry-run']) {\n emitJson({\n application: null,\n error: {message: failure.message},\n payload: null,\n reason: failure.message,\n undeployed: false,\n })\n }\n output.error(failure.message, {exit: failure.exit})\n }\n}\n\n/** The real run: resolve the target, confirm, delete, report. */\nasync function undeployApp(\n options: UndeployOptions,\n adapter: UndeployAdapter,\n): Promise<UndeployResult | undefined> {\n const {flags, output} = options\n\n const resolution = await resolveTarget(adapter, createFailFastReporter(output))\n // A resolve failure never lands here: the fail-fast reporter already exited.\n if (!resolution) return undefined\n if (resolution.type === 'none') {\n output.log(`${resolution.message}.`)\n if (resolution.solution) output.log(`${resolution.solution}.`)\n output.log('Nothing to undeploy.')\n return {application: null, payload: null, reason: resolution.message, undeployed: false}\n }\n\n const {target} = resolution\n if (!flags.yes && options.isUnattended) {\n throw new CLIError('Undeploy requires confirmation. Pass --yes to continue.', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n\n if (!flags.yes) {\n const shouldUndeploy = await confirm({\n default: false,\n message: confirmUndeployMessage(target),\n })\n if (!shouldUndeploy) {\n throw new CLIError('Undeploy cancelled', {exit: exitCodes.USER_ABORT})\n }\n }\n\n const label = undeployLabel(target, adapter.type)\n const spin = spinner(`Undeploying ${label}`).start()\n try {\n await adapter.undeploy(target)\n } catch (error) {\n spin.fail()\n undeployDebug(`Error undeploying ${label}`, error)\n // Labeled here, where the target is known — `normalizeFailure` only sees the adapter type.\n throw new CLIError(`Error undeploying ${label}: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n spin.succeed()\n\n printUndeployed(target, output)\n return {\n application: target.application ?? null,\n deletes: target.deletes,\n payload: target.payload,\n reason: null,\n undeployed: true,\n url: target.url,\n }\n}\n\n/**\n * Resolves the undeploy target and reports the verdict as a check, shared by\n * both modes so a real run and a dry run can't diverge.\n */\nasync function resolveTarget(\n adapter: UndeployAdapter,\n reporter: CheckReporter,\n): Promise<UndeployTargetResolution | null> {\n const spin = spinner('Checking application info').start()\n\n let resolution: UndeployTargetResolution\n try {\n resolution = await adapter.resolveTarget()\n } catch (error) {\n spin.fail()\n undeployDebug('Failed to resolve undeploy target', error)\n reporter.report({\n message: `Failed to resolve undeploy target: ${getErrorMessage(error)}`,\n status: 'fail',\n })\n return null\n }\n\n spin[resolution.type === 'found' ? 'succeed' : 'fail']()\n reporter.report(describeUndeployTarget(resolution))\n return resolution\n}\n\nfunction confirmUndeployMessage(target: UndeployTarget): string {\n if (target.deletes === 'config') {\n return `This will delete the deployed config for ${styleText(\n 'yellow',\n target.title ?? 'this app',\n )}.\nAre you ${styleText('red', 'sure')} you want to undeploy?`\n }\n\n if (target.type === 'coreApp') {\n return `This will undeploy the following application:\n\n Title: ${styleText('yellow', target.title || '(untitled application)')}\n ID: ${styleText('yellow', target.id)}\n\nThe application will no longer be available for any of your users if you proceed.\n\nAre you ${styleText('red', 'sure')} you want to undeploy?`\n }\n\n return `This will undeploy ${styleText('yellow', target.url ?? target.id)} and make it unavailable for your users.\nAre you ${styleText('red', 'sure')} you want to undeploy?`\n}\n\nfunction printUndeployed(target: UndeployTarget, output: Output): void {\n if (target.deletes === 'config') {\n output.log(`\\n${styleText('bold', 'Config deleted.')}`)\n return\n }\n\n if (target.type === 'coreApp') {\n output.log(\n `\\n${styleText('bold', '⏱️ Application undeploy scheduled.')} It might be a few minutes until ${\n target.title ? styleText('italic', `'${target.title}'`) : 'your application'\n } is unavailable.`,\n )\n output.log(\n `\\n${styleText('bold', 'Remember to remove `deployment.appId` from your application configuration')} to avoid errors when redeploying.`,\n )\n return\n }\n\n output.log(\n `\\nStudio undeploy scheduled. It might be a few minutes until ${target.url ?? 'your studio'} is unavailable.`,\n )\n}\n\n/** The one failure diagnosis both the stderr message and the `--json` envelope read. */\nfunction normalizeFailure(\n error: unknown,\n type: UndeployAdapter['type'],\n): {exit: number; message: string} {\n // Ctrl+C on the confirmation prompt isn't a real failure\n if (error instanceof Error && error.name === 'ExitPromptError') {\n return {exit: exitCodes.USER_ABORT, message: 'Undeploy cancelled'}\n }\n // A failed check already carries its own message and exit code\n if (error instanceof CLIError) {\n return {exit: error.oclif?.exit ?? 1, message: error.message}\n }\n const label = type === 'coreApp' ? 'application' : 'studio'\n undeployDebug(`Error undeploying ${label}`, error)\n return {\n exit: exitCodes.RUNTIME_ERROR,\n message: `Error undeploying ${label}: ${getErrorMessage(error)}`,\n }\n}\n"],"names":["styleText","CLIError","exitCodes","subdebug","getErrorMessage","confirm","spinner","createCollectingReporter","createFailFastReporter","toStderrOutput","describeUndeployTarget","renderUndeployPlan","undeployLabel","undeployPlanToJson","undeployDebug","runUndeploy","options","adapter","flags","output","json","emitJson","payload","log","JSON","stringify","runOptions","reporter","resolution","resolveTarget","plan","checks","results","reason","type","message","target","failed","find","check","status","error","exit","exitCode","result","undeployApp","failure","normalizeFailure","application","undeployed","undefined","solution","yes","isUnattended","USAGE_ERROR","shouldUndeploy","default","confirmUndeployMessage","USER_ABORT","label","spin","start","undeploy","fail","RUNTIME_ERROR","succeed","printUndeployed","deletes","url","report","title","id","Error","name","oclif"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/undeploy/runUndeploy.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {CLIError} from '@oclif/core/errors'\nimport {exitCodes, type Output, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage, JsonOutputError} from '@sanity/cli-core/errors'\nimport {\n type UndeployAdapter,\n type UndeployTarget,\n type UndeployTargetResolution,\n} from '@sanity/cli-core/undeploy'\nimport {confirm, spinner} from '@sanity/cli-core/ux'\n\nimport {type UndeployCommand} from '../../commands/undeploy.js'\nimport {\n type CheckReporter,\n createCollectingReporter,\n createFailFastReporter,\n} from '../../util/checks.js'\nimport {toStderrOutput} from '../../util/toStderrOutput.js'\nimport {\n describeUndeployTarget,\n renderUndeployPlan,\n undeployLabel,\n type UndeployPlan,\n undeployPlanToJson,\n} from './undeployPlan.js'\n\nconst undeployDebug = subdebug('undeploy')\n\ntype UndeployFlags = UndeployCommand['flags']\n\nexport interface UndeployOptions {\n flags: UndeployFlags\n isUnattended: boolean\n output: Output\n}\n\n/** What a real undeploy produced — the payload `--json` reports. */\ntype UndeployResult =\n | {application: null; payload: null; reason: string; undeployed: false}\n | {\n application: object | null\n deletes: UndeployTarget['deletes']\n payload: UndeployTarget['payload']\n reason: null\n undeployed: true\n url: string | null\n }\n\n/**\n * Runs an undeploy in the mode the flags select: a real undeploy fails fast,\n * confirms, and deletes; `--dry-run` drives the same target resolution\n * read-only and renders a plan instead. `--json` emits the same information as\n * machine-readable JSON.\n */\nexport async function runUndeploy(\n options: UndeployOptions,\n adapter: UndeployAdapter,\n): Promise<void> {\n const {flags, output} = options\n const json = !!flags.json\n const emitJson = (payload: unknown) => output.logJson(payload)\n let failurePayload: unknown\n\n // The JSON payload owns stdout, so the run's progress logs go to stderr; only\n // the final JSON.stringify writes to stdout.\n const runOptions = json ? {...options, output: toStderrOutput(output)} : options\n\n try {\n if (flags['dry-run']) {\n const reporter = createCollectingReporter()\n const resolution = await resolveTarget(adapter, reporter)\n const plan: UndeployPlan = {\n checks: reporter.results,\n reason: resolution?.type === 'none' ? resolution.message : null,\n target: resolution?.type === 'found' ? resolution.target : null,\n type: adapter.type,\n }\n if (json) {\n const payload = undeployPlanToJson(plan)\n if (plan.checks.some((check) => check.status === 'fail')) failurePayload = payload\n else emitJson(payload)\n } else renderUndeployPlan(plan, output)\n // A blocked plan exits like a real (fail-fast) undeploy would.\n const failed = plan.checks.find((check) => check.status === 'fail')\n if (failed) output.error('Undeploy blocked by failing checks.', {exit: failed.exitCode ?? 1})\n return\n }\n\n const result = await undeployApp(runOptions, adapter)\n if (json && result) emitJson(result)\n } catch (error) {\n const failure = normalizeFailure(error, adapter.type)\n // Preserve the blocked plan or the existing undeployment failure envelope.\n if (json && !flags['dry-run']) {\n failurePayload = {\n application: null,\n error: {message: failure.message},\n payload: null,\n reason: failure.message,\n undeployed: false,\n }\n }\n if (json && failurePayload !== undefined) {\n throw new JsonOutputError(failure.message, failurePayload, failure.exit)\n }\n output.error(failure.message, {exit: failure.exit})\n }\n}\n\n/** The real run: resolve the target, confirm, delete, report. */\nasync function undeployApp(\n options: UndeployOptions,\n adapter: UndeployAdapter,\n): Promise<UndeployResult | undefined> {\n const {flags, output} = options\n\n const resolution = await resolveTarget(adapter, createFailFastReporter(output))\n // A resolve failure never lands here: the fail-fast reporter already exited.\n if (!resolution) return undefined\n if (resolution.type === 'none') {\n output.log(`${resolution.message}.`)\n if (resolution.solution) output.log(`${resolution.solution}.`)\n output.log('Nothing to undeploy.')\n return {application: null, payload: null, reason: resolution.message, undeployed: false}\n }\n\n const {target} = resolution\n if (!flags.yes && options.isUnattended) {\n throw new CLIError('Undeploy requires confirmation. Pass --yes to continue.', {\n exit: exitCodes.USAGE_ERROR,\n })\n }\n\n if (!flags.yes) {\n const shouldUndeploy = await confirm({\n default: false,\n message: confirmUndeployMessage(target),\n })\n if (!shouldUndeploy) {\n throw new CLIError('Undeploy cancelled', {exit: exitCodes.USER_ABORT})\n }\n }\n\n const label = undeployLabel(target, adapter.type)\n const spin = spinner(`Undeploying ${label}`).start()\n try {\n await adapter.undeploy(target)\n } catch (error) {\n spin.fail()\n undeployDebug(`Error undeploying ${label}`, error)\n // Labeled here, where the target is known — `normalizeFailure` only sees the adapter type.\n throw new CLIError(`Error undeploying ${label}: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n spin.succeed()\n\n printUndeployed(target, output)\n return {\n application: target.application ?? null,\n deletes: target.deletes,\n payload: target.payload,\n reason: null,\n undeployed: true,\n url: target.url,\n }\n}\n\n/**\n * Resolves the undeploy target and reports the verdict as a check, shared by\n * both modes so a real run and a dry run can't diverge.\n */\nasync function resolveTarget(\n adapter: UndeployAdapter,\n reporter: CheckReporter,\n): Promise<UndeployTargetResolution | null> {\n const spin = spinner('Checking application info').start()\n\n let resolution: UndeployTargetResolution\n try {\n resolution = await adapter.resolveTarget()\n } catch (error) {\n spin.fail()\n undeployDebug('Failed to resolve undeploy target', error)\n reporter.report({\n message: `Failed to resolve undeploy target: ${getErrorMessage(error)}`,\n status: 'fail',\n })\n return null\n }\n\n spin[resolution.type === 'found' ? 'succeed' : 'fail']()\n reporter.report(describeUndeployTarget(resolution))\n return resolution\n}\n\nfunction confirmUndeployMessage(target: UndeployTarget): string {\n if (target.deletes === 'config') {\n return `This will delete the deployed config for ${styleText(\n 'yellow',\n target.title ?? 'this app',\n )}.\nAre you ${styleText('red', 'sure')} you want to undeploy?`\n }\n\n if (target.type === 'coreApp') {\n return `This will undeploy the following application:\n\n Title: ${styleText('yellow', target.title || '(untitled application)')}\n ID: ${styleText('yellow', target.id)}\n\nThe application will no longer be available for any of your users if you proceed.\n\nAre you ${styleText('red', 'sure')} you want to undeploy?`\n }\n\n return `This will undeploy ${styleText('yellow', target.url ?? target.id)} and make it unavailable for your users.\nAre you ${styleText('red', 'sure')} you want to undeploy?`\n}\n\nfunction printUndeployed(target: UndeployTarget, output: Output): void {\n if (target.deletes === 'config') {\n output.log(`\\n${styleText('bold', 'Config deleted.')}`)\n return\n }\n\n if (target.type === 'coreApp') {\n output.log(\n `\\n${styleText('bold', '⏱️ Application undeploy scheduled.')} It might be a few minutes until ${\n target.title ? styleText('italic', `'${target.title}'`) : 'your application'\n } is unavailable.`,\n )\n output.log(\n `\\n${styleText('bold', 'Remember to remove `deployment.appId` from your application configuration')} to avoid errors when redeploying.`,\n )\n return\n }\n\n output.log(\n `\\nStudio undeploy scheduled. It might be a few minutes until ${target.url ?? 'your studio'} is unavailable.`,\n )\n}\n\n/** The one failure diagnosis both the stderr message and the `--json` envelope read. */\nfunction normalizeFailure(\n error: unknown,\n type: UndeployAdapter['type'],\n): {exit: number; message: string} {\n // Ctrl+C on the confirmation prompt isn't a real failure\n if (error instanceof Error && error.name === 'ExitPromptError') {\n return {exit: exitCodes.USER_ABORT, message: 'Undeploy cancelled'}\n }\n // A failed check already carries its own message and exit code\n if (error instanceof CLIError) {\n return {exit: error.oclif?.exit ?? 1, message: error.message}\n }\n const label = type === 'coreApp' ? 'application' : 'studio'\n undeployDebug(`Error undeploying ${label}`, error)\n return {\n exit: exitCodes.RUNTIME_ERROR,\n message: `Error undeploying ${label}: ${getErrorMessage(error)}`,\n }\n}\n"],"names":["styleText","CLIError","exitCodes","subdebug","getErrorMessage","JsonOutputError","confirm","spinner","createCollectingReporter","createFailFastReporter","toStderrOutput","describeUndeployTarget","renderUndeployPlan","undeployLabel","undeployPlanToJson","undeployDebug","runUndeploy","options","adapter","flags","output","json","emitJson","payload","logJson","failurePayload","runOptions","reporter","resolution","resolveTarget","plan","checks","results","reason","type","message","target","some","check","status","failed","find","error","exit","exitCode","result","undeployApp","failure","normalizeFailure","application","undeployed","undefined","log","solution","yes","isUnattended","USAGE_ERROR","shouldUndeploy","default","confirmUndeployMessage","USER_ABORT","label","spin","start","undeploy","fail","RUNTIME_ERROR","succeed","printUndeployed","deletes","url","report","title","id","Error","name","oclif"],"mappings":"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"}
@@ -81,6 +81,12 @@ export class CodemodCommand extends SanityCommand {
81
81
  const dryRun = flags.dry;
82
82
  // We use npx to run jscodeshift, so verify that it exists and works before using it
83
83
  this.ensureNpx();
84
+ const prepared = await mod.prepare?.({
85
+ output: this.output,
86
+ workDir
87
+ });
88
+ // jscodeshift JSON-parses option values, so encode them to keep strings like "2024" as strings
89
+ const transformOptions = Object.entries(prepared?.options ?? {}).map(([key, value])=>`--${key}=${JSON.stringify(value)}`);
84
90
  // If there is a gitignore in the target folder, we want to use that to know
85
91
  // which folders to ignore - eg `dist`, `coverage` or whatever
86
92
  const hasGitIgnore = existsSync(path.join(workDir, '.gitignore'));
@@ -100,7 +106,10 @@ export class CodemodCommand extends SanityCommand {
100
106
  '--extensions',
101
107
  exts.join(','),
102
108
  dryRun && '--dry',
103
- workDir
109
+ ...transformOptions,
110
+ ...prepared?.paths ?? [
111
+ workDir
112
+ ]
104
113
  ].filter((item)=>typeof item === 'string');
105
114
  const child = spawn('npx', cmdArgs, {
106
115
  stdio: 'inherit'
@@ -109,10 +118,12 @@ export class CodemodCommand extends SanityCommand {
109
118
  child.kill(2);
110
119
  };
111
120
  process.on('SIGINT', handleSigint);
112
- child.on('close', (code)=>{
113
- process.removeListener('SIGINT', handleSigint);
114
- this.exit(code || undefined);
121
+ // Wait inside run() so oclif handles the exit, rather than throwing from an event callback
122
+ const code = await new Promise((resolve)=>{
123
+ child.on('close', resolve);
115
124
  });
125
+ process.removeListener('SIGINT', handleSigint);
126
+ this.exit(code || undefined);
116
127
  }
117
128
  ensureNpx() {
118
129
  try {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/codemod.ts"],"sourcesContent":["import {execSync, spawn} from 'node:child_process'\nimport {existsSync} from 'node:fs'\nimport path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {codemods} from '../actions/codemods/index.js'\nimport {type CodeMod} from '../actions/codemods/types.js'\n\nconst codemodeDebug = subdebug('codemod')\n\nexport class CodemodCommand extends SanityCommand<typeof CodemodCommand> {\n static override args = {\n codemodName: Args.string({\n description: 'Name of the codemod to run',\n required: false,\n }),\n }\n\n static override description = 'Updates Sanity Studio codebase with a code modification script'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Show available code mods',\n },\n {\n command: '<%= config.bin %> <%= command.id %> reactIconsV3 --dry',\n description: 'Run codemod to transform react-icons imports (dry run)',\n },\n ]\n\n static override flags = {\n dry: Flags.boolean({\n default: false,\n description: 'Dry run (no changes are made to files)',\n }),\n extensions: Flags.string({\n default: 'js,ts,tsx',\n description: 'Transform files with these file extensions (comma separated)',\n }),\n 'no-verify': Flags.boolean({\n default: false,\n description: 'Skip verification steps before running codemod',\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(CodemodCommand)\n const {codemodName} = args\n const workDir = process.cwd()\n\n if (!codemodName) {\n this.printMods()\n return\n }\n\n // Make a record where all the keys of the available codemods are lowercased,\n // eg `reactIconsV3` turns into `{reacticonsv3: CodeMod}`\n const normalizedMods: Map<string, CodeMod> = new Map()\n for (const [originalName, mod] of Object.entries(codemods)) {\n normalizedMods.set(originalName.toLowerCase(), mod)\n }\n\n // Verify that mod exists\n const mod = normalizedMods.get(codemodName.toLowerCase())\n if (!mod) {\n this.error(`Codemod with name \"${codemodName}\" not found`, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n // Verify if there is any verification defined, and user has not opted out of it\n if (typeof mod.verify === 'function' && !flags['no-verify']) {\n try {\n await mod.verify({workDir})\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n codemodeDebug('Verification failed: %s', err.message)\n this.error(`Verification failed: ${err.message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n // If extensions are defined, they come in as CSV, so split and normalize them\n const exts = flags.extensions\n ? flags.extensions.split(',').map((ext) => ext.trim().replace(/^\\./, ''))\n : ['js', 'ts', 'tsx']\n\n const dryRun = flags.dry\n\n // We use npx to run jscodeshift, so verify that it exists and works before using it\n this.ensureNpx()\n\n // If there is a gitignore in the target folder, we want to use that to know\n // which folders to ignore - eg `dist`, `coverage` or whatever\n const hasGitIgnore = existsSync(path.join(workDir, '.gitignore'))\n\n // Build the CLI command arguments\n const cliRoot = path.resolve(import.meta.dirname, '../..')\n const modPath = path.resolve(path.join(cliRoot, 'codemods', mod.filename))\n const cmdArgs = [\n 'jscodeshift',\n '--ignore-pattern',\n 'node_modules',\n '--ignore-pattern',\n 'dist',\n hasGitIgnore && '--ignore-config',\n hasGitIgnore && '.gitignore',\n '-t',\n modPath,\n '--extensions',\n exts.join(','),\n dryRun && '--dry',\n workDir,\n ].filter((item): item is string => typeof item === 'string')\n\n const child = spawn('npx', cmdArgs, {\n stdio: 'inherit',\n })\n\n const handleSigint = () => {\n child.kill(2)\n }\n\n process.on('SIGINT', handleSigint)\n\n child.on('close', (code) => {\n process.removeListener('SIGINT', handleSigint)\n this.exit(code || undefined)\n })\n }\n\n private ensureNpx(): void {\n try {\n const npxHelp = execSync('npx --help', {encoding: 'utf8'})\n if (!npxHelp.includes('npm')) {\n this.error('Not the npx we expected', {exit: exitCodes.RUNTIME_ERROR})\n }\n } catch {\n this.error(\n `Failed to run \"npx\" - required to run codemods. Do you have a recent version of npm installed?`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n }\n\n private printMods(): void {\n this.log('Available code modifications:\\n')\n\n for (const [modName, mod] of Object.entries(codemods)) {\n this.log(`${modName} - ${mod.purpose}`)\n }\n }\n}\n"],"names":["execSync","spawn","existsSync","path","Args","Flags","exitCodes","SanityCommand","subdebug","codemods","codemodeDebug","CodemodCommand","args","codemodName","string","description","required","examples","command","flags","dry","boolean","default","extensions","run","parse","workDir","process","cwd","printMods","normalizedMods","Map","originalName","mod","Object","entries","set","toLowerCase","get","error","exit","RUNTIME_ERROR","verify","err","Error","String","message","exts","split","map","ext","trim","replace","dryRun","ensureNpx","hasGitIgnore","join","cliRoot","resolve","dirname","modPath","filename","cmdArgs","filter","item","child","stdio","handleSigint","kill","on","code","removeListener","undefined","npxHelp","encoding","includes","log","modName","purpose"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/commands/codemod.ts"],"sourcesContent":["import {execSync, spawn} from 'node:child_process'\nimport {existsSync} from 'node:fs'\nimport path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {codemods} from '../actions/codemods/index.js'\nimport {type CodeMod} from '../actions/codemods/types.js'\n\nconst codemodeDebug = subdebug('codemod')\n\nexport class CodemodCommand extends SanityCommand<typeof CodemodCommand> {\n static override args = {\n codemodName: Args.string({\n description: 'Name of the codemod to run',\n required: false,\n }),\n }\n\n static override description = 'Updates Sanity Studio codebase with a code modification script'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Show available code mods',\n },\n {\n command: '<%= config.bin %> <%= command.id %> reactIconsV3 --dry',\n description: 'Run codemod to transform react-icons imports (dry run)',\n },\n ]\n\n static override flags = {\n dry: Flags.boolean({\n default: false,\n description: 'Dry run (no changes are made to files)',\n }),\n extensions: Flags.string({\n default: 'js,ts,tsx',\n description: 'Transform files with these file extensions (comma separated)',\n }),\n 'no-verify': Flags.boolean({\n default: false,\n description: 'Skip verification steps before running codemod',\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(CodemodCommand)\n const {codemodName} = args\n const workDir = process.cwd()\n\n if (!codemodName) {\n this.printMods()\n return\n }\n\n // Make a record where all the keys of the available codemods are lowercased,\n // eg `reactIconsV3` turns into `{reacticonsv3: CodeMod}`\n const normalizedMods: Map<string, CodeMod> = new Map()\n for (const [originalName, mod] of Object.entries(codemods)) {\n normalizedMods.set(originalName.toLowerCase(), mod)\n }\n\n // Verify that mod exists\n const mod = normalizedMods.get(codemodName.toLowerCase())\n if (!mod) {\n this.error(`Codemod with name \"${codemodName}\" not found`, {exit: exitCodes.RUNTIME_ERROR})\n }\n\n // Verify if there is any verification defined, and user has not opted out of it\n if (typeof mod.verify === 'function' && !flags['no-verify']) {\n try {\n await mod.verify({workDir})\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n codemodeDebug('Verification failed: %s', err.message)\n this.error(`Verification failed: ${err.message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n // If extensions are defined, they come in as CSV, so split and normalize them\n const exts = flags.extensions\n ? flags.extensions.split(',').map((ext) => ext.trim().replace(/^\\./, ''))\n : ['js', 'ts', 'tsx']\n\n const dryRun = flags.dry\n\n // We use npx to run jscodeshift, so verify that it exists and works before using it\n this.ensureNpx()\n\n const prepared = await mod.prepare?.({output: this.output, workDir})\n // jscodeshift JSON-parses option values, so encode them to keep strings like \"2024\" as strings\n const transformOptions = Object.entries(prepared?.options ?? {}).map(\n ([key, value]) => `--${key}=${JSON.stringify(value)}`,\n )\n\n // If there is a gitignore in the target folder, we want to use that to know\n // which folders to ignore - eg `dist`, `coverage` or whatever\n const hasGitIgnore = existsSync(path.join(workDir, '.gitignore'))\n\n // Build the CLI command arguments\n const cliRoot = path.resolve(import.meta.dirname, '../..')\n const modPath = path.resolve(path.join(cliRoot, 'codemods', mod.filename))\n const cmdArgs = [\n 'jscodeshift',\n '--ignore-pattern',\n 'node_modules',\n '--ignore-pattern',\n 'dist',\n hasGitIgnore && '--ignore-config',\n hasGitIgnore && '.gitignore',\n '-t',\n modPath,\n '--extensions',\n exts.join(','),\n dryRun && '--dry',\n ...transformOptions,\n ...(prepared?.paths ?? [workDir]),\n ].filter((item): item is string => typeof item === 'string')\n\n const child = spawn('npx', cmdArgs, {\n stdio: 'inherit',\n })\n\n const handleSigint = () => {\n child.kill(2)\n }\n\n process.on('SIGINT', handleSigint)\n\n // Wait inside run() so oclif handles the exit, rather than throwing from an event callback\n const code = await new Promise<number | null>((resolve) => {\n child.on('close', resolve)\n })\n process.removeListener('SIGINT', handleSigint)\n this.exit(code || undefined)\n }\n\n private ensureNpx(): void {\n try {\n const npxHelp = execSync('npx --help', {encoding: 'utf8'})\n if (!npxHelp.includes('npm')) {\n this.error('Not the npx we expected', {exit: exitCodes.RUNTIME_ERROR})\n }\n } catch {\n this.error(\n `Failed to run \"npx\" - required to run codemods. Do you have a recent version of npm installed?`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n }\n\n private printMods(): void {\n this.log('Available code modifications:\\n')\n\n for (const [modName, mod] of Object.entries(codemods)) {\n this.log(`${modName} - ${mod.purpose}`)\n }\n }\n}\n"],"names":["execSync","spawn","existsSync","path","Args","Flags","exitCodes","SanityCommand","subdebug","codemods","codemodeDebug","CodemodCommand","args","codemodName","string","description","required","examples","command","flags","dry","boolean","default","extensions","run","parse","workDir","process","cwd","printMods","normalizedMods","Map","originalName","mod","Object","entries","set","toLowerCase","get","error","exit","RUNTIME_ERROR","verify","err","Error","String","message","exts","split","map","ext","trim","replace","dryRun","ensureNpx","prepared","prepare","output","transformOptions","options","key","value","JSON","stringify","hasGitIgnore","join","cliRoot","resolve","dirname","modPath","filename","cmdArgs","paths","filter","item","child","stdio","handleSigint","kill","on","code","Promise","removeListener","undefined","npxHelp","encoding","includes","log","modName","purpose"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Args, Flags } from '@oclif/core';
1
+ import { Args } from '@oclif/core';
2
2
  import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
3
  import { getErrorMessage } from '@sanity/cli-core/errors';
4
4
  import { isHttpError } from '@sanity/client';
@@ -13,6 +13,7 @@ export class GetKnowledgeBaseCommand extends SanityCommand {
13
13
  })
14
14
  };
15
15
  static description = 'Get details of a knowledge base';
16
+ static enableJsonFlag = true;
16
17
  static examples = [
17
18
  {
18
19
  command: '<%= config.bin %> <%= command.id %> kb-abc123',
@@ -23,12 +24,6 @@ export class GetKnowledgeBaseCommand extends SanityCommand {
23
24
  description: 'Output the knowledge base as JSON'
24
25
  }
25
26
  ];
26
- static flags = {
27
- json: Flags.boolean({
28
- default: false,
29
- description: 'Output the knowledge base in JSON format'
30
- })
31
- };
32
27
  async run() {
33
28
  const { knowledgeBaseId } = this.args;
34
29
  const { json } = this.flags;
@@ -47,7 +42,7 @@ export class GetKnowledgeBaseCommand extends SanityCommand {
47
42
  });
48
43
  }
49
44
  if (json) {
50
- this.log(JSON.stringify(knowledgeBase, null, 2));
45
+ this.logJson(knowledgeBase);
51
46
  return;
52
47
  }
53
48
  const pending = knowledgeBase.pendingChanges;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/context/get.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {formatKeyValue} from '../../actions/debug/output.js'\nimport {getKnowledgeBase} from '../../services/context.js'\n\nconst getContextDebug = subdebug('context:get')\n\nexport class GetKnowledgeBaseCommand extends SanityCommand<typeof GetKnowledgeBaseCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n }\n\n static override description = 'Get details of a knowledge base'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123',\n description: 'Get details of a specific knowledge base',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --json',\n description: 'Output the knowledge base as JSON',\n },\n ]\n\n static override flags = {\n json: Flags.boolean({\n default: false,\n description: 'Output the knowledge base in JSON format',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {knowledgeBaseId} = this.args\n const {json} = this.flags\n\n let knowledgeBase\n try {\n knowledgeBase = await getKnowledgeBase(knowledgeBaseId)\n } catch (error) {\n getContextDebug('Error getting knowledge base', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Knowledge base \"${knowledgeBaseId}\" not found`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to get knowledge base: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (json) {\n this.log(JSON.stringify(knowledgeBase, null, 2))\n return\n }\n\n const pending = knowledgeBase.pendingChanges\n const padTo = 15 // \"Pending changes\" is the longest key\n this.log(formatKeyValue('ID', knowledgeBase.publicId, {padTo}))\n this.log(formatKeyValue('Title', knowledgeBase.title, {padTo}))\n this.log(formatKeyValue('Description', knowledgeBase.description, {padTo}))\n this.log(formatKeyValue('Organization', knowledgeBase.organizationId, {padTo}))\n this.log(formatKeyValue('State', knowledgeBase.state, {padTo}))\n this.log(formatKeyValue('Active job', knowledgeBase.activeJobId ?? '-', {padTo}))\n this.log(\n formatKeyValue(\n 'Pending changes',\n pending\n ? `${pending.added} added, ${pending.changed} changed, ${pending.removed} removed`\n : '-',\n {padTo},\n ),\n )\n this.log(\n formatKeyValue(\n 'Refresh',\n knowledgeBase.refreshEnabled ? `enabled (${knowledgeBase.refreshFrequency})` : 'disabled',\n {padTo},\n ),\n )\n this.log(formatKeyValue('Open issues', knowledgeBase.openIssueCount, {padTo}))\n this.log(formatKeyValue('Instructions', knowledgeBase.instructionCount, {padTo}))\n this.log(formatKeyValue('Created', knowledgeBase.createdAt, {padTo}))\n this.log(formatKeyValue('Updated', knowledgeBase.updatedAt, {padTo}))\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","formatKeyValue","getKnowledgeBase","getContextDebug","GetKnowledgeBaseCommand","args","knowledgeBaseId","string","description","required","examples","command","flags","json","boolean","default","run","knowledgeBase","error","statusCode","exit","RUNTIME_ERROR","log","JSON","stringify","pending","pendingChanges","padTo","publicId","title","organizationId","state","activeJobId","added","changed","removed","refreshEnabled","refreshFrequency","openIssueCount","instructionCount","createdAt","updatedAt"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/commands/context/get.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {formatKeyValue} from '../../actions/debug/output.js'\nimport {getKnowledgeBase} from '../../services/context.js'\n\nconst getContextDebug = subdebug('context:get')\n\nexport class GetKnowledgeBaseCommand extends SanityCommand<typeof GetKnowledgeBaseCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n }\n\n static override description = 'Get details of a knowledge base'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123',\n description: 'Get details of a specific knowledge base',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --json',\n description: 'Output the knowledge base as JSON',\n },\n ]\n\n public async run(): Promise<void> {\n const {knowledgeBaseId} = this.args\n const {json} = this.flags\n\n let knowledgeBase\n try {\n knowledgeBase = await getKnowledgeBase(knowledgeBaseId)\n } catch (error) {\n getContextDebug('Error getting knowledge base', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Knowledge base \"${knowledgeBaseId}\" not found`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to get knowledge base: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (json) {\n this.logJson(knowledgeBase)\n return\n }\n\n const pending = knowledgeBase.pendingChanges\n const padTo = 15 // \"Pending changes\" is the longest key\n this.log(formatKeyValue('ID', knowledgeBase.publicId, {padTo}))\n this.log(formatKeyValue('Title', knowledgeBase.title, {padTo}))\n this.log(formatKeyValue('Description', knowledgeBase.description, {padTo}))\n this.log(formatKeyValue('Organization', knowledgeBase.organizationId, {padTo}))\n this.log(formatKeyValue('State', knowledgeBase.state, {padTo}))\n this.log(formatKeyValue('Active job', knowledgeBase.activeJobId ?? '-', {padTo}))\n this.log(\n formatKeyValue(\n 'Pending changes',\n pending\n ? `${pending.added} added, ${pending.changed} changed, ${pending.removed} removed`\n : '-',\n {padTo},\n ),\n )\n this.log(\n formatKeyValue(\n 'Refresh',\n knowledgeBase.refreshEnabled ? `enabled (${knowledgeBase.refreshFrequency})` : 'disabled',\n {padTo},\n ),\n )\n this.log(formatKeyValue('Open issues', knowledgeBase.openIssueCount, {padTo}))\n this.log(formatKeyValue('Instructions', knowledgeBase.instructionCount, {padTo}))\n this.log(formatKeyValue('Created', knowledgeBase.createdAt, {padTo}))\n this.log(formatKeyValue('Updated', knowledgeBase.updatedAt, {padTo}))\n }\n}\n"],"names":["Args","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","formatKeyValue","getKnowledgeBase","getContextDebug","GetKnowledgeBaseCommand","args","knowledgeBaseId","string","description","required","enableJsonFlag","examples","command","run","json","flags","knowledgeBase","error","statusCode","exit","RUNTIME_ERROR","logJson","pending","pendingChanges","padTo","log","publicId","title","organizationId","state","activeJobId","added","changed","removed","refreshEnabled","refreshFrequency","openIssueCount","instructionCount","createdAt","updatedAt"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Args, Flags } from '@oclif/core';
1
+ import { Args } from '@oclif/core';
2
2
  import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
3
  import { getErrorMessage } from '@sanity/cli-core/errors';
4
4
  import { isHttpError } from '@sanity/client';
@@ -18,18 +18,13 @@ export class DownloadImportCommand extends SanityCommand {
18
18
  })
19
19
  };
20
20
  static description = 'Get a short-lived signed URL for the original uploaded bytes of a file import';
21
+ static enableJsonFlag = true;
21
22
  static examples = [
22
23
  {
23
24
  command: '<%= config.bin %> <%= command.id %> kb-abc123 import-def456',
24
25
  description: 'Get a download URL for an uploaded file'
25
26
  }
26
27
  ];
27
- static flags = {
28
- json: Flags.boolean({
29
- default: false,
30
- description: 'Output the download URL in JSON format'
31
- })
32
- };
33
28
  async run() {
34
29
  const { importId, knowledgeBaseId } = this.args;
35
30
  const { json } = this.flags;
@@ -48,7 +43,7 @@ export class DownloadImportCommand extends SanityCommand {
48
43
  });
49
44
  }
50
45
  if (json) {
51
- this.log(JSON.stringify(download, null, 2));
46
+ this.logJson(download);
52
47
  return;
53
48
  }
54
49
  const padTo = 7 // "Expires" is the longest key
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/context/imports/download.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {formatKeyValue} from '../../../actions/debug/output.js'\nimport {downloadImport} from '../../../services/context.js'\n\nconst downloadImportDebug = subdebug('context:imports:download')\n\nexport class DownloadImportCommand extends SanityCommand<typeof DownloadImportCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n importId: Args.string({\n description: 'Import ID',\n required: true,\n }),\n }\n\n static override description =\n 'Get a short-lived signed URL for the original uploaded bytes of a file import'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 import-def456',\n description: 'Get a download URL for an uploaded file',\n },\n ]\n\n static override flags = {\n json: Flags.boolean({\n default: false,\n description: 'Output the download URL in JSON format',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {importId, knowledgeBaseId} = this.args\n const {json} = this.flags\n\n let download\n try {\n download = await downloadImport(knowledgeBaseId, importId)\n } catch (error) {\n downloadImportDebug('Error getting import download URL', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Import \"${importId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to get import download URL: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (json) {\n this.log(JSON.stringify(download, null, 2))\n return\n }\n\n const padTo = 7 // \"Expires\" is the longest key\n this.log(formatKeyValue('URL', download.url, {padTo}))\n this.log(formatKeyValue('Expires', download.expiresAt, {padTo}))\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","formatKeyValue","downloadImport","downloadImportDebug","DownloadImportCommand","args","knowledgeBaseId","string","description","required","importId","examples","command","flags","json","boolean","default","run","download","error","statusCode","exit","RUNTIME_ERROR","log","JSON","stringify","padTo","url","expiresAt"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AAEvC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,cAAc,QAAO,mCAAkC;AAC/D,SAAQC,cAAc,QAAO,+BAA8B;AAE3D,MAAMC,sBAAsBL,SAAS;AAErC,OAAO,MAAMM,8BAA8BP;IACzC,OAAgBQ,OAAO;QACrBC,iBAAiBZ,KAAKa,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;QACA,gGAAgG;QAChGC,UAAUhB,KAAKa,MAAM,CAAC;YACpBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cACd,gFAA+E;IAEjF,OAAgBG,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa;QACf;KACD,CAAA;IAED,OAAgBK,QAAQ;QACtBC,MAAMnB,MAAMoB,OAAO,CAAC;YAClBC,SAAS;YACTR,aAAa;QACf;IACF,EAAqB;IAErB,MAAaS,MAAqB;QAChC,MAAM,EAACP,QAAQ,EAAEJ,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QAC7C,MAAM,EAACS,IAAI,EAAC,GAAG,IAAI,CAACD,KAAK;QAEzB,IAAIK;QACJ,IAAI;YACFA,WAAW,MAAMhB,eAAeI,iBAAiBI;QACnD,EAAE,OAAOS,OAAO;YACdhB,oBAAoB,qCAAqCgB;YACzD,IAAInB,YAAYmB,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,QAAQ,EAAET,SAAS,+BAA+B,EAAEJ,gBAAgB,CAAC,CAAC,EAAE;oBAClFe,MAAMzB,UAAU0B,aAAa;gBAC/B;YACF;YACA,IAAI,CAACH,KAAK,CAAC,CAAC,mCAAmC,EAAEpB,gBAAgBoB,QAAQ,EAAE;gBACzEE,MAAMzB,UAAU0B,aAAa;YAC/B;QACF;QAEA,IAAIR,MAAM;YACR,IAAI,CAACS,GAAG,CAACC,KAAKC,SAAS,CAACP,UAAU,MAAM;YACxC;QACF;QAEA,MAAMQ,QAAQ,EAAE,+BAA+B;;QAC/C,IAAI,CAACH,GAAG,CAACtB,eAAe,OAAOiB,SAASS,GAAG,EAAE;YAACD;QAAK;QACnD,IAAI,CAACH,GAAG,CAACtB,eAAe,WAAWiB,SAASU,SAAS,EAAE;YAACF;QAAK;IAC/D;AACF"}
1
+ {"version":3,"sources":["../../../../src/commands/context/imports/download.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {formatKeyValue} from '../../../actions/debug/output.js'\nimport {downloadImport} from '../../../services/context.js'\n\nconst downloadImportDebug = subdebug('context:imports:download')\n\nexport class DownloadImportCommand extends SanityCommand<typeof DownloadImportCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n importId: Args.string({\n description: 'Import ID',\n required: true,\n }),\n }\n\n static override description =\n 'Get a short-lived signed URL for the original uploaded bytes of a file import'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 import-def456',\n description: 'Get a download URL for an uploaded file',\n },\n ]\n\n public async run(): Promise<void> {\n const {importId, knowledgeBaseId} = this.args\n const {json} = this.flags\n\n let download\n try {\n download = await downloadImport(knowledgeBaseId, importId)\n } catch (error) {\n downloadImportDebug('Error getting import download URL', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Import \"${importId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to get import download URL: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (json) {\n this.logJson(download)\n return\n }\n\n const padTo = 7 // \"Expires\" is the longest key\n this.log(formatKeyValue('URL', download.url, {padTo}))\n this.log(formatKeyValue('Expires', download.expiresAt, {padTo}))\n }\n}\n"],"names":["Args","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","formatKeyValue","downloadImport","downloadImportDebug","DownloadImportCommand","args","knowledgeBaseId","string","description","required","importId","enableJsonFlag","examples","command","run","json","flags","download","error","statusCode","exit","RUNTIME_ERROR","logJson","padTo","log","url","expiresAt"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,cAAc,QAAO,mCAAkC;AAC/D,SAAQC,cAAc,QAAO,+BAA8B;AAE3D,MAAMC,sBAAsBL,SAAS;AAErC,OAAO,MAAMM,8BAA8BP;IACzC,OAAgBQ,OAAO;QACrBC,iBAAiBX,KAAKY,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;QACA,gGAAgG;QAChGC,UAAUf,KAAKY,MAAM,CAAC;YACpBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cACd,gFAA+E;IAEjF,OAAgBG,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTL,aAAa;QACf;KACD,CAAA;IAED,MAAaM,MAAqB;QAChC,MAAM,EAACJ,QAAQ,EAAEJ,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QAC7C,MAAM,EAACU,IAAI,EAAC,GAAG,IAAI,CAACC,KAAK;QAEzB,IAAIC;QACJ,IAAI;YACFA,WAAW,MAAMf,eAAeI,iBAAiBI;QACnD,EAAE,OAAOQ,OAAO;YACdf,oBAAoB,qCAAqCe;YACzD,IAAIlB,YAAYkB,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,QAAQ,EAAER,SAAS,+BAA+B,EAAEJ,gBAAgB,CAAC,CAAC,EAAE;oBAClFc,MAAMxB,UAAUyB,aAAa;gBAC/B;YACF;YACA,IAAI,CAACH,KAAK,CAAC,CAAC,mCAAmC,EAAEnB,gBAAgBmB,QAAQ,EAAE;gBACzEE,MAAMxB,UAAUyB,aAAa;YAC/B;QACF;QAEA,IAAIN,MAAM;YACR,IAAI,CAACO,OAAO,CAACL;YACb;QACF;QAEA,MAAMM,QAAQ,EAAE,+BAA+B;;QAC/C,IAAI,CAACC,GAAG,CAACvB,eAAe,OAAOgB,SAASQ,GAAG,EAAE;YAACF;QAAK;QACnD,IAAI,CAACC,GAAG,CAACvB,eAAe,WAAWgB,SAASS,SAAS,EAAE;YAACH;QAAK;IAC/D;AACF"}
@@ -1,4 +1,4 @@
1
- import { Args, Flags } from '@oclif/core';
1
+ import { Args } from '@oclif/core';
2
2
  import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
3
  import { getErrorMessage } from '@sanity/cli-core/errors';
4
4
  import { isHttpError } from '@sanity/client';
@@ -18,6 +18,7 @@ export class GetImportCommand extends SanityCommand {
18
18
  })
19
19
  };
20
20
  static description = 'Get details of an import';
21
+ static enableJsonFlag = true;
21
22
  static examples = [
22
23
  {
23
24
  command: '<%= config.bin %> <%= command.id %> kb-abc123 import-def456',
@@ -28,12 +29,6 @@ export class GetImportCommand extends SanityCommand {
28
29
  description: 'Output the import as JSON'
29
30
  }
30
31
  ];
31
- static flags = {
32
- json: Flags.boolean({
33
- default: false,
34
- description: 'Output the import in JSON format'
35
- })
36
- };
37
32
  async run() {
38
33
  const { importId, knowledgeBaseId } = this.args;
39
34
  const { json } = this.flags;
@@ -52,7 +47,7 @@ export class GetImportCommand extends SanityCommand {
52
47
  });
53
48
  }
54
49
  if (json) {
55
- this.log(JSON.stringify(importDetail, null, 2));
50
+ this.logJson(importDetail);
56
51
  return;
57
52
  }
58
53
  const padTo = 9 // "Completed" is the longest key
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/context/imports/get.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {formatKeyValue} from '../../../actions/debug/output.js'\nimport {getImport} from '../../../services/context.js'\n\nconst getImportDebug = subdebug('context:imports:get')\n\nexport class GetImportCommand extends SanityCommand<typeof GetImportCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n importId: Args.string({\n description: 'Import ID',\n required: true,\n }),\n }\n\n static override description = 'Get details of an import'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 import-def456',\n description: 'Get details of a specific import',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 import-def456 --json',\n description: 'Output the import as JSON',\n },\n ]\n\n static override flags = {\n json: Flags.boolean({\n default: false,\n description: 'Output the import in JSON format',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {importId, knowledgeBaseId} = this.args\n const {json} = this.flags\n\n let importDetail\n try {\n importDetail = await getImport(knowledgeBaseId, importId)\n } catch (error) {\n getImportDebug('Error getting import', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Import \"${importId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to get import: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (json) {\n this.log(JSON.stringify(importDetail, null, 2))\n return\n }\n\n const padTo = 9 // \"Completed\" is the longest key\n this.log(formatKeyValue('ID', importDetail.id, {padTo}))\n this.log(formatKeyValue('Name', importDetail.name ?? '-', {padTo}))\n this.log(formatKeyValue('Kind', importDetail.sourceKind, {padTo}))\n this.log(formatKeyValue('Status', importDetail.status, {padTo}))\n this.log(formatKeyValue('Detail', importDetail.statusDetail ?? '-', {padTo}))\n this.log(formatKeyValue('Error', importDetail.error ?? '-', {padTo}))\n this.log(formatKeyValue('Sources', importDetail.sourceCount, {padTo}))\n this.log(\n formatKeyValue(\n 'Distilled',\n `${importDetail.distilledCount}/${importDetail.totalDistillableCount}`,\n {padTo},\n ),\n )\n this.log(formatKeyValue('Created', importDetail.createdAt, {padTo}))\n this.log(formatKeyValue('Completed', importDetail.completedAt ?? '-', {padTo}))\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","formatKeyValue","getImport","getImportDebug","GetImportCommand","args","knowledgeBaseId","string","description","required","importId","examples","command","flags","json","boolean","default","run","importDetail","error","statusCode","exit","RUNTIME_ERROR","log","JSON","stringify","padTo","id","name","sourceKind","status","statusDetail","sourceCount","distilledCount","totalDistillableCount","createdAt","completedAt"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AAEvC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,cAAc,QAAO,mCAAkC;AAC/D,SAAQC,SAAS,QAAO,+BAA8B;AAEtD,MAAMC,iBAAiBL,SAAS;AAEhC,OAAO,MAAMM,yBAAyBP;IACpC,OAAgBQ,OAAO;QACrBC,iBAAiBZ,KAAKa,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;QACA,gGAAgG;QAChGC,UAAUhB,KAAKa,MAAM,CAAC;YACpBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,2BAA0B;IAExD,OAAgBG,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;KACD,CAAA;IAED,OAAgBK,QAAQ;QACtBC,MAAMnB,MAAMoB,OAAO,CAAC;YAClBC,SAAS;YACTR,aAAa;QACf;IACF,EAAqB;IAErB,MAAaS,MAAqB;QAChC,MAAM,EAACP,QAAQ,EAAEJ,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QAC7C,MAAM,EAACS,IAAI,EAAC,GAAG,IAAI,CAACD,KAAK;QAEzB,IAAIK;QACJ,IAAI;YACFA,eAAe,MAAMhB,UAAUI,iBAAiBI;QAClD,EAAE,OAAOS,OAAO;YACdhB,eAAe,wBAAwBgB;YACvC,IAAInB,YAAYmB,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,QAAQ,EAAET,SAAS,+BAA+B,EAAEJ,gBAAgB,CAAC,CAAC,EAAE;oBAClFe,MAAMzB,UAAU0B,aAAa;gBAC/B;YACF;YACA,IAAI,CAACH,KAAK,CAAC,CAAC,sBAAsB,EAAEpB,gBAAgBoB,QAAQ,EAAE;gBAC5DE,MAAMzB,UAAU0B,aAAa;YAC/B;QACF;QAEA,IAAIR,MAAM;YACR,IAAI,CAACS,GAAG,CAACC,KAAKC,SAAS,CAACP,cAAc,MAAM;YAC5C;QACF;QAEA,MAAMQ,QAAQ,EAAE,iCAAiC;;QACjD,IAAI,CAACH,GAAG,CAACtB,eAAe,MAAMiB,aAAaS,EAAE,EAAE;YAACD;QAAK;QACrD,IAAI,CAACH,GAAG,CAACtB,eAAe,QAAQiB,aAAaU,IAAI,IAAI,KAAK;YAACF;QAAK;QAChE,IAAI,CAACH,GAAG,CAACtB,eAAe,QAAQiB,aAAaW,UAAU,EAAE;YAACH;QAAK;QAC/D,IAAI,CAACH,GAAG,CAACtB,eAAe,UAAUiB,aAAaY,MAAM,EAAE;YAACJ;QAAK;QAC7D,IAAI,CAACH,GAAG,CAACtB,eAAe,UAAUiB,aAAaa,YAAY,IAAI,KAAK;YAACL;QAAK;QAC1E,IAAI,CAACH,GAAG,CAACtB,eAAe,SAASiB,aAAaC,KAAK,IAAI,KAAK;YAACO;QAAK;QAClE,IAAI,CAACH,GAAG,CAACtB,eAAe,WAAWiB,aAAac,WAAW,EAAE;YAACN;QAAK;QACnE,IAAI,CAACH,GAAG,CACNtB,eACE,aACA,GAAGiB,aAAae,cAAc,CAAC,CAAC,EAAEf,aAAagB,qBAAqB,EAAE,EACtE;YAACR;QAAK;QAGV,IAAI,CAACH,GAAG,CAACtB,eAAe,WAAWiB,aAAaiB,SAAS,EAAE;YAACT;QAAK;QACjE,IAAI,CAACH,GAAG,CAACtB,eAAe,aAAaiB,aAAakB,WAAW,IAAI,KAAK;YAACV;QAAK;IAC9E;AACF"}
1
+ {"version":3,"sources":["../../../../src/commands/context/imports/get.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {formatKeyValue} from '../../../actions/debug/output.js'\nimport {getImport} from '../../../services/context.js'\n\nconst getImportDebug = subdebug('context:imports:get')\n\nexport class GetImportCommand extends SanityCommand<typeof GetImportCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n importId: Args.string({\n description: 'Import ID',\n required: true,\n }),\n }\n\n static override description = 'Get details of an import'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 import-def456',\n description: 'Get details of a specific import',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 import-def456 --json',\n description: 'Output the import as JSON',\n },\n ]\n\n public async run(): Promise<void> {\n const {importId, knowledgeBaseId} = this.args\n const {json} = this.flags\n\n let importDetail\n try {\n importDetail = await getImport(knowledgeBaseId, importId)\n } catch (error) {\n getImportDebug('Error getting import', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Import \"${importId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to get import: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (json) {\n this.logJson(importDetail)\n return\n }\n\n const padTo = 9 // \"Completed\" is the longest key\n this.log(formatKeyValue('ID', importDetail.id, {padTo}))\n this.log(formatKeyValue('Name', importDetail.name ?? '-', {padTo}))\n this.log(formatKeyValue('Kind', importDetail.sourceKind, {padTo}))\n this.log(formatKeyValue('Status', importDetail.status, {padTo}))\n this.log(formatKeyValue('Detail', importDetail.statusDetail ?? '-', {padTo}))\n this.log(formatKeyValue('Error', importDetail.error ?? '-', {padTo}))\n this.log(formatKeyValue('Sources', importDetail.sourceCount, {padTo}))\n this.log(\n formatKeyValue(\n 'Distilled',\n `${importDetail.distilledCount}/${importDetail.totalDistillableCount}`,\n {padTo},\n ),\n )\n this.log(formatKeyValue('Created', importDetail.createdAt, {padTo}))\n this.log(formatKeyValue('Completed', importDetail.completedAt ?? '-', {padTo}))\n }\n}\n"],"names":["Args","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","formatKeyValue","getImport","getImportDebug","GetImportCommand","args","knowledgeBaseId","string","description","required","importId","enableJsonFlag","examples","command","run","json","flags","importDetail","error","statusCode","exit","RUNTIME_ERROR","logJson","padTo","log","id","name","sourceKind","status","statusDetail","sourceCount","distilledCount","totalDistillableCount","createdAt","completedAt"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,cAAc,QAAO,mCAAkC;AAC/D,SAAQC,SAAS,QAAO,+BAA8B;AAEtD,MAAMC,iBAAiBL,SAAS;AAEhC,OAAO,MAAMM,yBAAyBP;IACpC,OAAgBQ,OAAO;QACrBC,iBAAiBX,KAAKY,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;QACA,gGAAgG;QAChGC,UAAUf,KAAKY,MAAM,CAAC;YACpBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,2BAA0B;IAExD,OAAgBG,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTL,aAAa;QACf;QACA;YACEK,SAAS;YACTL,aAAa;QACf;KACD,CAAA;IAED,MAAaM,MAAqB;QAChC,MAAM,EAACJ,QAAQ,EAAEJ,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QAC7C,MAAM,EAACU,IAAI,EAAC,GAAG,IAAI,CAACC,KAAK;QAEzB,IAAIC;QACJ,IAAI;YACFA,eAAe,MAAMf,UAAUI,iBAAiBI;QAClD,EAAE,OAAOQ,OAAO;YACdf,eAAe,wBAAwBe;YACvC,IAAIlB,YAAYkB,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,QAAQ,EAAER,SAAS,+BAA+B,EAAEJ,gBAAgB,CAAC,CAAC,EAAE;oBAClFc,MAAMxB,UAAUyB,aAAa;gBAC/B;YACF;YACA,IAAI,CAACH,KAAK,CAAC,CAAC,sBAAsB,EAAEnB,gBAAgBmB,QAAQ,EAAE;gBAC5DE,MAAMxB,UAAUyB,aAAa;YAC/B;QACF;QAEA,IAAIN,MAAM;YACR,IAAI,CAACO,OAAO,CAACL;YACb;QACF;QAEA,MAAMM,QAAQ,EAAE,iCAAiC;;QACjD,IAAI,CAACC,GAAG,CAACvB,eAAe,MAAMgB,aAAaQ,EAAE,EAAE;YAACF;QAAK;QACrD,IAAI,CAACC,GAAG,CAACvB,eAAe,QAAQgB,aAAaS,IAAI,IAAI,KAAK;YAACH;QAAK;QAChE,IAAI,CAACC,GAAG,CAACvB,eAAe,QAAQgB,aAAaU,UAAU,EAAE;YAACJ;QAAK;QAC/D,IAAI,CAACC,GAAG,CAACvB,eAAe,UAAUgB,aAAaW,MAAM,EAAE;YAACL;QAAK;QAC7D,IAAI,CAACC,GAAG,CAACvB,eAAe,UAAUgB,aAAaY,YAAY,IAAI,KAAK;YAACN;QAAK;QAC1E,IAAI,CAACC,GAAG,CAACvB,eAAe,SAASgB,aAAaC,KAAK,IAAI,KAAK;YAACK;QAAK;QAClE,IAAI,CAACC,GAAG,CAACvB,eAAe,WAAWgB,aAAaa,WAAW,EAAE;YAACP;QAAK;QACnE,IAAI,CAACC,GAAG,CACNvB,eACE,aACA,GAAGgB,aAAac,cAAc,CAAC,CAAC,EAAEd,aAAae,qBAAqB,EAAE,EACtE;YAACT;QAAK;QAGV,IAAI,CAACC,GAAG,CAACvB,eAAe,WAAWgB,aAAagB,SAAS,EAAE;YAACV;QAAK;QACjE,IAAI,CAACC,GAAG,CAACvB,eAAe,aAAagB,aAAaiB,WAAW,IAAI,KAAK;YAACX;QAAK;IAC9E;AACF"}
@@ -1,4 +1,4 @@
1
- import { Args, Flags } from '@oclif/core';
1
+ import { Args } from '@oclif/core';
2
2
  import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
3
  import { getErrorMessage } from '@sanity/cli-core/errors';
4
4
  import { isHttpError } from '@sanity/client';
@@ -13,6 +13,7 @@ export class ListImportsCommand extends SanityCommand {
13
13
  })
14
14
  };
15
15
  static description = 'List imports for a knowledge base';
16
+ static enableJsonFlag = true;
16
17
  static examples = [
17
18
  {
18
19
  command: '<%= config.bin %> <%= command.id %> kb-abc123',
@@ -23,12 +24,6 @@ export class ListImportsCommand extends SanityCommand {
23
24
  description: 'Output imports as JSON'
24
25
  }
25
26
  ];
26
- static flags = {
27
- json: Flags.boolean({
28
- default: false,
29
- description: 'Output imports in JSON format'
30
- })
31
- };
32
27
  async run() {
33
28
  const { knowledgeBaseId } = this.args;
34
29
  const { json } = this.flags;
@@ -47,7 +42,7 @@ export class ListImportsCommand extends SanityCommand {
47
42
  });
48
43
  }
49
44
  if (json) {
50
- this.log(JSON.stringify(imports, null, 2));
45
+ this.logJson(imports);
51
46
  return;
52
47
  }
53
48
  if (imports.length === 0) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/context/imports/list.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {listImports} from '../../../services/context.js'\nimport {Table} from '../../../util/responsiveTable.js'\n\nconst listImportsDebug = subdebug('context:imports:list')\n\nexport class ListImportsCommand extends SanityCommand<typeof ListImportsCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n }\n\n static override description = 'List imports for a knowledge base'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123',\n description: 'List all imports for a knowledge base',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --json',\n description: 'Output imports as JSON',\n },\n ]\n\n static override flags = {\n json: Flags.boolean({\n default: false,\n description: 'Output imports in JSON format',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {knowledgeBaseId} = this.args\n const {json} = this.flags\n\n let imports\n try {\n imports = await listImports(knowledgeBaseId)\n } catch (error) {\n listImportsDebug('Error listing imports', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Knowledge base \"${knowledgeBaseId}\" not found`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to list imports: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (json) {\n this.log(JSON.stringify(imports, null, 2))\n return\n }\n\n if (imports.length === 0) {\n this.log('No imports found')\n return\n }\n\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'id', title: 'ID'},\n {alignment: 'left', name: 'name', title: 'Name'},\n {alignment: 'left', name: 'kind', title: 'Kind'},\n {alignment: 'left', name: 'status', title: 'Status'},\n {alignment: 'right', name: 'sources', title: 'Sources'},\n {alignment: 'left', name: 'createdAt', title: 'Created'},\n ],\n })\n\n for (const {createdAt, id, name, sourceCount, sourceKind, status} of imports) {\n table.addRow({\n createdAt,\n id,\n kind: sourceKind,\n name: name ?? '-',\n sources: sourceCount,\n status,\n })\n }\n\n this.log(table.render())\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","listImports","Table","listImportsDebug","ListImportsCommand","args","knowledgeBaseId","string","description","required","examples","command","flags","json","boolean","default","run","imports","error","statusCode","exit","RUNTIME_ERROR","log","JSON","stringify","length","table","columns","alignment","name","title","createdAt","id","sourceCount","sourceKind","status","addRow","kind","sources","render"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AAEvC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,WAAW,QAAO,+BAA8B;AACxD,SAAQC,KAAK,QAAO,mCAAkC;AAEtD,MAAMC,mBAAmBL,SAAS;AAElC,OAAO,MAAMM,2BAA2BP;IACtC,OAAgBQ,OAAO;QACrBC,iBAAiBZ,KAAKa,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,oCAAmC;IAEjE,OAAgBE,WAAW;QACzB;YACEC,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IAED,OAAgBI,QAAQ;QACtBC,MAAMlB,MAAMmB,OAAO,CAAC;YAClBC,SAAS;YACTP,aAAa;QACf;IACF,EAAqB;IAErB,MAAaQ,MAAqB;QAChC,MAAM,EAACV,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QACnC,MAAM,EAACQ,IAAI,EAAC,GAAG,IAAI,CAACD,KAAK;QAEzB,IAAIK;QACJ,IAAI;YACFA,UAAU,MAAMhB,YAAYK;QAC9B,EAAE,OAAOY,OAAO;YACdf,iBAAiB,yBAAyBe;YAC1C,IAAIlB,YAAYkB,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,gBAAgB,EAAEZ,gBAAgB,WAAW,CAAC,EAAE;oBAC1Dc,MAAMxB,UAAUyB,aAAa;gBAC/B;YACF;YACA,IAAI,CAACH,KAAK,CAAC,CAAC,wBAAwB,EAAEnB,gBAAgBmB,QAAQ,EAAE;gBAC9DE,MAAMxB,UAAUyB,aAAa;YAC/B;QACF;QAEA,IAAIR,MAAM;YACR,IAAI,CAACS,GAAG,CAACC,KAAKC,SAAS,CAACP,SAAS,MAAM;YACvC;QACF;QAEA,IAAIA,QAAQQ,MAAM,KAAK,GAAG;YACxB,IAAI,CAACH,GAAG,CAAC;YACT;QACF;QAEA,MAAMI,QAAQ,IAAIxB,MAAM;YACtByB,SAAS;gBACP;oBAACC,WAAW;oBAAQC,MAAM;oBAAMC,OAAO;gBAAI;gBAC3C;oBAACF,WAAW;oBAAQC,MAAM;oBAAQC,OAAO;gBAAM;gBAC/C;oBAACF,WAAW;oBAAQC,MAAM;oBAAQC,OAAO;gBAAM;gBAC/C;oBAACF,WAAW;oBAAQC,MAAM;oBAAUC,OAAO;gBAAQ;gBACnD;oBAACF,WAAW;oBAASC,MAAM;oBAAWC,OAAO;gBAAS;gBACtD;oBAACF,WAAW;oBAAQC,MAAM;oBAAaC,OAAO;gBAAS;aACxD;QACH;QAEA,KAAK,MAAM,EAACC,SAAS,EAAEC,EAAE,EAAEH,IAAI,EAAEI,WAAW,EAAEC,UAAU,EAAEC,MAAM,EAAC,IAAIlB,QAAS;YAC5ES,MAAMU,MAAM,CAAC;gBACXL;gBACAC;gBACAK,MAAMH;gBACNL,MAAMA,QAAQ;gBACdS,SAASL;gBACTE;YACF;QACF;QAEA,IAAI,CAACb,GAAG,CAACI,MAAMa,MAAM;IACvB;AACF"}
1
+ {"version":3,"sources":["../../../../src/commands/context/imports/list.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {listImports} from '../../../services/context.js'\nimport {Table} from '../../../util/responsiveTable.js'\n\nconst listImportsDebug = subdebug('context:imports:list')\n\nexport class ListImportsCommand extends SanityCommand<typeof ListImportsCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n }\n\n static override description = 'List imports for a knowledge base'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123',\n description: 'List all imports for a knowledge base',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --json',\n description: 'Output imports as JSON',\n },\n ]\n\n public async run(): Promise<void> {\n const {knowledgeBaseId} = this.args\n const {json} = this.flags\n\n let imports\n try {\n imports = await listImports(knowledgeBaseId)\n } catch (error) {\n listImportsDebug('Error listing imports', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Knowledge base \"${knowledgeBaseId}\" not found`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to list imports: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (json) {\n this.logJson(imports)\n return\n }\n\n if (imports.length === 0) {\n this.log('No imports found')\n return\n }\n\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'id', title: 'ID'},\n {alignment: 'left', name: 'name', title: 'Name'},\n {alignment: 'left', name: 'kind', title: 'Kind'},\n {alignment: 'left', name: 'status', title: 'Status'},\n {alignment: 'right', name: 'sources', title: 'Sources'},\n {alignment: 'left', name: 'createdAt', title: 'Created'},\n ],\n })\n\n for (const {createdAt, id, name, sourceCount, sourceKind, status} of imports) {\n table.addRow({\n createdAt,\n id,\n kind: sourceKind,\n name: name ?? '-',\n sources: sourceCount,\n status,\n })\n }\n\n this.log(table.render())\n }\n}\n"],"names":["Args","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","listImports","Table","listImportsDebug","ListImportsCommand","args","knowledgeBaseId","string","description","required","enableJsonFlag","examples","command","run","json","flags","imports","error","statusCode","exit","RUNTIME_ERROR","logJson","length","log","table","columns","alignment","name","title","createdAt","id","sourceCount","sourceKind","status","addRow","kind","sources","render"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,WAAW,QAAO,+BAA8B;AACxD,SAAQC,KAAK,QAAO,mCAAkC;AAEtD,MAAMC,mBAAmBL,SAAS;AAElC,OAAO,MAAMM,2BAA2BP;IACtC,OAAgBQ,OAAO;QACrBC,iBAAiBX,KAAKY,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,oCAAmC;IAEjE,OAAgBE,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;KACD,CAAA;IAED,MAAaK,MAAqB;QAChC,MAAM,EAACP,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QACnC,MAAM,EAACS,IAAI,EAAC,GAAG,IAAI,CAACC,KAAK;QAEzB,IAAIC;QACJ,IAAI;YACFA,UAAU,MAAMf,YAAYK;QAC9B,EAAE,OAAOW,OAAO;YACdd,iBAAiB,yBAAyBc;YAC1C,IAAIjB,YAAYiB,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,gBAAgB,EAAEX,gBAAgB,WAAW,CAAC,EAAE;oBAC1Da,MAAMvB,UAAUwB,aAAa;gBAC/B;YACF;YACA,IAAI,CAACH,KAAK,CAAC,CAAC,wBAAwB,EAAElB,gBAAgBkB,QAAQ,EAAE;gBAC9DE,MAAMvB,UAAUwB,aAAa;YAC/B;QACF;QAEA,IAAIN,MAAM;YACR,IAAI,CAACO,OAAO,CAACL;YACb;QACF;QAEA,IAAIA,QAAQM,MAAM,KAAK,GAAG;YACxB,IAAI,CAACC,GAAG,CAAC;YACT;QACF;QAEA,MAAMC,QAAQ,IAAItB,MAAM;YACtBuB,SAAS;gBACP;oBAACC,WAAW;oBAAQC,MAAM;oBAAMC,OAAO;gBAAI;gBAC3C;oBAACF,WAAW;oBAAQC,MAAM;oBAAQC,OAAO;gBAAM;gBAC/C;oBAACF,WAAW;oBAAQC,MAAM;oBAAQC,OAAO;gBAAM;gBAC/C;oBAACF,WAAW;oBAAQC,MAAM;oBAAUC,OAAO;gBAAQ;gBACnD;oBAACF,WAAW;oBAASC,MAAM;oBAAWC,OAAO;gBAAS;gBACtD;oBAACF,WAAW;oBAAQC,MAAM;oBAAaC,OAAO;gBAAS;aACxD;QACH;QAEA,KAAK,MAAM,EAACC,SAAS,EAAEC,EAAE,EAAEH,IAAI,EAAEI,WAAW,EAAEC,UAAU,EAAEC,MAAM,EAAC,IAAIjB,QAAS;YAC5EQ,MAAMU,MAAM,CAAC;gBACXL;gBACAC;gBACAK,MAAMH;gBACNL,MAAMA,QAAQ;gBACdS,SAASL;gBACTE;YACF;QACF;QAEA,IAAI,CAACV,GAAG,CAACC,MAAMa,MAAM;IACvB;AACF"}
@@ -1,6 +1,6 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
2
  import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
3
- import { getErrorMessage } from '@sanity/cli-core/errors';
3
+ import { getErrorMessage, JsonOutputError } from '@sanity/cli-core/errors';
4
4
  import { isHttpError } from '@sanity/client';
5
5
  import { watchJob } from '../../../actions/context/watchJob.js';
6
6
  import { formatKeyValue } from '../../../actions/debug/output.js';
@@ -19,6 +19,7 @@ export class GetJobCommand extends SanityCommand {
19
19
  })
20
20
  };
21
21
  static description = 'Get the status of a knowledge base job';
22
+ static enableJsonFlag = true;
22
23
  static examples = [
23
24
  {
24
25
  command: '<%= config.bin %> <%= command.id %> kb-abc123 job-def456',
@@ -30,10 +31,6 @@ export class GetJobCommand extends SanityCommand {
30
31
  }
31
32
  ];
32
33
  static flags = {
33
- json: Flags.boolean({
34
- default: false,
35
- description: 'Output the job in JSON format'
36
- }),
37
34
  watch: Flags.boolean({
38
35
  default: false,
39
36
  description: 'Poll until the job reaches a terminal state'
@@ -58,8 +55,11 @@ export class GetJobCommand extends SanityCommand {
58
55
  exit: exitCodes.RUNTIME_ERROR
59
56
  });
60
57
  }
58
+ const jobFailed = watch && job.status !== 'succeeded';
59
+ const failureMessage = `Job ${job.status}${job.error ? `: ${job.error}` : ''}`;
61
60
  if (json) {
62
- this.log(JSON.stringify(job, null, 2));
61
+ if (jobFailed) throw new JsonOutputError(failureMessage, job, exitCodes.RUNTIME_ERROR);
62
+ this.logJson(job);
63
63
  } else {
64
64
  const padTo = 9 // "Completed" is the longest key
65
65
  ;
@@ -79,8 +79,8 @@ export class GetJobCommand extends SanityCommand {
79
79
  padTo
80
80
  }));
81
81
  }
82
- if (watch && job.status !== 'succeeded') {
83
- this.error(`Job ${job.status}${job.error ? `: ${job.error}` : ''}`, {
82
+ if (jobFailed) {
83
+ this.error(failureMessage, {
84
84
  exit: exitCodes.RUNTIME_ERROR
85
85
  });
86
86
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/context/jobs/get.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {watchJob} from '../../../actions/context/watchJob.js'\nimport {formatKeyValue} from '../../../actions/debug/output.js'\nimport {getJob} from '../../../services/context.js'\n\nconst getJobDebug = subdebug('context:jobs:get')\n\nexport class GetJobCommand extends SanityCommand<typeof GetJobCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n jobId: Args.string({\n description: 'Job ID',\n required: true,\n }),\n }\n\n static override description = 'Get the status of a knowledge base job'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 job-def456',\n description: 'Get the current status of a job',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 job-def456 --watch',\n description: 'Wait for the job to finish (non-zero exit if it does not succeed)',\n },\n ]\n\n static override flags = {\n json: Flags.boolean({\n default: false,\n description: 'Output the job in JSON format',\n }),\n watch: Flags.boolean({\n default: false,\n description: 'Poll until the job reaches a terminal state',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {jobId, knowledgeBaseId} = this.args\n const {json, watch} = this.flags\n\n let job\n try {\n job = watch\n ? await watchJob(knowledgeBaseId, jobId, {label: 'Waiting for job'})\n : await getJob(knowledgeBaseId, jobId)\n } catch (error) {\n getJobDebug('Error getting job', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Job \"${jobId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to get job: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (json) {\n this.log(JSON.stringify(job, null, 2))\n } else {\n const padTo = 9 // \"Completed\" is the longest key\n this.log(formatKeyValue('ID', job.id, {padTo}))\n this.log(formatKeyValue('Status', job.status, {padTo}))\n this.log(formatKeyValue('Started', job.startedAt ?? '-', {padTo}))\n this.log(formatKeyValue('Completed', job.completedAt ?? '-', {padTo}))\n this.log(formatKeyValue('Error', job.error ?? '-', {padTo}))\n }\n\n if (watch && job.status !== 'succeeded') {\n this.error(`Job ${job.status}${job.error ? `: ${job.error}` : ''}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","watchJob","formatKeyValue","getJob","getJobDebug","GetJobCommand","args","knowledgeBaseId","string","description","required","jobId","examples","command","flags","json","boolean","default","watch","run","job","label","error","statusCode","exit","RUNTIME_ERROR","log","JSON","stringify","padTo","id","status","startedAt","completedAt"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AAEvC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,QAAQ,QAAO,uCAAsC;AAC7D,SAAQC,cAAc,QAAO,mCAAkC;AAC/D,SAAQC,MAAM,QAAO,+BAA8B;AAEnD,MAAMC,cAAcN,SAAS;AAE7B,OAAO,MAAMO,sBAAsBR;IACjC,OAAgBS,OAAO;QACrBC,iBAAiBb,KAAKc,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;QACA,gGAAgG;QAChGC,OAAOjB,KAAKc,MAAM,CAAC;YACjBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,yCAAwC;IAEtE,OAAgBG,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;KACD,CAAA;IAED,OAAgBK,QAAQ;QACtBC,MAAMpB,MAAMqB,OAAO,CAAC;YAClBC,SAAS;YACTR,aAAa;QACf;QACAS,OAAOvB,MAAMqB,OAAO,CAAC;YACnBC,SAAS;YACTR,aAAa;QACf;IACF,EAAqB;IAErB,MAAaU,MAAqB;QAChC,MAAM,EAACR,KAAK,EAAEJ,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QAC1C,MAAM,EAACS,IAAI,EAAEG,KAAK,EAAC,GAAG,IAAI,CAACJ,KAAK;QAEhC,IAAIM;QACJ,IAAI;YACFA,MAAMF,QACF,MAAMjB,SAASM,iBAAiBI,OAAO;gBAACU,OAAO;YAAiB,KAChE,MAAMlB,OAAOI,iBAAiBI;QACpC,EAAE,OAAOW,OAAO;YACdlB,YAAY,qBAAqBkB;YACjC,IAAItB,YAAYsB,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,KAAK,EAAEX,MAAM,+BAA+B,EAAEJ,gBAAgB,CAAC,CAAC,EAAE;oBAC5EiB,MAAM5B,UAAU6B,aAAa;gBAC/B;YACF;YACA,IAAI,CAACH,KAAK,CAAC,CAAC,mBAAmB,EAAEvB,gBAAgBuB,QAAQ,EAAE;gBACzDE,MAAM5B,UAAU6B,aAAa;YAC/B;QACF;QAEA,IAAIV,MAAM;YACR,IAAI,CAACW,GAAG,CAACC,KAAKC,SAAS,CAACR,KAAK,MAAM;QACrC,OAAO;YACL,MAAMS,QAAQ,EAAE,iCAAiC;;YACjD,IAAI,CAACH,GAAG,CAACxB,eAAe,MAAMkB,IAAIU,EAAE,EAAE;gBAACD;YAAK;YAC5C,IAAI,CAACH,GAAG,CAACxB,eAAe,UAAUkB,IAAIW,MAAM,EAAE;gBAACF;YAAK;YACpD,IAAI,CAACH,GAAG,CAACxB,eAAe,WAAWkB,IAAIY,SAAS,IAAI,KAAK;gBAACH;YAAK;YAC/D,IAAI,CAACH,GAAG,CAACxB,eAAe,aAAakB,IAAIa,WAAW,IAAI,KAAK;gBAACJ;YAAK;YACnE,IAAI,CAACH,GAAG,CAACxB,eAAe,SAASkB,IAAIE,KAAK,IAAI,KAAK;gBAACO;YAAK;QAC3D;QAEA,IAAIX,SAASE,IAAIW,MAAM,KAAK,aAAa;YACvC,IAAI,CAACT,KAAK,CAAC,CAAC,IAAI,EAAEF,IAAIW,MAAM,GAAGX,IAAIE,KAAK,GAAG,CAAC,EAAE,EAAEF,IAAIE,KAAK,EAAE,GAAG,IAAI,EAAE;gBAClEE,MAAM5B,UAAU6B,aAAa;YAC/B;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../../../../src/commands/context/jobs/get.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage, JsonOutputError} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {watchJob} from '../../../actions/context/watchJob.js'\nimport {formatKeyValue} from '../../../actions/debug/output.js'\nimport {getJob} from '../../../services/context.js'\n\nconst getJobDebug = subdebug('context:jobs:get')\n\nexport class GetJobCommand extends SanityCommand<typeof GetJobCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n jobId: Args.string({\n description: 'Job ID',\n required: true,\n }),\n }\n\n static override description = 'Get the status of a knowledge base job'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 job-def456',\n description: 'Get the current status of a job',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 job-def456 --watch',\n description: 'Wait for the job to finish (non-zero exit if it does not succeed)',\n },\n ]\n\n static override flags = {\n watch: Flags.boolean({\n default: false,\n description: 'Poll until the job reaches a terminal state',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {jobId, knowledgeBaseId} = this.args\n const {json, watch} = this.flags\n\n let job\n try {\n job = watch\n ? await watchJob(knowledgeBaseId, jobId, {label: 'Waiting for job'})\n : await getJob(knowledgeBaseId, jobId)\n } catch (error) {\n getJobDebug('Error getting job', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Job \"${jobId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to get job: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n const jobFailed = watch && job.status !== 'succeeded'\n const failureMessage = `Job ${job.status}${job.error ? `: ${job.error}` : ''}`\n if (json) {\n if (jobFailed) throw new JsonOutputError(failureMessage, job, exitCodes.RUNTIME_ERROR)\n this.logJson(job)\n } else {\n const padTo = 9 // \"Completed\" is the longest key\n this.log(formatKeyValue('ID', job.id, {padTo}))\n this.log(formatKeyValue('Status', job.status, {padTo}))\n this.log(formatKeyValue('Started', job.startedAt ?? '-', {padTo}))\n this.log(formatKeyValue('Completed', job.completedAt ?? '-', {padTo}))\n this.log(formatKeyValue('Error', job.error ?? '-', {padTo}))\n }\n\n if (jobFailed) {\n this.error(failureMessage, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","JsonOutputError","isHttpError","watchJob","formatKeyValue","getJob","getJobDebug","GetJobCommand","args","knowledgeBaseId","string","description","required","jobId","enableJsonFlag","examples","command","flags","watch","boolean","default","run","json","job","label","error","statusCode","exit","RUNTIME_ERROR","jobFailed","status","failureMessage","logJson","padTo","log","id","startedAt","completedAt"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AAEvC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,EAAEC,eAAe,QAAO,0BAAyB;AACxE,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,QAAQ,QAAO,uCAAsC;AAC7D,SAAQC,cAAc,QAAO,mCAAkC;AAC/D,SAAQC,MAAM,QAAO,+BAA8B;AAEnD,MAAMC,cAAcP,SAAS;AAE7B,OAAO,MAAMQ,sBAAsBT;IACjC,OAAgBU,OAAO;QACrBC,iBAAiBd,KAAKe,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;QACA,gGAAgG;QAChGC,OAAOlB,KAAKe,MAAM,CAAC;YACjBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,yCAAwC;IAEtE,OAAgBG,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTL,aAAa;QACf;QACA;YACEK,SAAS;YACTL,aAAa;QACf;KACD,CAAA;IAED,OAAgBM,QAAQ;QACtBC,OAAOtB,MAAMuB,OAAO,CAAC;YACnBC,SAAS;YACTT,aAAa;QACf;IACF,EAAqB;IAErB,MAAaU,MAAqB;QAChC,MAAM,EAACR,KAAK,EAAEJ,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QAC1C,MAAM,EAACc,IAAI,EAAEJ,KAAK,EAAC,GAAG,IAAI,CAACD,KAAK;QAEhC,IAAIM;QACJ,IAAI;YACFA,MAAML,QACF,MAAMf,SAASM,iBAAiBI,OAAO;gBAACW,OAAO;YAAiB,KAChE,MAAMnB,OAAOI,iBAAiBI;QACpC,EAAE,OAAOY,OAAO;YACdnB,YAAY,qBAAqBmB;YACjC,IAAIvB,YAAYuB,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,KAAK,EAAEZ,MAAM,+BAA+B,EAAEJ,gBAAgB,CAAC,CAAC,EAAE;oBAC5EkB,MAAM9B,UAAU+B,aAAa;gBAC/B;YACF;YACA,IAAI,CAACH,KAAK,CAAC,CAAC,mBAAmB,EAAEzB,gBAAgByB,QAAQ,EAAE;gBACzDE,MAAM9B,UAAU+B,aAAa;YAC/B;QACF;QAEA,MAAMC,YAAYX,SAASK,IAAIO,MAAM,KAAK;QAC1C,MAAMC,iBAAiB,CAAC,IAAI,EAAER,IAAIO,MAAM,GAAGP,IAAIE,KAAK,GAAG,CAAC,EAAE,EAAEF,IAAIE,KAAK,EAAE,GAAG,IAAI;QAC9E,IAAIH,MAAM;YACR,IAAIO,WAAW,MAAM,IAAI5B,gBAAgB8B,gBAAgBR,KAAK1B,UAAU+B,aAAa;YACrF,IAAI,CAACI,OAAO,CAACT;QACf,OAAO;YACL,MAAMU,QAAQ,EAAE,iCAAiC;;YACjD,IAAI,CAACC,GAAG,CAAC9B,eAAe,MAAMmB,IAAIY,EAAE,EAAE;gBAACF;YAAK;YAC5C,IAAI,CAACC,GAAG,CAAC9B,eAAe,UAAUmB,IAAIO,MAAM,EAAE;gBAACG;YAAK;YACpD,IAAI,CAACC,GAAG,CAAC9B,eAAe,WAAWmB,IAAIa,SAAS,IAAI,KAAK;gBAACH;YAAK;YAC/D,IAAI,CAACC,GAAG,CAAC9B,eAAe,aAAamB,IAAIc,WAAW,IAAI,KAAK;gBAACJ;YAAK;YACnE,IAAI,CAACC,GAAG,CAAC9B,eAAe,SAASmB,IAAIE,KAAK,IAAI,KAAK;gBAACQ;YAAK;QAC3D;QAEA,IAAIJ,WAAW;YACb,IAAI,CAACJ,KAAK,CAACM,gBAAgB;gBACzBJ,MAAM9B,UAAU+B,aAAa;YAC/B;QACF;IACF;AACF"}