@sanity/cli 7.8.0 → 7.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +132 -0
  2. package/dist/actions/auth/login/getProvider.js +7 -2
  3. package/dist/actions/auth/login/getProvider.js.map +1 -1
  4. package/dist/actions/dataset/create.js +2 -2
  5. package/dist/actions/dataset/create.js.map +1 -1
  6. package/dist/actions/deploy/createUserApplication.js +8 -5
  7. package/dist/actions/deploy/createUserApplication.js.map +1 -1
  8. package/dist/actions/deploy/deployApp.js +43 -20
  9. package/dist/actions/deploy/deployApp.js.map +1 -1
  10. package/dist/actions/deploy/deployChecks.js +9 -8
  11. package/dist/actions/deploy/deployChecks.js.map +1 -1
  12. package/dist/actions/deploy/deployStudio.js +12 -9
  13. package/dist/actions/deploy/deployStudio.js.map +1 -1
  14. package/dist/actions/deploy/resolveDeployTarget.js +3 -2
  15. package/dist/actions/deploy/resolveDeployTarget.js.map +1 -1
  16. package/dist/actions/deploy/urlUtils.js +0 -4
  17. package/dist/actions/deploy/urlUtils.js.map +1 -1
  18. package/dist/actions/documents/types.js.map +1 -1
  19. package/dist/actions/documents/validate.js +2 -1
  20. package/dist/actions/documents/validate.js.map +1 -1
  21. package/dist/actions/manifest/extractCoreAppManifest.js +6 -1
  22. package/dist/actions/manifest/extractCoreAppManifest.js.map +1 -1
  23. package/dist/actions/organizations/getOrganization.js +7 -3
  24. package/dist/actions/organizations/getOrganization.js.map +1 -1
  25. package/dist/actions/organizations/validateOrganizationSlug.js +20 -0
  26. package/dist/actions/organizations/validateOrganizationSlug.js.map +1 -0
  27. package/dist/actions/undeploy/adapters.js +3 -3
  28. package/dist/actions/undeploy/adapters.js.map +1 -1
  29. package/dist/actions/undeploy/runUndeploy.js +20 -6
  30. package/dist/actions/undeploy/runUndeploy.js.map +1 -1
  31. package/dist/actions/undeploy/undeployPlan.js +18 -3
  32. package/dist/actions/undeploy/undeployPlan.js.map +1 -1
  33. package/dist/commands/documents/validate.js +18 -17
  34. package/dist/commands/documents/validate.js.map +1 -1
  35. package/dist/commands/hooks/create.js +4 -0
  36. package/dist/commands/hooks/create.js.map +1 -1
  37. package/dist/commands/hooks/delete.js +5 -0
  38. package/dist/commands/hooks/delete.js.map +1 -1
  39. package/dist/commands/hooks/logs.js +5 -0
  40. package/dist/commands/hooks/logs.js.map +1 -1
  41. package/dist/commands/install.js +1 -1
  42. package/dist/commands/install.js.map +1 -1
  43. package/dist/commands/organizations/create.js +79 -0
  44. package/dist/commands/organizations/create.js.map +1 -0
  45. package/dist/commands/organizations/delete.js +100 -0
  46. package/dist/commands/organizations/delete.js.map +1 -0
  47. package/dist/commands/organizations/get.js +48 -0
  48. package/dist/commands/organizations/get.js.map +1 -0
  49. package/dist/commands/organizations/list.js +60 -0
  50. package/dist/commands/organizations/list.js.map +1 -0
  51. package/dist/commands/organizations/update.js +115 -0
  52. package/dist/commands/organizations/update.js.map +1 -0
  53. package/dist/commands/projects/create.js +2 -1
  54. package/dist/commands/projects/create.js.map +1 -1
  55. package/dist/commands/undeploy.js +13 -1
  56. package/dist/commands/undeploy.js.map +1 -1
  57. package/dist/prompts/promptForOrganizationName.js +2 -1
  58. package/dist/prompts/promptForOrganizationName.js.map +1 -1
  59. package/dist/server/devServer.js.map +1 -1
  60. package/dist/services/organizations.js +45 -2
  61. package/dist/services/organizations.js.map +1 -1
  62. package/dist/services/userApplications.js.map +1 -1
  63. package/dist/topicAliases.js +7 -0
  64. package/dist/topicAliases.js.map +1 -1
  65. package/dist/util/organizationAliases.js +12 -0
  66. package/dist/util/organizationAliases.js.map +1 -0
  67. package/oclif.config.js +1 -0
  68. package/oclif.manifest.json +1342 -1094
  69. package/package.json +27 -27
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/hooks/delete.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {select} from '@sanity/cli-core/ux'\n\nimport {type Hook} from '../../actions/hook/types'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {deleteHookForProject, listHooksForProject} from '../../services/hooks.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst deleteHookDebug = subdebug('hook:delete')\n\nexport class Delete extends SanityCommand<typeof Delete> {\n static override args = {\n name: Args.string({\n description: 'Name of webhook to delete (will prompt if not provided)',\n required: false,\n }),\n }\n\n static override description = 'Delete a webhook from the project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Interactively select and delete a webhook',\n },\n {\n command: '<%= config.bin %> <%= command.id %> my-hook',\n description: 'Delete a specific webhook by name',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --project-id abc123',\n description: 'Delete a webhook from a specific project',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to delete webhook from',\n semantics: 'override',\n }),\n }\n\n static override hiddenAliases: string[] = ['hook:delete']\n\n public async run(): Promise<void> {\n const {args} = await this.parse(Delete)\n\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [{grant: 'delete', permission: 'sanity.project.webhooks'}],\n }),\n })\n\n // Get the hook ID to delete\n const hookId = await this.promptForHook(args.name, projectId)\n\n try {\n await deleteHookForProject(projectId, hookId)\n\n this.log('Hook deleted')\n } catch (error) {\n const err = error as Error\n deleteHookDebug(`Error deleting hook ${hookId} for project ${projectId}`, err)\n this.error(`Hook deletion failed:\\n${err.message}`, {exit: 1})\n }\n }\n\n private async promptForHook(\n specifiedName: string | undefined,\n projectId: string,\n ): Promise<string> {\n let hooks: Hook[]\n try {\n hooks = await listHooksForProject(projectId)\n } catch (error) {\n const err = error as Error\n deleteHookDebug(`Error fetching hooks for project ${projectId}`, err)\n this.error(`Failed to fetch hooks:\\n${err.message}`, {exit: 1})\n }\n\n if (hooks.length === 0) {\n this.error('No hooks configured for this project.', {exit: 1})\n }\n\n // If hook name is specified, find it in the list\n if (specifiedName) {\n const specifiedNameLower = specifiedName.toLowerCase()\n const selectedHook = hooks.find((hook) => hook.name.toLowerCase() === specifiedNameLower)\n\n if (!selectedHook) {\n this.error(`Hook with name \"${specifiedName}\" not found`, {exit: 1})\n }\n\n return selectedHook.id\n }\n\n // If no hook name specified, prompt user to select one\n const choices = hooks.map((hook) => ({\n name: hook.name,\n value: hook.id,\n }))\n\n const selectedId = await select({\n choices,\n message: 'Select hook to delete',\n })\n\n return selectedId\n }\n}\n"],"names":["Args","SanityCommand","subdebug","select","promptForProject","deleteHookForProject","listHooksForProject","getProjectIdFlag","deleteHookDebug","Delete","args","name","string","description","required","examples","command","flags","semantics","hiddenAliases","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","hookId","promptForHook","log","error","err","message","exit","specifiedName","hooks","length","specifiedNameLower","toLowerCase","selectedHook","find","hook","id","choices","map","value","selectedId"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACxD,SAAQC,MAAM,QAAO,sBAAqB;AAG1C,SAAQC,gBAAgB,QAAO,oCAAmC;AAClE,SAAQC,oBAAoB,EAAEC,mBAAmB,QAAO,0BAAyB;AACjF,SAAQC,gBAAgB,QAAO,4BAA2B;AAE1D,MAAMC,kBAAkBN,SAAS;AAEjC,OAAO,MAAMO,eAAeR;IAC1B,OAAgBS,OAAO;QACrBC,MAAMX,KAAKY,MAAM,CAAC;YAChBC,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;QACA;YACEG,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IAED,OAAgBI,QAAQ;QACtB,GAAGV,iBAAiB;YAClBM,aAAa;YACbK,WAAW;QACb,EAAE;IACJ,EAAC;IAED,OAAgBC,gBAA0B;QAAC;KAAc,CAAA;IAEzD,MAAaC,MAAqB;QAChC,MAAM,EAACV,IAAI,EAAC,GAAG,MAAM,IAAI,CAACW,KAAK,CAACZ;QAEhC,MAAMa,YAAY,MAAM,IAAI,CAACC,YAAY,CAAC;YACxCC,UAAU,IACRpB,iBAAiB;oBACfqB,qBAAqB;wBAAC;4BAACC,OAAO;4BAAUC,YAAY;wBAAyB;qBAAE;gBACjF;QACJ;QAEA,4BAA4B;QAC5B,MAAMC,SAAS,MAAM,IAAI,CAACC,aAAa,CAACnB,KAAKC,IAAI,EAAEW;QAEnD,IAAI;YACF,MAAMjB,qBAAqBiB,WAAWM;YAEtC,IAAI,CAACE,GAAG,CAAC;QACX,EAAE,OAAOC,OAAO;YACd,MAAMC,MAAMD;YACZvB,gBAAgB,CAAC,oBAAoB,EAAEoB,OAAO,aAAa,EAAEN,WAAW,EAAEU;YAC1E,IAAI,CAACD,KAAK,CAAC,CAAC,uBAAuB,EAAEC,IAAIC,OAAO,EAAE,EAAE;gBAACC,MAAM;YAAC;QAC9D;IACF;IAEA,MAAcL,cACZM,aAAiC,EACjCb,SAAiB,EACA;QACjB,IAAIc;QACJ,IAAI;YACFA,QAAQ,MAAM9B,oBAAoBgB;QACpC,EAAE,OAAOS,OAAO;YACd,MAAMC,MAAMD;YACZvB,gBAAgB,CAAC,iCAAiC,EAAEc,WAAW,EAAEU;YACjE,IAAI,CAACD,KAAK,CAAC,CAAC,wBAAwB,EAAEC,IAAIC,OAAO,EAAE,EAAE;gBAACC,MAAM;YAAC;QAC/D;QAEA,IAAIE,MAAMC,MAAM,KAAK,GAAG;YACtB,IAAI,CAACN,KAAK,CAAC,yCAAyC;gBAACG,MAAM;YAAC;QAC9D;QAEA,iDAAiD;QACjD,IAAIC,eAAe;YACjB,MAAMG,qBAAqBH,cAAcI,WAAW;YACpD,MAAMC,eAAeJ,MAAMK,IAAI,CAAC,CAACC,OAASA,KAAK/B,IAAI,CAAC4B,WAAW,OAAOD;YAEtE,IAAI,CAACE,cAAc;gBACjB,IAAI,CAACT,KAAK,CAAC,CAAC,gBAAgB,EAAEI,cAAc,WAAW,CAAC,EAAE;oBAACD,MAAM;gBAAC;YACpE;YAEA,OAAOM,aAAaG,EAAE;QACxB;QAEA,uDAAuD;QACvD,MAAMC,UAAUR,MAAMS,GAAG,CAAC,CAACH,OAAU,CAAA;gBACnC/B,MAAM+B,KAAK/B,IAAI;gBACfmC,OAAOJ,KAAKC,EAAE;YAChB,CAAA;QAEA,MAAMI,aAAa,MAAM5C,OAAO;YAC9ByC;YACAX,SAAS;QACX;QAEA,OAAOc;IACT;AACF"}
1
+ {"version":3,"sources":["../../../src/commands/hooks/delete.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {select} from '@sanity/cli-core/ux'\n\nimport {type Hook} from '../../actions/hook/types'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {deleteHookForProject, listHooksForProject} from '../../services/hooks.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst deleteHookDebug = subdebug('hook:delete')\n\nexport class Delete extends SanityCommand<typeof Delete> {\n static override args = {\n name: Args.string({\n description: 'Name of webhook to delete (will prompt if not provided)',\n required: false,\n }),\n }\n\n static override description = 'Delete a webhook from the project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Interactively select and delete a webhook',\n },\n {\n command: '<%= config.bin %> <%= command.id %> my-hook',\n description: 'Delete a specific webhook by name',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --project-id abc123',\n description: 'Delete a webhook from a specific project',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to delete webhook from',\n semantics: 'override',\n }),\n }\n\n static override hiddenAliases: string[] = ['hook:delete']\n\n public async run(): Promise<void> {\n const {args} = await this.parse(Delete)\n\n if (!args.name && this.isUnattended()) {\n this.error('Webhook name is required. Pass the name as an argument.', {exit: 2})\n }\n\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [{grant: 'delete', permission: 'sanity.project.webhooks'}],\n }),\n })\n\n // Get the hook ID to delete\n const hookId = await this.promptForHook(args.name, projectId)\n\n try {\n await deleteHookForProject(projectId, hookId)\n\n this.log('Hook deleted')\n } catch (error) {\n const err = error as Error\n deleteHookDebug(`Error deleting hook ${hookId} for project ${projectId}`, err)\n this.error(`Hook deletion failed:\\n${err.message}`, {exit: 1})\n }\n }\n\n private async promptForHook(\n specifiedName: string | undefined,\n projectId: string,\n ): Promise<string> {\n let hooks: Hook[]\n try {\n hooks = await listHooksForProject(projectId)\n } catch (error) {\n const err = error as Error\n deleteHookDebug(`Error fetching hooks for project ${projectId}`, err)\n this.error(`Failed to fetch hooks:\\n${err.message}`, {exit: 1})\n }\n\n if (hooks.length === 0) {\n this.error('No hooks configured for this project.', {exit: 1})\n }\n\n // If hook name is specified, find it in the list\n if (specifiedName) {\n const specifiedNameLower = specifiedName.toLowerCase()\n const selectedHook = hooks.find((hook) => hook.name.toLowerCase() === specifiedNameLower)\n\n if (!selectedHook) {\n this.error(`Hook with name \"${specifiedName}\" not found`, {exit: 1})\n }\n\n return selectedHook.id\n }\n\n // If no hook name specified, prompt user to select one\n const choices = hooks.map((hook) => ({\n name: hook.name,\n value: hook.id,\n }))\n\n const selectedId = await select({\n choices,\n message: 'Select hook to delete',\n })\n\n return selectedId\n }\n}\n"],"names":["Args","SanityCommand","subdebug","select","promptForProject","deleteHookForProject","listHooksForProject","getProjectIdFlag","deleteHookDebug","Delete","args","name","string","description","required","examples","command","flags","semantics","hiddenAliases","run","parse","isUnattended","error","exit","projectId","getProjectId","fallback","requiredPermissions","grant","permission","hookId","promptForHook","log","err","message","specifiedName","hooks","length","specifiedNameLower","toLowerCase","selectedHook","find","hook","id","choices","map","value","selectedId"],"mappings":"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"}
@@ -86,6 +86,11 @@ export class LogsHookCommand extends SanityCommand {
86
86
  selectedHook = hooks[0];
87
87
  } else {
88
88
  // Otherwise prompt user to select a hook
89
+ if (this.isUnattended()) {
90
+ this.error('Webhook name is required when multiple webhooks exist. Pass the name as an argument.', {
91
+ exit: 2
92
+ });
93
+ }
89
94
  selectedHook = await this.selectHook(hooks);
90
95
  }
