feat(organizations): add commands for listing, creating, updating, and deleting organizations#762
feat(organizations): add commands for listing, creating, updating, and deleting organizations#762rexxars wants to merge 18 commits into
Conversation
|
Claude finished @mttdnt's task in 1m 50s —— View job Review
1.
if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(input) && !/^[a-z0-9]$/.test(input)) {
return 'Organization slug may only contain lowercase letters, numbers, and hyphens'
}2. Misleading "User cancelled" error in
} catch (error) {
deleteOrgDebug(`User cancelled or input error`, error)
this.error(getErrorMessage(error), {exit: 1})
}3. Falsy check in
body: {name, ...(defaultRoleName !== undefined ? {defaultRoleName} : {})},4.
|
Coverage Delta
Comparing 8 changed files against main @ Overall Coverage
|
fe45e78 to
740971e
Compare
📦 Bundle Stats —
|
| Metric | Value | vs main (8985b42) |
|---|---|---|
| Internal (raw) | 2.7 KB | +539 B, +24.7% |
| Internal (gzip) | 1.0 KB | +257 B, +32.2% |
| Bundled (raw) | 11.15 MB | +19.2 KB, +0.2% |
| Bundled (gzip) | 2.10 MB | +5.2 KB, +0.2% |
| Import time | 874ms | -1ms, -0.1% |
bin:sanity
| Metric | Value | vs main (8985b42) |
|---|---|---|
| Internal (raw) | 782 B | - |
| Internal (gzip) | 423 B | - |
| Bundled (raw) | 9.87 MB | - |
| Bundled (gzip) | 1.77 MB | - |
| Import time | 1.98s | +1.05s, +112.8% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — @sanity/cli-core
Compared against main (8985b42f)
| Metric | Value | vs main (8985b42) |
|---|---|---|
| Internal (raw) | 106.7 KB | +8.5 KB, +8.7% |
| Internal (gzip) | 26.7 KB | +3.4 KB, +14.5% |
| Bundled (raw) | 21.71 MB | +7.8 KB, +0.0% |
| Bundled (gzip) | 3.46 MB | +3.3 KB, +0.1% |
| Import time | 771ms | +1ms, +0.2% |
🗺️ View treemap · Artifacts
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
📦 Bundle Stats — create-sanity
Compared against main (8985b42f)
| Metric | Value | vs main (8985b42) |
|---|---|---|
| Internal (raw) | 908 B | - |
| Internal (gzip) | 483 B | - |
| Bundled (raw) | 931 B | - |
| Bundled (gzip) | 491 B | - |
| Import time | ❌ ChildProcess denied: node | - |
Details
- Import time regressions over 10% are flagged with
⚠️ - Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.
Coverage Delta
Comparing 10 changed files against main @ Overall Coverage
|
Coverage Delta
Comparing 11 changed files against main @ Overall Coverage
|
ba5ff81 to
24915ab
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 24915ab. Configure here.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…pe guard Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Adds `organizations update` command with --name, --slug, and --default-role flags. Includes tests for success, validation (no flags), missing arg, and API error cases. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Remove export from Organization and OrganizationDeleteResponse interfaces as they are only used internally within the service module. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Wire up topic aliases (organization, organisations, organisation, org, orgs) in topicAliases.ts and oclif.config.js. Fix linter-reported import and property ordering in org command files. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…d patterns closer
…or throwing errors
- Trim organization names on create, update, prompt, and delete confirmation compare, so padded names round-trip consistently - Validate slug charset (lowercase letters, numbers, dashes; no leading or trailing dash) before hitting the API - Reject empty --default-role on both create and update - Narrow hasStatusCode guard to what it actually verifies, drop the 'as' cast - Assert request payloads in create/update tests; fix vacuous dash assertion in list test; cover trimmed delete confirmation Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
4bda978 to
e155564
Compare
runeb
left a comment
There was a problem hiding this comment.
Lets make sure create returns an actionable error if ran without the required params in non-interactive mode. Currently I think it will just halt with a prompt.
Instead of introducing hasStatusCode can we leverage the existing isHttpError from @sanity/client already in use in the project?
It would also be great if list/get supports --json like other commands do, but that is a nicety. I dont think all commands support this generally yet.
|
Addressed your PR feedback. Yes, Also heading on vacation for a bit, so handing this off to someone else until I'm back 👋 |

Description
Adds a new
organizationstopic to the CLI with five commands for managing organizations:sanity organizations list- list all organizations you're a member ofsanity organizations get <organizationId>- show details of a specific organizationsanity organizations create- create a new organization (interactive or--name/--default-roleflags)sanity organizations update <organizationId>- update name, slug, or default rolesanity organizations delete <organizationId>- delete an organization (with confirmation prompt)Hidden topic aliases so all of these also work:
organization,organisations,organisation,org,orgs. Uses the two-layer alias approach from #714 (hiddenAliaseson each command class +topicAliases.tsentry).What to review
src/services/organizations.ts- extended withgetOrganization,updateOrganization,deleteOrganization;createOrganizationnow accepts optionaldefaultRoleName; fixedProjectOrganization.slugto bestring | nullsrc/commands/organizations/- five command files, all thin: parse flags, call service, format outputsrc/util/apiError.ts- sharedhasStatusCodetype guard to avoidasassertions in catch blockssrc/topicAliases.tsandoclif.config.js- alias wiring for theorganizationstopicsrc/commands/organizations/__tests__/- 23 tests across all five commandsTesting
getGlobalCliClient), no service file mocksif (error) throw error; error tests asserttoBeInstanceOf(Error)+ messageNotes
--slugflag only onupdate, notcreate- the API requires theauthSAMLfeature for slugs, which a brand-new org won't havedeleteblocks server-side if the org has associated projects - the command surfaces that API error clearlyorganizations members list/invite) are deferred pending internal discussionFIXES AIGRO-4968
Note
Medium Risk
Delete and update call destructive or org-wide APIs with only CLI-side guards; mistakes or
--forcecould remove organizations, though patterns match existing CLI topics.Overview
Adds a new
organizationsCLI topic (minor@sanity/clichangeset) with list, get, create, update, and delete commands wired through extendedorganizationsservice helpers (getOrganization,updateOrganization,deleteOrganization, optionaldefaultRoleNameon create).Create supports
--name/--default-roleor interactive naming; update patches name, slug, or default role with client-side slug rules via newvalidateOrganizationSlug; delete fetches the org and requires typing its name unless--force. Commands registerhiddenAliasesplustopicAliases/oclif.config.jsentries soorg,organization, etc. resolve to the same actions.promptForOrganizationNamenow works without a user argument and trims input;ProjectOrganization.slugis typed as nullable. Broad command and validator tests cover success paths, validation, 404s, and delete confirmation behavior.Reviewed by Cursor Bugbot for commit fe06012. Bugbot is set up for automated code reviews on this repo. Configure here.