91
96
  if (!selectedHook) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/hooks/logs.ts"],"sourcesContent":["import {inspect, styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {select} from '@sanity/cli-core/ux'\nimport groupBy from 'lodash-es/groupBy.js'\n\nimport {formatFailure} from '../../actions/hook/formatFailure.js'\nimport {type DeliveryAttempt, type Hook, type HookMessage} from '../../actions/hook/types'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {\n getHookAttemptsForProject,\n getHookMessagesForProject,\n getHooksForProject,\n} from '../../services/hooks.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst logsHookDebug = subdebug('hook:logs')\n\nexport class LogsHookCommand extends SanityCommand<typeof LogsHookCommand> {\n static override args = {\n name: Args.string({\n description: 'Name of the webhook to show logs for',\n required: false,\n }),\n }\n\n static override description = 'Show log entries for project webhooks'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Show log entries for project webhooks',\n },\n {\n command: '<%= config.bin %> <%= command.id %> [NAME]',\n description: 'Show log entries for a specific webhook by name',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --project-id abc123',\n description: 'Show log entries for a specific project',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to view webhook logs for',\n semantics: 'override',\n }),\n detailed: Flags.boolean({\n description: 'Include detailed payload and attempts',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['hook:logs']\n\n public async run() {\n const {args, flags} = await this.parse(LogsHookCommand)\n\n // Ensure we have project context\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [{grant: 'read', permission: 'sanity.project.webhooks'}],\n }),\n })\n\n // Get hooks for the project\n let hooks: Hook[]\n try {\n hooks = await getHooksForProject(projectId)\n } catch (error) {\n const err = error as Error\n logsHookDebug(`Error fetching hooks for project ${projectId}`, err)\n this.error(`Hook list retrieval failed:\\n${err.message}`, {exit: 1})\n }\n\n if (hooks.length === 0) {\n this.error('No hooks currently registered', {exit: 1})\n }\n\n // If hook name is provided, find that specific hook\n let selectedHook: Hook | undefined\n if (args.name) {\n selectedHook = hooks.find((hook) => hook.name.toLowerCase() === args.name?.toLowerCase())\n if (!selectedHook) {\n this.error(`Hook with name \"${args.name}\" not found`, {exit: 1})\n }\n } else if (hooks.length === 1) {\n // If only one hook exists, use that\n selectedHook = hooks[0]\n } else {\n // Otherwise prompt user to select a hook\n selectedHook = await this.selectHook(hooks)\n }\n\n if (!selectedHook) {\n this.error('No hook selected', {exit: 1})\n }\n\n // Fetch messages and attempts for the selected hook\n let messages: HookMessage[]\n let attempts: DeliveryAttempt[] = []\n try {\n ;[messages, attempts] = await Promise.all([\n getHookMessagesForProject({\n hookId: selectedHook.id,\n projectId,\n }),\n getHookAttemptsForProject({\n hookId: selectedHook.id,\n projectId,\n }),\n ])\n } catch (error) {\n const err = error as Error\n logsHookDebug(`Error fetching logs for hook ${selectedHook.id}`, err)\n this.error(`Hook logs retrieval failed:\\n${err.message}`, {exit: 1})\n }\n\n // Group attempts by message ID\n const groupedAttempts = groupBy(attempts, 'messageId')\n\n // Populate messages with attempts\n const populated = messages.map((msg): HookMessage & {attempts: DeliveryAttempt[]} => ({\n ...msg,\n attempts: groupedAttempts[msg.id] || [],\n }))\n\n const totalMessages = messages.length - 1\n\n for (const [i, message] of populated.entries()) {\n this.printMessage(message, {detailed: flags.detailed})\n this.printSeparator(totalMessages === i)\n }\n }\n\n private formatAttemptDate(dateString: string): string {\n try {\n return new Date(dateString).toISOString().replace(/\\.\\d+Z$/, 'Z')\n } catch {\n return dateString // fallback to original if parsing fails\n }\n }\n\n private printMessage(\n message: HookMessage & {attempts: DeliveryAttempt[]},\n options: {detailed?: boolean},\n ) {\n const {detailed} = options\n\n this.log(`Date: ${message.createdAt}`)\n this.log(`Status: ${message.status}`)\n if (message.resultCode) {\n this.log(`Result code: ${message.resultCode}`)\n }\n\n if (message.failureCount > 0) {\n this.log(`Failures: ${message.failureCount}`)\n }\n\n if (detailed) {\n this.log('Payload:')\n try {\n const payload = JSON.parse(message.payload)\n this.log(inspect(payload, {colors: true}))\n } catch (error) {\n this.log(`Payload (raw): ${message.payload}`)\n logsHookDebug('Failed to parse payload JSON:', error)\n }\n }\n\n if (detailed && message.attempts && message.attempts.length > 0) {\n this.log('Attempts:')\n for (const attempt of message.attempts) {\n const date = this.formatAttemptDate(attempt.createdAt)\n const prefix = ` [${date}]`\n\n if (attempt.inProgress) {\n this.log(`${prefix} ${styleText('yellow', 'Pending')}`)\n } else if (attempt.isFailure) {\n const failure = formatFailure(attempt, {includeHelp: true})\n this.log(`${prefix} ${styleText('yellow', `Failure: ${failure}`)}`)\n } else {\n this.log(`${prefix} Success: HTTP ${attempt.resultCode} (${attempt.duration}ms)`)\n }\n }\n }\n\n // Leave some empty space between messages\n this.log('')\n }\n\n private printSeparator(skip: boolean) {\n if (!skip) {\n this.log('---\\n')\n }\n }\n\n private async selectHook(hooks: Hook[]) {\n const hookId = await select({\n choices: hooks.map((hook) => ({\n name: hook.name,\n value: hook.id,\n })),\n message: 'Select hook to list logs for',\n })\n\n return hooks.find((hook) => hook.id === hookId)\n }\n}\n"],"names":["inspect","styleText","Args","Flags","SanityCommand","subdebug","select","groupBy","formatFailure","promptForProject","getHookAttemptsForProject","getHookMessagesForProject","getHooksForProject","getProjectIdFlag","logsHookDebug","LogsHookCommand","args","name","string","description","required","examples","command","flags","semantics","detailed","boolean","hiddenAliases","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","hooks","error","err","message","exit","length","selectedHook","find","hook","toLowerCase","selectHook","messages","attempts","Promise","all","hookId","id","groupedAttempts","populated","map","msg","totalMessages","i","entries","printMessage","printSeparator","formatAttemptDate","dateString","Date","toISOString","replace","options","log","createdAt","status","resultCode","failureCount","payload","JSON","colors","attempt","date","prefix","inProgress","isFailure","failure","includeHelp","duration","skip","choices","value"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/commands/hooks/logs.ts"],"sourcesContent":["import {inspect, styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {select} from '@sanity/cli-core/ux'\nimport groupBy from 'lodash-es/groupBy.js'\n\nimport {formatFailure} from '../../actions/hook/formatFailure.js'\nimport {type DeliveryAttempt, type Hook, type HookMessage} from '../../actions/hook/types'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {\n getHookAttemptsForProject,\n getHookMessagesForProject,\n getHooksForProject,\n} from '../../services/hooks.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst logsHookDebug = subdebug('hook:logs')\n\nexport class LogsHookCommand extends SanityCommand<typeof LogsHookCommand> {\n static override args = {\n name: Args.string({\n description: 'Name of the webhook to show logs for',\n required: false,\n }),\n }\n\n static override description = 'Show log entries for project webhooks'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Show log entries for project webhooks',\n },\n {\n command: '<%= config.bin %> <%= command.id %> [NAME]',\n description: 'Show log entries for a specific webhook by name',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --project-id abc123',\n description: 'Show log entries for a specific project',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to view webhook logs for',\n semantics: 'override',\n }),\n detailed: Flags.boolean({\n description: 'Include detailed payload and attempts',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['hook:logs']\n\n public async run() {\n const {args, flags} = await this.parse(LogsHookCommand)\n\n // Ensure we have project context\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [{grant: 'read', permission: 'sanity.project.webhooks'}],\n }),\n })\n\n // Get hooks for the project\n let hooks: Hook[]\n try {\n hooks = await getHooksForProject(projectId)\n } catch (error) {\n const err = error as Error\n logsHookDebug(`Error fetching hooks for project ${projectId}`, err)\n this.error(`Hook list retrieval failed:\\n${err.message}`, {exit: 1})\n }\n\n if (hooks.length === 0) {\n this.error('No hooks currently registered', {exit: 1})\n }\n\n // If hook name is provided, find that specific hook\n let selectedHook: Hook | undefined\n if (args.name) {\n selectedHook = hooks.find((hook) => hook.name.toLowerCase() === args.name?.toLowerCase())\n if (!selectedHook) {\n this.error(`Hook with name \"${args.name}\" not found`, {exit: 1})\n }\n } else if (hooks.length === 1) {\n // If only one hook exists, use that\n selectedHook = hooks[0]\n } else {\n // Otherwise prompt user to select a hook\n if (this.isUnattended()) {\n this.error(\n 'Webhook name is required when multiple webhooks exist. Pass the name as an argument.',\n {\n exit: 2,\n },\n )\n }\n selectedHook = await this.selectHook(hooks)\n }\n\n if (!selectedHook) {\n this.error('No hook selected', {exit: 1})\n }\n\n // Fetch messages and attempts for the selected hook\n let messages: HookMessage[]\n let attempts: DeliveryAttempt[] = []\n try {\n ;[messages, attempts] = await Promise.all([\n getHookMessagesForProject({\n hookId: selectedHook.id,\n projectId,\n }),\n getHookAttemptsForProject({\n hookId: selectedHook.id,\n projectId,\n }),\n ])\n } catch (error) {\n const err = error as Error\n logsHookDebug(`Error fetching logs for hook ${selectedHook.id}`, err)\n this.error(`Hook logs retrieval failed:\\n${err.message}`, {exit: 1})\n }\n\n // Group attempts by message ID\n const groupedAttempts = groupBy(attempts, 'messageId')\n\n // Populate messages with attempts\n const populated = messages.map((msg): HookMessage & {attempts: DeliveryAttempt[]} => ({\n ...msg,\n attempts: groupedAttempts[msg.id] || [],\n }))\n\n const totalMessages = messages.length - 1\n\n for (const [i, message] of populated.entries()) {\n this.printMessage(message, {detailed: flags.detailed})\n this.printSeparator(totalMessages === i)\n }\n }\n\n private formatAttemptDate(dateString: string): string {\n try {\n return new Date(dateString).toISOString().replace(/\\.\\d+Z$/, 'Z')\n } catch {\n return dateString // fallback to original if parsing fails\n }\n }\n\n private printMessage(\n message: HookMessage & {attempts: DeliveryAttempt[]},\n options: {detailed?: boolean},\n ) {\n const {detailed} = options\n\n this.log(`Date: ${message.createdAt}`)\n this.log(`Status: ${message.status}`)\n if (message.resultCode) {\n this.log(`Result code: ${message.resultCode}`)\n }\n\n if (message.failureCount > 0) {\n this.log(`Failures: ${message.failureCount}`)\n }\n\n if (detailed) {\n this.log('Payload:')\n try {\n const payload = JSON.parse(message.payload)\n this.log(inspect(payload, {colors: true}))\n } catch (error) {\n this.log(`Payload (raw): ${message.payload}`)\n logsHookDebug('Failed to parse payload JSON:', error)\n }\n }\n\n if (detailed && message.attempts && message.attempts.length > 0) {\n this.log('Attempts:')\n for (const attempt of message.attempts) {\n const date = this.formatAttemptDate(attempt.createdAt)\n const prefix = ` [${date}]`\n\n if (attempt.inProgress) {\n this.log(`${prefix} ${styleText('yellow', 'Pending')}`)\n } else if (attempt.isFailure) {\n const failure = formatFailure(attempt, {includeHelp: true})\n this.log(`${prefix} ${styleText('yellow', `Failure: ${failure}`)}`)\n } else {\n this.log(`${prefix} Success: HTTP ${attempt.resultCode} (${attempt.duration}ms)`)\n }\n }\n }\n\n // Leave some empty space between messages\n this.log('')\n }\n\n private printSeparator(skip: boolean) {\n if (!skip) {\n this.log('---\\n')\n }\n }\n\n private async selectHook(hooks: Hook[]) {\n const hookId = await select({\n choices: hooks.map((hook) => ({\n name: hook.name,\n value: hook.id,\n })),\n message: 'Select hook to list logs for',\n })\n\n return hooks.find((hook) => hook.id === hookId)\n }\n}\n"],"names":["inspect","styleText","Args","Flags","SanityCommand","subdebug","select","groupBy","formatFailure","promptForProject","getHookAttemptsForProject","getHookMessagesForProject","getHooksForProject","getProjectIdFlag","logsHookDebug","LogsHookCommand","args","name","string","description","required","examples","command","flags","semantics","detailed","boolean","hiddenAliases","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","hooks","error","err","message","exit","length","selectedHook","find","hook","toLowerCase","isUnattended","selectHook","messages","attempts","Promise","all","hookId","id","groupedAttempts","populated","map","msg","totalMessages","i","entries","printMessage","printSeparator","formatAttemptDate","dateString","Date","toISOString","replace","options","log","createdAt","status","resultCode","failureCount","payload","JSON","colors","attempt","date","prefix","inProgress","isFailure","failure","includeHelp","duration","skip","choices","value"],"mappings":"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"}
@@ -25,7 +25,7 @@ export class Install extends SanityCommand {
25
25
  const root = await this.getProjectRoot();
26
26
  const workDir = root.directory;
27
27
  const pkgManager = await getPackageManagerChoice(workDir, {
28
- interactive: true
28
+ interactive: !this.isUnattended()
29
29
  });
30
30
  await (packages.length > 0 ? installNewPackages({
31
31
  packageManager: pkgManager.chosen,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/install.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {\n installDeclaredPackages,\n installNewPackages,\n} from '../util/packageManager/installPackages.js'\nimport {getPackageManagerChoice} from '../util/packageManager/packageManagerChoice.js'\n\nexport class Install extends SanityCommand<typeof Install> {\n static override args = {\n packages: Args.string({\n description: 'Packages to install',\n multiple: true,\n required: false,\n }),\n }\n\n static override description = 'Install dependencies for the Sanity Studio project'\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n '<%= config.bin %> <%= command.id %> @sanity/vision',\n '<%= config.bin %> <%= command.id %> some-package another-package',\n ]\n\n static strict = false\n\n public async run(): Promise<void> {\n const {argv} = await this.parse(Install)\n // Oclif doesn't support multiple arguments\n // so we need to parse the arguments manually\n const packages = argv as string[]\n const root = await this.getProjectRoot()\n const workDir = root.directory\n\n const pkgManager = await getPackageManagerChoice(workDir, {interactive: true})\n\n await (packages.length > 0\n ? installNewPackages(\n {packageManager: pkgManager.chosen, packages},\n {output: this.output, workDir},\n )\n : installDeclaredPackages(workDir, pkgManager.chosen, {output: this.output, workDir}))\n }\n}\n"],"names":["Args","SanityCommand","installDeclaredPackages","installNewPackages","getPackageManagerChoice","Install","args","packages","string","description","multiple","required","examples","strict","run","argv","parse","root","getProjectRoot","workDir","directory","pkgManager","interactive","length","packageManager","chosen","output"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,aAAa,QAAO,mBAAkB;AAE9C,SACEC,uBAAuB,EACvBC,kBAAkB,QACb,4CAA2C;AAClD,SAAQC,uBAAuB,QAAO,iDAAgD;AAEtF,OAAO,MAAMC,gBAAgBJ;IAC3B,OAAgBK,OAAO;QACrBC,UAAUP,KAAKQ,MAAM,CAAC;YACpBC,aAAa;YACbC,UAAU;YACVC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBF,cAAc,qDAAoD;IAElF,OAAgBG,WAAW;QACzB;QACA;QACA;KACD,CAAA;IAED,OAAOC,SAAS,MAAK;IAErB,MAAaC,MAAqB;QAChC,MAAM,EAACC,IAAI,EAAC,GAAG,MAAM,IAAI,CAACC,KAAK,CAACX;QAChC,2CAA2C;QAC3C,6CAA6C;QAC7C,MAAME,WAAWQ;QACjB,MAAME,OAAO,MAAM,IAAI,CAACC,cAAc;QACtC,MAAMC,UAAUF,KAAKG,SAAS;QAE9B,MAAMC,aAAa,MAAMjB,wBAAwBe,SAAS;YAACG,aAAa;QAAI;QAE5E,MAAOf,CAAAA,SAASgB,MAAM,GAAG,IACrBpB,mBACE;YAACqB,gBAAgBH,WAAWI,MAAM;YAAElB;QAAQ,GAC5C;YAACmB,QAAQ,IAAI,CAACA,MAAM;YAAEP;QAAO,KAE/BjB,wBAAwBiB,SAASE,WAAWI,MAAM,EAAE;YAACC,QAAQ,IAAI,CAACA,MAAM;YAAEP;QAAO,EAAC;IACxF;AACF"}
1
+ {"version":3,"sources":["../../src/commands/install.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {\n installDeclaredPackages,\n installNewPackages,\n} from '../util/packageManager/installPackages.js'\nimport {getPackageManagerChoice} from '../util/packageManager/packageManagerChoice.js'\n\nexport class Install extends SanityCommand<typeof Install> {\n static override args = {\n packages: Args.string({\n description: 'Packages to install',\n multiple: true,\n required: false,\n }),\n }\n\n static override description = 'Install dependencies for the Sanity Studio project'\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n '<%= config.bin %> <%= command.id %> @sanity/vision',\n '<%= config.bin %> <%= command.id %> some-package another-package',\n ]\n\n static strict = false\n\n public async run(): Promise<void> {\n const {argv} = await this.parse(Install)\n // Oclif doesn't support multiple arguments\n // so we need to parse the arguments manually\n const packages = argv as string[]\n const root = await this.getProjectRoot()\n const workDir = root.directory\n\n const pkgManager = await getPackageManagerChoice(workDir, {\n interactive: !this.isUnattended(),\n })\n\n await (packages.length > 0\n ? installNewPackages(\n {packageManager: pkgManager.chosen, packages},\n {output: this.output, workDir},\n )\n : installDeclaredPackages(workDir, pkgManager.chosen, {output: this.output, workDir}))\n }\n}\n"],"names":["Args","SanityCommand","installDeclaredPackages","installNewPackages","getPackageManagerChoice","Install","args","packages","string","description","multiple","required","examples","strict","run","argv","parse","root","getProjectRoot","workDir","directory","pkgManager","interactive","isUnattended","length","packageManager","chosen","output"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,aAAa,QAAO,mBAAkB;AAE9C,SACEC,uBAAuB,EACvBC,kBAAkB,QACb,4CAA2C;AAClD,SAAQC,uBAAuB,QAAO,iDAAgD;AAEtF,OAAO,MAAMC,gBAAgBJ;IAC3B,OAAgBK,OAAO;QACrBC,UAAUP,KAAKQ,MAAM,CAAC;YACpBC,aAAa;YACbC,UAAU;YACVC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBF,cAAc,qDAAoD;IAElF,OAAgBG,WAAW;QACzB;QACA;QACA;KACD,CAAA;IAED,OAAOC,SAAS,MAAK;IAErB,MAAaC,MAAqB;QAChC,MAAM,EAACC,IAAI,EAAC,GAAG,MAAM,IAAI,CAACC,KAAK,CAACX;QAChC,2CAA2C;QAC3C,6CAA6C;QAC7C,MAAME,WAAWQ;QACjB,MAAME,OAAO,MAAM,IAAI,CAACC,cAAc;QACtC,MAAMC,UAAUF,KAAKG,SAAS;QAE9B,MAAMC,aAAa,MAAMjB,wBAAwBe,SAAS;YACxDG,aAAa,CAAC,IAAI,CAACC,YAAY;QACjC;QAEA,MAAOhB,CAAAA,SAASiB,MAAM,GAAG,IACrBrB,mBACE;YAACsB,gBAAgBJ,WAAWK,MAAM;YAAEnB;QAAQ,GAC5C;YAACoB,QAAQ,IAAI,CAACA,MAAM;YAAER;QAAO,KAE/BjB,wBAAwBiB,SAASE,WAAWK,MAAM,EAAE;YAACC,QAAQ,IAAI,CAACA,MAAM;YAAER;QAAO,EAAC;IACxF;AACF"}
@@ -0,0 +1,79 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { SanityCommand, subdebug } from '@sanity/cli-core';
3
+ import { getErrorMessage } from '@sanity/cli-core/errors';
4
+ import { spinner } from '@sanity/cli-core/ux';
5
+ import { validateOrganizationName } from '../../actions/organizations/validateOrganizationName.js';
6
+ import { promptForOrganizationName } from '../../prompts/promptForOrganizationName.js';
7
+ import { createOrganization } from '../../services/organizations.js';
8
+ import { organizationAliases } from '../../util/organizationAliases.js';
9
+ const createOrgDebug = subdebug('organizations:create');
10
+ export class CreateOrganizationCommand extends SanityCommand {
11
+ static description = 'Create a new organization';
12
+ static examples = [
13
+ {
14
+ command: '<%= config.bin %> <%= command.id %>',
15
+ description: 'Interactively create an organization'
16
+ },
17
+ {
18
+ command: '<%= config.bin %> <%= command.id %> --name "Acme Corp"',
19
+ description: 'Create an organization named "Acme Corp"'
20
+ },
21
+ {
22
+ command: '<%= config.bin %> <%= command.id %> --name "Acme Corp" --default-role member',
23
+ description: 'Create an organization with a default member role'
24
+ }
25
+ ];
26
+ static flags = {
27
+ 'default-role': Flags.string({
28
+ description: 'Default role assigned to new members',
29
+ required: false
30
+ }),
31
+ name: Flags.string({
32
+ description: 'Organization name',
33
+ required: false
34
+ })
35
+ };
36
+ static hiddenAliases = organizationAliases('create');
37
+ async run() {
38
+ const { 'default-role': defaultRoleFlag, name: nameFlag } = this.flags;
39
+ const defaultRole = defaultRoleFlag?.trim();
40
+ if (defaultRole === '') {
41
+ this.error('Default role cannot be empty', {
42
+ exit: 1
43
+ });
44
+ }
45
+ let name;
46
+ if (nameFlag === undefined) {
47
+ if (this.isUnattended()) {
48
+ this.error('Organization name is required. Provide it with the --name flag.', {
49
+ exit: 1
50
+ });
51
+ }
52
+ name = await promptForOrganizationName();
53
+ } else {
54
+ const trimmedName = nameFlag.trim();
55
+ const validation = validateOrganizationName(trimmedName);
56
+ if (validation !== true) {
57
+ this.error(validation, {
58
+ exit: 1
59
+ });
60
+ }
61
+ name = trimmedName;
62
+ }
63
+ const spin = spinner('Creating organization').start();
64
+ try {
65
+ const org = await createOrganization(name, defaultRole);
66
+ spin.succeed('Organization created');
67
+ this.log(`ID: ${org.id}`);
68
+ this.log(`Name: ${org.name}`);
69
+ } catch (error) {
70
+ spin.fail();
71
+ createOrgDebug('Error creating organization', error);
72
+ this.error(`Failed to create organization: ${getErrorMessage(error)}`, {
73
+ exit: 1
74
+ });
75
+ }
76
+ }
77
+ }
78
+
79
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/commands/organizations/create.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {spinner} from '@sanity/cli-core/ux'\n\nimport {validateOrganizationName} from '../../actions/organizations/validateOrganizationName.js'\nimport {promptForOrganizationName} from '../../prompts/promptForOrganizationName.js'\nimport {createOrganization} from '../../services/organizations.js'\nimport {organizationAliases} from '../../util/organizationAliases.js'\n\nconst createOrgDebug = subdebug('organizations:create')\n\nexport class CreateOrganizationCommand extends SanityCommand<typeof CreateOrganizationCommand> {\n static override description = 'Create a new organization'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Interactively create an organization',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --name \"Acme Corp\"',\n description: 'Create an organization named \"Acme Corp\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --name \"Acme Corp\" --default-role member',\n description: 'Create an organization with a default member role',\n },\n ]\n\n static override flags = {\n 'default-role': Flags.string({\n description: 'Default role assigned to new members',\n required: false,\n }),\n name: Flags.string({\n description: 'Organization name',\n required: false,\n }),\n } satisfies FlagInput\n\n static override hiddenAliases = organizationAliases('create')\n\n public async run(): Promise<void> {\n const {'default-role': defaultRoleFlag, name: nameFlag} = this.flags\n\n const defaultRole = defaultRoleFlag?.trim()\n if (defaultRole === '') {\n this.error('Default role cannot be empty', {exit: 1})\n }\n\n let name: string\n if (nameFlag === undefined) {\n if (this.isUnattended()) {\n this.error('Organization name is required. Provide it with the --name flag.', {exit: 1})\n }\n name = await promptForOrganizationName()\n } else {\n const trimmedName = nameFlag.trim()\n const validation = validateOrganizationName(trimmedName)\n if (validation !== true) {\n this.error(validation, {exit: 1})\n }\n name = trimmedName\n }\n\n const spin = spinner('Creating organization').start()\n try {\n const org = await createOrganization(name, defaultRole)\n spin.succeed('Organization created')\n this.log(`ID: ${org.id}`)\n this.log(`Name: ${org.name}`)\n } catch (error) {\n spin.fail()\n createOrgDebug('Error creating organization', error)\n this.error(`Failed to create organization: ${getErrorMessage(error)}`, {\n exit: 1,\n })\n }\n }\n}\n"],"names":["Flags","SanityCommand","subdebug","getErrorMessage","spinner","validateOrganizationName","promptForOrganizationName","createOrganization","organizationAliases","createOrgDebug","CreateOrganizationCommand","description","examples","command","flags","string","required","name","hiddenAliases","run","defaultRoleFlag","nameFlag","defaultRole","trim","error","exit","undefined","isUnattended","trimmedName","validation","spin","start","org","succeed","log","id","fail"],"mappings":"AAAA,SAAQA,KAAK,QAAO,cAAa;AAEjC,SAAQC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACxD,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,OAAO,QAAO,sBAAqB;AAE3C,SAAQC,wBAAwB,QAAO,0DAAyD;AAChG,SAAQC,yBAAyB,QAAO,6CAA4C;AACpF,SAAQC,kBAAkB,QAAO,kCAAiC;AAClE,SAAQC,mBAAmB,QAAO,oCAAmC;AAErE,MAAMC,iBAAiBP,SAAS;AAEhC,OAAO,MAAMQ,kCAAkCT;IAC7C,OAAgBU,cAAc,4BAA2B;IAEzD,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ;QACtB,gBAAgBd,MAAMe,MAAM,CAAC;YAC3BJ,aAAa;YACbK,UAAU;QACZ;QACAC,MAAMjB,MAAMe,MAAM,CAAC;YACjBJ,aAAa;YACbK,UAAU;QACZ;IACF,EAAqB;IAErB,OAAgBE,gBAAgBV,oBAAoB,UAAS;IAE7D,MAAaW,MAAqB;QAChC,MAAM,EAAC,gBAAgBC,eAAe,EAAEH,MAAMI,QAAQ,EAAC,GAAG,IAAI,CAACP,KAAK;QAEpE,MAAMQ,cAAcF,iBAAiBG;QACrC,IAAID,gBAAgB,IAAI;YACtB,IAAI,CAACE,KAAK,CAAC,gCAAgC;gBAACC,MAAM;YAAC;QACrD;QAEA,IAAIR;QACJ,IAAII,aAAaK,WAAW;YAC1B,IAAI,IAAI,CAACC,YAAY,IAAI;gBACvB,IAAI,CAACH,KAAK,CAAC,mEAAmE;oBAACC,MAAM;gBAAC;YACxF;YACAR,OAAO,MAAMX;QACf,OAAO;YACL,MAAMsB,cAAcP,SAASE,IAAI;YACjC,MAAMM,aAAaxB,yBAAyBuB;YAC5C,IAAIC,eAAe,MAAM;gBACvB,IAAI,CAACL,KAAK,CAACK,YAAY;oBAACJ,MAAM;gBAAC;YACjC;YACAR,OAAOW;QACT;QAEA,MAAME,OAAO1B,QAAQ,yBAAyB2B,KAAK;QACnD,IAAI;YACF,MAAMC,MAAM,MAAMzB,mBAAmBU,MAAMK;YAC3CQ,KAAKG,OAAO,CAAC;YACb,IAAI,CAACC,GAAG,CAAC,CAAC,MAAM,EAAEF,IAAIG,EAAE,EAAE;YAC1B,IAAI,CAACD,GAAG,CAAC,CAAC,MAAM,EAAEF,IAAIf,IAAI,EAAE;QAC9B,EAAE,OAAOO,OAAO;YACdM,KAAKM,IAAI;YACT3B,eAAe,+BAA+Be;YAC9C,IAAI,CAACA,KAAK,CAAC,CAAC,+BAA+B,EAAErB,gBAAgBqB,QAAQ,EAAE;gBACrEC,MAAM;YACR;QACF;IACF;AACF"}
@@ -0,0 +1,100 @@
1
+ import { styleText } from 'node:util';
2
+ import { Args, Flags } from '@oclif/core';
3
+ import { SanityCommand, subdebug } from '@sanity/cli-core';
4
+ import { getErrorMessage } from '@sanity/cli-core/errors';
5
+ import { input, logSymbols, spinner } from '@sanity/cli-core/ux';
6
+ import { isHttpError } from '@sanity/client';
7
+ import { deleteOrganization, getOrganization } from '../../services/organizations.js';
8
+ import { organizationAliases } from '../../util/organizationAliases.js';
9
+ const deleteOrgDebug = subdebug('organizations:delete');
10
+ export class DeleteOrganizationCommand extends SanityCommand {
11
+ static args = {
12
+ organizationId: Args.string({
13
+ description: 'Organization ID to delete',
14
+ required: true
15
+ })
16
+ };
17
+ static description = 'Delete an organization';
18
+ static examples = [
19
+ {
20
+ command: '<%= config.bin %> <%= command.id %> org-abc123',
21
+ description: 'Delete an organization (prompts for confirmation)'
22
+ },
23
+ {
24
+ command: '<%= config.bin %> <%= command.id %> org-abc123 --force',
25
+ description: 'Delete an organization without confirmation'
26
+ }
27
+ ];
28
+ static flags = {
29
+ force: Flags.boolean({
30
+ description: 'Do not prompt for delete confirmation - forcefully delete',
31
+ required: false
32
+ })
33
+ };
34
+ static hiddenAliases = organizationAliases('delete');
35
+ async run() {
36
+ const { organizationId } = this.args;
37
+ const { force } = this.flags;
38
+ if (force) {
39
+ this.warn(`'--force' used: skipping confirmation, deleting organization "${organizationId}"`);
40
+ } else {
41
+ await this.confirmDeletion(organizationId);
42
+ }
43
+ const spin = spinner('Deleting organization').start();
44
+ try {
45
+ await deleteOrganization(organizationId);
46
+ spin.succeed();
47
+ this.log('Organization deleted');
48
+ } catch (error) {
49
+ spin.fail();
50
+ deleteOrgDebug('Error deleting organization', error);
51
+ if (isHttpError(error) && error.statusCode === 404) {
52
+ this.error(`Organization "${organizationId}" not found`, {
53
+ exit: 1
54
+ });
55
+ }
56
+ this.error(`Failed to delete organization: ${getErrorMessage(error)}`, {
57
+ exit: 1
58
+ });
59
+ }
60
+ }
61
+ async confirmDeletion(organizationId) {
62
+ let orgName;
63
+ try {
64
+ const org = await getOrganization(organizationId);
65
+ orgName = org.name;
66
+ } catch (error) {
67
+ const err = error instanceof Error ? error : new Error(`${error}`);
68
+ deleteOrgDebug(`Error getting organization ${organizationId}`, err);
69
+ if (isHttpError(error) && error.statusCode === 404) {
70
+ this.error(`Organization "${organizationId}" not found`, {
71
+ exit: 1
72
+ });
73
+ }
74
+ this.error(`Organization retrieval failed: ${err.message}`, {
75
+ exit: 1
76
+ });
77
+ }
78
+ this.log(styleText('yellow', `${logSymbols.warning} Deleting organization "${styleText([
79
+ 'bold',
80
+ 'underline'
81
+ ], orgName)}"\n`));
82
+ try {
83
+ await input({
84
+ message: 'Are you ABSOLUTELY sure you want to delete this organization?\n Type the name of the organization to confirm delete:',
85
+ validate: (value)=>{
86
+ const trimmed = value.trim().toLowerCase();
87
+ return trimmed === orgName.trim().toLowerCase() || 'Incorrect organization name. Ctrl + C to cancel delete.';
88
+ }
89
+ });
90
+ } catch (error) {
91
+ const err = error instanceof Error ? error : new Error(`${error}`);
92
+ deleteOrgDebug(`User cancelled`, err);
93
+ this.error(`User cancelled`, {
94
+ exit: 1
95
+ });
96
+ }
97
+ }
98
+ }
99
+
100
+ //# sourceMappingURL=delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/commands/organizations/delete.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {input, logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {isHttpError} from '@sanity/client'\n\nimport {deleteOrganization, getOrganization} from '../../services/organizations.js'\nimport {organizationAliases} from '../../util/organizationAliases.js'\n\nconst deleteOrgDebug = subdebug('organizations:delete')\n\nexport class DeleteOrganizationCommand extends SanityCommand<typeof DeleteOrganizationCommand> {\n static override args = {\n organizationId: Args.string({\n description: 'Organization ID to delete',\n required: true,\n }),\n }\n\n static override description = 'Delete an organization'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> org-abc123',\n description: 'Delete an organization (prompts for confirmation)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> org-abc123 --force',\n description: 'Delete an organization without confirmation',\n },\n ]\n\n static override flags = {\n force: Flags.boolean({\n description: 'Do not prompt for delete confirmation - forcefully delete',\n required: false,\n }),\n } satisfies FlagInput\n\n static override hiddenAliases = organizationAliases('delete')\n\n public async run(): Promise<void> {\n const {organizationId} = this.args\n const {force} = this.flags\n\n if (force) {\n this.warn(`'--force' used: skipping confirmation, deleting organization \"${organizationId}\"`)\n } else {\n await this.confirmDeletion(organizationId)\n }\n\n const spin = spinner('Deleting organization').start()\n try {\n await deleteOrganization(organizationId)\n spin.succeed()\n this.log('Organization deleted')\n } catch (error) {\n spin.fail()\n deleteOrgDebug('Error deleting organization', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Organization \"${organizationId}\" not found`, {exit: 1})\n }\n this.error(`Failed to delete organization: ${getErrorMessage(error)}`, {exit: 1})\n }\n }\n\n private async confirmDeletion(organizationId: string): Promise<void> {\n let orgName: string\n try {\n const org = await getOrganization(organizationId)\n orgName = org.name\n } catch (error) {\n const err = error instanceof Error ? error : new Error(`${error}`)\n deleteOrgDebug(`Error getting organization ${organizationId}`, err)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Organization \"${organizationId}\" not found`, {exit: 1})\n }\n this.error(`Organization retrieval failed: ${err.message}`, {exit: 1})\n }\n\n this.log(\n styleText(\n 'yellow',\n `${logSymbols.warning} Deleting organization \"${styleText(['bold', 'underline'], orgName)}\"\\n`,\n ),\n )\n\n try {\n await input({\n message:\n 'Are you ABSOLUTELY sure you want to delete this organization?\\n Type the name of the organization to confirm delete:',\n validate: (value) => {\n const trimmed = value.trim().toLowerCase()\n return (\n trimmed === orgName.trim().toLowerCase() ||\n 'Incorrect organization name. Ctrl + C to cancel delete.'\n )\n },\n })\n } catch (error) {\n const err = error instanceof Error ? error : new Error(`${error}`)\n deleteOrgDebug(`User cancelled`, err)\n this.error(`User cancelled`, {exit: 1})\n }\n }\n}\n"],"names":["styleText","Args","Flags","SanityCommand","subdebug","getErrorMessage","input","logSymbols","spinner","isHttpError","deleteOrganization","getOrganization","organizationAliases","deleteOrgDebug","DeleteOrganizationCommand","args","organizationId","string","description","required","examples","command","flags","force","boolean","hiddenAliases","run","warn","confirmDeletion","spin","start","succeed","log","error","fail","statusCode","exit","orgName","org","name","err","Error","message","warning","validate","value","trimmed","trim","toLowerCase"],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { Args } from '@oclif/core';
2
+ import { SanityCommand, subdebug } from '@sanity/cli-core';
3
+ import { getErrorMessage } from '@sanity/cli-core/errors';
4
+ import { isHttpError } from '@sanity/client';
5
+ import { getOrganization } from '../../services/organizations.js';
6
+ import { organizationAliases } from '../../util/organizationAliases.js';
7
+ const getOrgDebug = subdebug('organizations:get');
8
+ export class GetOrganizationCommand extends SanityCommand {
9
+ static args = {
10
+ organizationId: Args.string({
11
+ description: 'Organization ID',
12
+ required: true
13
+ })
14
+ };
15
+ static description = 'Get details of an organization';
16
+ static examples = [
17
+ {
18
+ command: '<%= config.bin %> <%= command.id %> org-abc123',
19
+ description: 'Get details of a specific organization'
20
+ }
21
+ ];
22
+ static hiddenAliases = organizationAliases('get');
23
+ async run() {
24
+ const { organizationId } = this.args;
25
+ let org;
26
+ try {
27
+ org = await getOrganization(organizationId);
28
+ } catch (error) {
29
+ getOrgDebug('Error getting organization', error);
30
+ if (isHttpError(error) && error.statusCode === 404) {
31
+ this.error(`Organization "${organizationId}" not found`, {
32
+ exit: 1
33
+ });
34
+ }
35
+ this.error(`Failed to get organization: ${getErrorMessage(error)}`, {
36
+ exit: 1
37
+ });
38
+ }
39
+ this.log(`ID: ${org.id}`);
40
+ this.log(`Name: ${org.name}`);
41
+ this.log(`Slug: ${org.slug ?? '-'}`);
42
+ this.log(`Default role: ${org.defaultRoleName ?? '-'}`);
43
+ this.log(`Created: ${org.createdAt}`);
44
+ this.log(`Updated: ${org.updatedAt}`);
45
+ }
46
+ }
47
+
48
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/commands/organizations/get.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {getOrganization} from '../../services/organizations.js'\nimport {organizationAliases} from '../../util/organizationAliases.js'\n\nconst getOrgDebug = subdebug('organizations:get')\n\nexport class GetOrganizationCommand extends SanityCommand<typeof GetOrganizationCommand> {\n static override args = {\n organizationId: Args.string({\n description: 'Organization ID',\n required: true,\n }),\n }\n\n static override description = 'Get details of an organization'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> org-abc123',\n description: 'Get details of a specific organization',\n },\n ]\n\n static override hiddenAliases = organizationAliases('get')\n\n public async run(): Promise<void> {\n const {organizationId} = this.args\n\n let org\n try {\n org = await getOrganization(organizationId)\n } catch (error) {\n getOrgDebug('Error getting organization', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Organization \"${organizationId}\" not found`, {exit: 1})\n }\n this.error(`Failed to get organization: ${getErrorMessage(error)}`, {exit: 1})\n }\n\n this.log(`ID: ${org.id}`)\n this.log(`Name: ${org.name}`)\n this.log(`Slug: ${org.slug ?? '-'}`)\n this.log(`Default role: ${org.defaultRoleName ?? '-'}`)\n this.log(`Created: ${org.createdAt}`)\n this.log(`Updated: ${org.updatedAt}`)\n }\n}\n"],"names":["Args","SanityCommand","subdebug","getErrorMessage","isHttpError","getOrganization","organizationAliases","getOrgDebug","GetOrganizationCommand","args","organizationId","string","description","required","examples","command","hiddenAliases","run","org","error","statusCode","exit","log","id","name","slug","defaultRoleName","createdAt","updatedAt"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACxD,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,eAAe,QAAO,kCAAiC;AAC/D,SAAQC,mBAAmB,QAAO,oCAAmC;AAErE,MAAMC,cAAcL,SAAS;AAE7B,OAAO,MAAMM,+BAA+BP;IAC1C,OAAgBQ,OAAO;QACrBC,gBAAgBV,KAAKW,MAAM,CAAC;YAC1BC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,iCAAgC;IAE9D,OAAgBE,WAAW;QACzB;YACEC,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IAED,OAAgBI,gBAAgBV,oBAAoB,OAAM;IAE1D,MAAaW,MAAqB;QAChC,MAAM,EAACP,cAAc,EAAC,GAAG,IAAI,CAACD,IAAI;QAElC,IAAIS;QACJ,IAAI;YACFA,MAAM,MAAMb,gBAAgBK;QAC9B,EAAE,OAAOS,OAAO;YACdZ,YAAY,8BAA8BY;YAC1C,IAAIf,YAAYe,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,cAAc,EAAET,eAAe,WAAW,CAAC,EAAE;oBAACW,MAAM;gBAAC;YACnE;YACA,IAAI,CAACF,KAAK,CAAC,CAAC,4BAA4B,EAAEhB,gBAAgBgB,QAAQ,EAAE;gBAACE,MAAM;YAAC;QAC9E;QAEA,IAAI,CAACC,GAAG,CAAC,CAAC,cAAc,EAAEJ,IAAIK,EAAE,EAAE;QAClC,IAAI,CAACD,GAAG,CAAC,CAAC,cAAc,EAAEJ,IAAIM,IAAI,EAAE;QACpC,IAAI,CAACF,GAAG,CAAC,CAAC,cAAc,EAAEJ,IAAIO,IAAI,IAAI,KAAK;QAC3C,IAAI,CAACH,GAAG,CAAC,CAAC,cAAc,EAAEJ,IAAIQ,eAAe,IAAI,KAAK;QACtD,IAAI,CAACJ,GAAG,CAAC,CAAC,cAAc,EAAEJ,IAAIS,SAAS,EAAE;QACzC,IAAI,CAACL,GAAG,CAAC,CAAC,cAAc,EAAEJ,IAAIU,SAAS,EAAE;IAC3C;AACF"}
@@ -0,0 +1,60 @@
1
+ import { SanityCommand, subdebug } from '@sanity/cli-core';
2
+ import { getErrorMessage } from '@sanity/cli-core/errors';
3
+ import { Table } from 'console-table-printer';
4
+ import { listOrganizations } from '../../services/organizations.js';
5
+ import { organizationAliases } from '../../util/organizationAliases.js';
6
+ const listOrgsDebug = subdebug('organizations:list');
7
+ export class ListOrganizationsCommand extends SanityCommand {
8
+ static description = 'List organizations you are a member of';
9
+ static examples = [
10
+ {
11
+ command: '<%= config.bin %> <%= command.id %>',
12
+ description: 'List all your organizations'
13
+ }
14
+ ];
15
+ static hiddenAliases = organizationAliases('list');
16
+ async run() {
17
+ let organizations;
18
+ try {
19
+ organizations = await listOrganizations();
20
+ } catch (error) {
21
+ listOrgsDebug('Error listing organizations', error);
22
+ this.error(`Failed to list organizations: ${getErrorMessage(error)}`, {
23
+ exit: 1
24
+ });
25
+ }
26
+ if (organizations.length === 0) {
27
+ this.log('No organizations found');
28
+ return;
29
+ }
30
+ const table = new Table({
31
+ columns: [
32
+ {
33
+ alignment: 'left',
34
+ name: 'id',
35
+ title: 'ID'
36
+ },
37
+ {
38
+ alignment: 'left',
39
+ name: 'name',
40
+ title: 'Name'
41
+ },
42
+ {
43
+ alignment: 'left',
44
+ name: 'slug',
45
+ title: 'Slug'
46
+ }
47
+ ]
48
+ });
49
+ for (const { id, name, slug } of organizations){
50
+ table.addRow({
51
+ id,
52
+ name,
53
+ slug: slug ?? '-'
54
+ });
55
+ }
56
+ table.printTable();
57
+ }
58
+ }
59
+
60
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/commands/organizations/list.ts"],"sourcesContent":["import {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {Table} from 'console-table-printer'\n\nimport {listOrganizations} from '../../services/organizations.js'\nimport {organizationAliases} from '../../util/organizationAliases.js'\n\nconst listOrgsDebug = subdebug('organizations:list')\n\nexport class ListOrganizationsCommand extends SanityCommand<typeof ListOrganizationsCommand> {\n static override description = 'List organizations you are a member of'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List all your organizations',\n },\n ]\n\n static override hiddenAliases = organizationAliases('list')\n\n public async run(): Promise<void> {\n let organizations\n try {\n organizations = await listOrganizations()\n } catch (error) {\n listOrgsDebug('Error listing organizations', error)\n this.error(`Failed to list organizations: ${getErrorMessage(error)}`, {exit: 1})\n }\n\n if (organizations.length === 0) {\n this.log('No organizations 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: 'slug', title: 'Slug'},\n ],\n })\n\n for (const {id, name, slug} of organizations) {\n table.addRow({id, name, slug: slug ?? '-'})\n }\n\n table.printTable()\n }\n}\n"],"names":["SanityCommand","subdebug","getErrorMessage","Table","listOrganizations","organizationAliases","listOrgsDebug","ListOrganizationsCommand","description","examples","command","hiddenAliases","run","organizations","error","exit","length","log","table","columns","alignment","name","title","id","slug","addRow","printTable"],"mappings":"AAAA,SAAQA,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACxD,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,KAAK,QAAO,wBAAuB;AAE3C,SAAQC,iBAAiB,QAAO,kCAAiC;AACjE,SAAQC,mBAAmB,QAAO,oCAAmC;AAErE,MAAMC,gBAAgBL,SAAS;AAE/B,OAAO,MAAMM,iCAAiCP;IAC5C,OAAgBQ,cAAc,yCAAwC;IAEtE,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,gBAAgBN,oBAAoB,QAAO;IAE3D,MAAaO,MAAqB;QAChC,IAAIC;QACJ,IAAI;YACFA,gBAAgB,MAAMT;QACxB,EAAE,OAAOU,OAAO;YACdR,cAAc,+BAA+BQ;YAC7C,IAAI,CAACA,KAAK,CAAC,CAAC,8BAA8B,EAAEZ,gBAAgBY,QAAQ,EAAE;gBAACC,MAAM;YAAC;QAChF;QAEA,IAAIF,cAAcG,MAAM,KAAK,GAAG;YAC9B,IAAI,CAACC,GAAG,CAAC;YACT;QACF;QAEA,MAAMC,QAAQ,IAAIf,MAAM;YACtBgB,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;aAChD;QACH;QAEA,KAAK,MAAM,EAACC,EAAE,EAAEF,IAAI,EAAEG,IAAI,EAAC,IAAIX,cAAe;YAC5CK,MAAMO,MAAM,CAAC;gBAACF;gBAAIF;gBAAMG,MAAMA,QAAQ;YAAG;QAC3C;QAEAN,MAAMQ,UAAU;IAClB;AACF"}
@@ -0,0 +1,115 @@
1
+ import { Args, Flags } from '@oclif/core';
2
+ import { SanityCommand, subdebug } from '@sanity/cli-core';
3
+ import { getErrorMessage } from '@sanity/cli-core/errors';
4
+ import { spinner } from '@sanity/cli-core/ux';
5
+ import { isHttpError } from '@sanity/client';
6
+ import { validateOrganizationName } from '../../actions/organizations/validateOrganizationName.js';
7
+ import { validateOrganizationSlug } from '../../actions/organizations/validateOrganizationSlug.js';
8
+ import { updateOrganization } from '../../services/organizations.js';
9
+ import { organizationAliases } from '../../util/organizationAliases.js';
10
+ const updateOrgDebug = subdebug('organizations:update');
11
+ const UPDATE_FLAGS = [
12
+ 'name',
13
+ 'slug',
14
+ 'default-role'
15
+ ];
16
+ export class UpdateOrganizationCommand extends SanityCommand {
17
+ static args = {
18
+ organizationId: Args.string({
19
+ description: 'Organization ID',
20
+ required: true
21
+ })
22
+ };
23
+ static description = 'Update an organization';
24
+ static examples = [
25
+ {
26
+ command: '<%= config.bin %> <%= command.id %> org-abc123 --name "New Name"',
27
+ description: 'Rename an organization'
28
+ },
29
+ {
30
+ command: '<%= config.bin %> <%= command.id %> org-abc123 --slug new-slug',
31
+ description: 'Set the organization slug (requires authSAML feature)'
32
+ },
33
+ {
34
+ command: '<%= config.bin %> <%= command.id %> org-abc123 --default-role viewer',
35
+ description: 'Change the default member role'
36
+ }
37
+ ];
38
+ static flags = {
39
+ 'default-role': Flags.string({
40
+ atLeastOne: [
41
+ ...UPDATE_FLAGS
42
+ ],
43
+ description: 'New default role for new members',
44
+ required: false
45
+ }),
46
+ name: Flags.string({
47
+ atLeastOne: [
48
+ ...UPDATE_FLAGS
49
+ ],
50
+ description: 'New organization name',
51
+ required: false
52
+ }),
53
+ slug: Flags.string({
54
+ atLeastOne: [
55
+ ...UPDATE_FLAGS
56
+ ],
57
+ description: 'New URL slug (requires authSAML feature on the organization)',
58
+ required: false
59
+ })
60
+ };
61
+ static hiddenAliases = organizationAliases('update');
62
+ async run() {
63
+ const { organizationId } = this.args;
64
+ const { 'default-role': defaultRole, name, slug } = this.flags;
65
+ const params = {};
66
+ if (name !== undefined) {
67
+ const trimmedName = name.trim();
68
+ const validation = validateOrganizationName(trimmedName);
69
+ if (validation !== true) {
70
+ this.error(validation, {
71
+ exit: 1
72
+ });
73
+ }
74
+ params.name = trimmedName;
75
+ }
76
+ if (slug !== undefined) {
77
+ const trimmedSlug = slug.trim();
78
+ const slugValidation = validateOrganizationSlug(trimmedSlug);
79
+ if (slugValidation !== true) {
80
+ this.error(slugValidation, {
81
+ exit: 1
82
+ });
83
+ }
84
+ params.slug = trimmedSlug;
85
+ }
86
+ if (defaultRole !== undefined) {
87
+ const trimmedRole = defaultRole.trim();
88
+ if (trimmedRole === '') {
89
+ this.error('Default role cannot be empty', {
90
+ exit: 1
91
+ });
92
+ }
93
+ params.defaultRoleName = trimmedRole;
94
+ }
95
+ const spin = spinner('Updating organization').start();
96
+ try {
97
+ await updateOrganization(organizationId, params);
98
+ spin.succeed();
99
+ this.log('Organization updated');
100
+ } catch (error) {
101
+ spin.fail();
102
+ updateOrgDebug('Error updating organization', error);
103
+ if (isHttpError(error) && error.statusCode === 404) {
104
+ this.error(`Organization "${organizationId}" not found`, {
105
+ exit: 1
106
+ });
107
+ }
108
+ this.error(`Failed to update organization: ${getErrorMessage(error)}`, {
109
+ exit: 1
110
+ });
111
+ }
112
+ }
113
+ }
114
+
115
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/commands/organizations/update.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {isHttpError} from '@sanity/client'\n\nimport {validateOrganizationName} from '../../actions/organizations/validateOrganizationName.js'\nimport {validateOrganizationSlug} from '../../actions/organizations/validateOrganizationSlug.js'\nimport {type OrganizationUpdateParams, updateOrganization} from '../../services/organizations.js'\nimport {organizationAliases} from '../../util/organizationAliases.js'\n\nconst updateOrgDebug = subdebug('organizations:update')\n\nconst UPDATE_FLAGS = ['name', 'slug', 'default-role'] as const\n\nexport class UpdateOrganizationCommand extends SanityCommand<typeof UpdateOrganizationCommand> {\n static override args = {\n organizationId: Args.string({\n description: 'Organization ID',\n required: true,\n }),\n }\n\n static override description = 'Update an organization'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> org-abc123 --name \"New Name\"',\n description: 'Rename an organization',\n },\n {\n command: '<%= config.bin %> <%= command.id %> org-abc123 --slug new-slug',\n description: 'Set the organization slug (requires authSAML feature)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> org-abc123 --default-role viewer',\n description: 'Change the default member role',\n },\n ]\n\n static override flags = {\n 'default-role': Flags.string({\n atLeastOne: [...UPDATE_FLAGS],\n description: 'New default role for new members',\n required: false,\n }),\n name: Flags.string({\n atLeastOne: [...UPDATE_FLAGS],\n description: 'New organization name',\n required: false,\n }),\n slug: Flags.string({\n atLeastOne: [...UPDATE_FLAGS],\n description: 'New URL slug (requires authSAML feature on the organization)',\n required: false,\n }),\n } satisfies FlagInput\n\n static override hiddenAliases = organizationAliases('update')\n\n public async run(): Promise<void> {\n const {organizationId} = this.args\n const {'default-role': defaultRole, name, slug} = this.flags\n\n const params: OrganizationUpdateParams = {}\n if (name !== undefined) {\n const trimmedName = name.trim()\n const validation = validateOrganizationName(trimmedName)\n if (validation !== true) {\n this.error(validation, {exit: 1})\n }\n params.name = trimmedName\n }\n if (slug !== undefined) {\n const trimmedSlug = slug.trim()\n const slugValidation = validateOrganizationSlug(trimmedSlug)\n if (slugValidation !== true) {\n this.error(slugValidation, {exit: 1})\n }\n params.slug = trimmedSlug\n }\n if (defaultRole !== undefined) {\n const trimmedRole = defaultRole.trim()\n if (trimmedRole === '') {\n this.error('Default role cannot be empty', {exit: 1})\n }\n params.defaultRoleName = trimmedRole\n }\n\n const spin = spinner('Updating organization').start()\n try {\n await updateOrganization(organizationId, params)\n spin.succeed()\n this.log('Organization updated')\n } catch (error) {\n spin.fail()\n updateOrgDebug('Error updating organization', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Organization \"${organizationId}\" not found`, {exit: 1})\n }\n this.error(`Failed to update organization: ${getErrorMessage(error)}`, {exit: 1})\n }\n }\n}\n"],"names":["Args","Flags","SanityCommand","subdebug","getErrorMessage","spinner","isHttpError","validateOrganizationName","validateOrganizationSlug","updateOrganization","organizationAliases","updateOrgDebug","UPDATE_FLAGS","UpdateOrganizationCommand","args","organizationId","string","description","required","examples","command","flags","atLeastOne","name","slug","hiddenAliases","run","defaultRole","params","undefined","trimmedName","trim","validation","error","exit","trimmedSlug","slugValidation","trimmedRole","defaultRoleName","spin","start","succeed","log","fail","statusCode"],"mappings":"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"}