@sanity/cli 3.96.1-next.4.af00ad2134 → 3.96.1-next.6.af20bbf4af

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.
@@ -3767,7 +3767,7 @@ function print() { __p += __j.call(arguments, '') }
3767
3767
  }(lodash$1, lodash$1.exports)), lodash$1.exports;
3768
3768
  }
3769
3769
  var lodashExports = requireLodash();
3770
- const helpText$m = `
3770
+ const helpText$n = `
3771
3771
  Arguments
3772
3772
  <type> Type of Resource to add (currently only 'function' is supported)
3773
3773
 
@@ -3809,7 +3809,7 @@ Examples:
3809
3809
  }, addBlueprintsCommand = {
3810
3810
  name: "add",
3811
3811
  group: "blueprints",
3812
- helpText: helpText$m,
3812
+ helpText: helpText$n,
3813
3813
  signature: "<type> [--name <name>] [--fn-type <document-publish>] [--fn-lang <ts|js>] [--javascript]",
3814
3814
  description: "Add a Resource to a Blueprint",
3815
3815
  async action(args, context) {
@@ -3870,7 +3870,7 @@ Examples:
3870
3870
  signature: "[COMMAND]",
3871
3871
  isGroupRoot: !0,
3872
3872
  description: "Deploy and manage Sanity Blueprints and Stacks (IaC)"
3873
- }, helpText$l = `
3873
+ }, helpText$m = `
3874
3874
  Options
3875
3875
  --edit, -e Edit the configuration
3876
3876
  --test, -t Test the configuration
@@ -3893,7 +3893,7 @@ Examples:
3893
3893
  }, configBlueprintsCommand = {
3894
3894
  name: "config",
3895
3895
  group: "blueprints",
3896
- helpText: helpText$l,
3896
+ helpText: helpText$m,
3897
3897
  signature: "[--edit] [-e] [--test] [-t] [--project-id <id>]",
3898
3898
  description: "View or edit local Blueprints configuration",
3899
3899
  async action(args, context) {
@@ -3920,7 +3920,7 @@ Examples:
3920
3920
  });
3921
3921
  if (!success) throw new Error(error2);
3922
3922
  }
3923
- }, helpText$k = `
3923
+ }, helpText$l = `
3924
3924
  Options
3925
3925
  --no-wait Do not wait for deployment to complete
3926
3926
 
@@ -3935,7 +3935,7 @@ Examples:
3935
3935
  }, deployBlueprintsCommand = {
3936
3936
  name: "deploy",
3937
3937
  group: "blueprints",
3938
- helpText: helpText$k,
3938
+ helpText: helpText$l,
3939
3939
  signature: "[--no-wait]",
3940
3940
  description: "Deploy a Blueprint to create or update a Stack",
3941
3941
  async action(args, context) {
@@ -3958,7 +3958,7 @@ Examples:
3958
3958
  });
3959
3959
  if (!success) throw new Error(error2);
3960
3960
  }
3961
- }, helpText$j = `
3961
+ }, helpText$k = `
3962
3962
  Options
3963
3963
  --force, -f Force destroy without confirmation
3964
3964
  --no-wait Do not wait for destroy to complete
@@ -3977,7 +3977,7 @@ Examples:
3977
3977
  }, destroyBlueprintsCommand = {
3978
3978
  name: "destroy",
3979
3979
  group: "blueprints",
3980
- helpText: helpText$j,
3980
+ helpText: helpText$k,
3981
3981
  signature: "[--force] [-f] [--no-wait]",
3982
3982
  description: "Destroy a Blueprint deployment",
3983
3983
  async action(args, context) {
@@ -4003,7 +4003,7 @@ Examples:
4003
4003
  });
4004
4004
  if (!success) throw new Error(error2);
4005
4005
  }
4006
- }, helpText$i = `
4006
+ }, helpText$j = `
4007
4007
  Examples:
4008
4008
  # Retrieve information about the current Stack
4009
4009
  sanity blueprints info
@@ -4012,7 +4012,7 @@ Examples:
4012
4012
  }, infoBlueprintsCommand = {
4013
4013
  name: "info",
4014
4014
  group: "blueprints",
4015
- helpText: helpText$i,
4015
+ helpText: helpText$j,
4016
4016
  signature: "",
4017
4017
  description: "Retrieve information about a Blueprint Stack",
4018
4018
  async action(args, context) {
@@ -4033,7 +4033,7 @@ Examples:
4033
4033
  });
4034
4034
  if (!success) throw new Error(error2);
4035
4035
  }
4036
- }, helpText$h = `
4036
+ }, helpText$i = `
4037
4037
  Arguments
4038
4038
  [dir] Path to initialize the Blueprint in
4039
4039
 
@@ -4055,7 +4055,7 @@ Examples:
4055
4055
  }, initBlueprintsCommand = {
4056
4056
  name: "init",
4057
4057
  group: "blueprints",
4058
- helpText: helpText$h,
4058
+ helpText: helpText$i,
4059
4059
  signature: "[dir] [--blueprint-type <type>] [--project-id <id>]",
4060
4060
  description: "Initialize a new Blueprint manifest file",
4061
4061
  async action(args, context) {
@@ -4095,7 +4095,7 @@ Examples:
4095
4095
  });
4096
4096
  if (!success) throw new Error(error2);
4097
4097
  }
4098
- }, helpText$g = `
4098
+ }, helpText$h = `
4099
4099
  Options
4100
4100
  --watch, -w Watch for new logs (streaming mode)
4101
4101
 
@@ -4110,7 +4110,7 @@ Examples:
4110
4110
  }, logsBlueprintsCommand = {
4111
4111
  name: "logs",
4112
4112
  group: "blueprints",
4113
- helpText: helpText$g,
4113
+ helpText: helpText$h,
4114
4114
  signature: "[--watch] [-w]",
4115
4115
  description: "Display logs for the current Blueprint Stack",
4116
4116
  async action(args, context) {
@@ -4133,7 +4133,7 @@ Examples:
4133
4133
  });
4134
4134
  if (streaming && await streaming, !success) throw new Error(error2);
4135
4135
  }
4136
- }, helpText$f = `
4136
+ }, helpText$g = `
4137
4137
  Safe to run at any time. Will not modify any Resources.
4138
4138
 
4139
4139
  Examples:
@@ -4142,7 +4142,7 @@ Examples:
4142
4142
  `, planBlueprintsCommand = {
4143
4143
  name: "plan",
4144
4144
  group: "blueprints",
4145
- helpText: helpText$f,
4145
+ helpText: helpText$g,
4146
4146
  signature: "",
4147
4147
  description: "Enumerate Resources to be deployed",
4148
4148
  async action(args, context) {
@@ -4162,7 +4162,7 @@ Examples:
4162
4162
  });
4163
4163
  if (!success) throw new Error(error2);
4164
4164
  }
4165
- }, helpText$e = `
4165
+ }, helpText$f = `
4166
4166
  Options
4167
4167
  --project-id <id> Project ID to use
4168
4168
 
@@ -4177,7 +4177,7 @@ Examples:
4177
4177
  }, stacksBlueprintsCommand = {
4178
4178
  name: "stacks",
4179
4179
  group: "blueprints",
4180
- helpText: helpText$e,
4180
+ helpText: helpText$f,
4181
4181
  signature: "[--project-id <id>]",
4182
4182
  description: "List all Blueprint Stacks for the current Project",
4183
4183
  hideFromHelp: !0,
@@ -4345,7 +4345,7 @@ function ensureNpx() {
4345
4345
  );
4346
4346
  }
4347
4347
  }
4348
- const helpText$d = `
4348
+ const helpText$e = `
4349
4349
  Runs a given code modification script on the current studio folder.
4350
4350
  Running the command without a specified codemod name will list available transformations.
4351
4351
 
@@ -4367,7 +4367,7 @@ Examples
4367
4367
  name: "codemod",
4368
4368
  signature: "[CODEMOD_NAME]",
4369
4369
  description: "Updates Sanity Studio codebase with a code modification script",
4370
- helpText: helpText$d,
4370
+ helpText: helpText$e,
4371
4371
  action: codemodAction
4372
4372
  };
4373
4373
  var lodash_isplainobject, hasRequiredLodash_isplainobject;
@@ -7905,7 +7905,7 @@ const docsCommand = {
7905
7905
  const { output } = context, { print } = output, url = "https://www.sanity.io/docs";
7906
7906
  print(`Opening ${url}`), await open(url);
7907
7907
  }
7908
- }, helpText$c = `
7908
+ }, helpText$d = `
7909
7909
  Options
7910
7910
  --port <port> Port to start emulator on
7911
7911
  --open Open dev server in a new browser tab
@@ -7925,7 +7925,7 @@ Examples
7925
7925
  }, devFunctionsCommand = {
7926
7926
  name: "dev",
7927
7927
  group: "functions",
7928
- helpText: helpText$c,
7928
+ helpText: helpText$d,
7929
7929
  signature: "[--port <port> --open]",
7930
7930
  description: "Start the Sanity Function emulator",
7931
7931
  async action(args, context) {
@@ -7946,7 +7946,7 @@ Examples
7946
7946
  if (!success) throw new Error(error2);
7947
7947
  shouldOpen && open(`http://localhost:${flags.port}`);
7948
7948
  }
7949
- }, helpText$b = `
7949
+ }, helpText$c = `
7950
7950
  Commands
7951
7951
  add Add or update an environment variable
7952
7952
  list List the environment variables
@@ -7969,7 +7969,7 @@ Examples
7969
7969
  `, envFunctionsCommand = {
7970
7970
  name: "env",
7971
7971
  group: "functions",
7972
- helpText: helpText$b,
7972
+ helpText: helpText$c,
7973
7973
  signature: "<add|list|remove> <name> [key] [value]",
7974
7974
  description: "Add or remove an environment variable or list environment variables for a Sanity function",
7975
7975
  async action(args, context) {
@@ -8025,7 +8025,7 @@ Examples
8025
8025
  signature: "[COMMAND]",
8026
8026
  isGroupRoot: !0,
8027
8027
  description: "Manage, test, and observe Sanity Functions"
8028
- }, helpText$a = `
8028
+ }, helpText$b = `
8029
8029
  Arguments
8030
8030
  <name> The name of the Function to retrieve logs for
8031
8031
 
@@ -8062,7 +8062,7 @@ Examples
8062
8062
  }, logsFunctionsCommand = {
8063
8063
  name: "logs",
8064
8064
  group: "functions",
8065
- helpText: helpText$a,
8065
+ helpText: helpText$b,
8066
8066
  signature: "<name> [--limit <number>] [--json] [--utc] [--delete [--force]] [--watch]",
8067
8067
  description: "Retrieve or delete logs for a Sanity Function",
8068
8068
  async action(args, context) {
@@ -8087,7 +8087,7 @@ Examples
8087
8087
  });
8088
8088
  if (!success) throw new Error(error2);
8089
8089
  }
8090
- }, helpText$9 = `
8090
+ }, helpText$a = `
8091
8091
  Arguments
8092
8092
  <name> The name of the Sanity Function
8093
8093
 
@@ -8115,7 +8115,7 @@ Examples
8115
8115
  }, testFunctionsCommand = {
8116
8116
  name: "test",
8117
8117
  group: "functions",
8118
- helpText: helpText$9,
8118
+ helpText: helpText$a,
8119
8119
  signature: "<name> [--data <json>] [--file <filename>] [--timeout <seconds>] [--api <version>] [--dataset <name>] [--project-id] <id>]",
8120
8120
  description: "Invoke a local Sanity Function",
8121
8121
  async action(args, context) {
@@ -8195,11 +8195,11 @@ const commonMistakes = { get: "list" }, levenThreshold = 3, coreCommands = [
8195
8195
  "undeploy",
8196
8196
  "uninstall",
8197
8197
  "users"
8198
- ], discouragedCommands = ["upgrade", "check", "configcheck", "uninstall"], helpText$8 = `
8198
+ ], discouragedCommands = ["upgrade", "check", "configcheck", "uninstall"], helpText$9 = `
8199
8199
  Run the command again within a Sanity project directory, where "sanity"
8200
8200
  is installed as a dependency.`;
8201
8201
  function getNoSuchCommandText(cmdName, parentGroupName, groups) {
8202
- return parentGroupName && groups && groups[parentGroupName] ? suggestCommand(cmdName, groups[parentGroupName], parentGroupName) : coreCommands.includes(cmdName) ? `Command "${cmdName}" is not available outside of a Sanity project context.${helpText$8}` : suggestCommand(cmdName, groups ? groups.default : []);
8202
+ return parentGroupName && groups && groups[parentGroupName] ? suggestCommand(cmdName, groups[parentGroupName], parentGroupName) : coreCommands.includes(cmdName) ? `Command "${cmdName}" is not available outside of a Sanity project context.${helpText$9}` : suggestCommand(cmdName, groups ? groups.default : []);
8203
8203
  }
8204
8204
  function suggestCommand(cmdName, group, parentGroupName = null) {
8205
8205
  const closest = group.filter((command2) => !discouragedCommands.includes(command2.name)).map((command2) => leven(command2.name, cmdName)).reduce(
@@ -53905,7 +53905,7 @@ ${err.message}`);
53905
53905
  throw new Error(
53906
53906
  `Given organization ID (${flags.organization}) not found, or you do not have access to it`
53907
53907
  );
53908
- if (!await hasProjectAttachGrant(flags.organization))
53908
+ if (!await hasProjectAttachGrant2(flags.organization))
53909
53909
  throw new Error(
53910
53910
  "You lack the necessary permissions to attach a project to this organization"
53911
53911
  );
@@ -54170,7 +54170,7 @@ The default dataset configuration has a public dataset named "production".`;
54170
54170
  }
54171
54171
  return cliFlags;
54172
54172
  }
54173
- async function createOrganization(props = {}) {
54173
+ async function createOrganization2(props = {}) {
54174
54174
  const name = props.name || await prompt2.single({
54175
54175
  type: "input",
54176
54176
  message: "Organization name:",
@@ -54200,13 +54200,13 @@ The default dataset configuration has a public dataset named "production".`;
54200
54200
  default: defaultOrganizationId || void 0,
54201
54201
  choices: organizationChoices
54202
54202
  });
54203
- return chosenOrg === "-new-" ? createOrganization().then((org) => org.id) : chosenOrg || void 0;
54203
+ return chosenOrg === "-new-" ? createOrganization2().then((org) => org.id) : chosenOrg || void 0;
54204
54204
  }
54205
54205
  async function getOrganizationId(organizations) {
54206
54206
  if (organizations.length === 0)
54207
- return createOrganization().then((org) => org.id);
54207
+ return createOrganization2().then((org) => org.id);
54208
54208
  loadEnv.debug(`User has ${organizations.length} organization(s), checking attach access`);
54209
- const withGrantInfo = await getOrganizationsWithAttachGrantInfo(organizations), withAttach = withGrantInfo.filter(({ hasAttachGrant }) => hasAttachGrant);
54209
+ const withGrantInfo = await getOrganizationsWithAttachGrantInfo2(organizations), withAttach = withGrantInfo.filter(({ hasAttachGrant }) => hasAttachGrant);
54210
54210
  loadEnv.debug("User has attach access to %d organizations.", withAttach.length);
54211
54211
  const organizationChoices = [
54212
54212
  ...withGrantInfo.map(({ organization, hasAttachGrant }) => ({
@@ -54223,9 +54223,9 @@ The default dataset configuration has a public dataset named "production".`;
54223
54223
  default: defaultOrganizationId || void 0,
54224
54224
  choices: organizationChoices
54225
54225
  });
54226
- return chosenOrg === "-new-" ? createOrganization().then((org) => org.id) : chosenOrg || void 0;
54226
+ return chosenOrg === "-new-" ? createOrganization2().then((org) => org.id) : chosenOrg || void 0;
54227
54227
  }
54228
- async function hasProjectAttachGrant(orgId) {
54228
+ async function hasProjectAttachGrant2(orgId) {
54229
54229
  const requiredGrantGroup = "sanity.organization.projects", requiredGrant = "attach", client2 = apiClient({ requireProject: !1, requireUser: !0 }).clone().config({ apiVersion: "v2021-06-07" });
54230
54230
  try {
54231
54231
  return ((await client2.request({ uri: `organizations/${orgId}/grants` }))[requiredGrantGroup] || []).some(
@@ -54235,11 +54235,11 @@ The default dataset configuration has a public dataset named "production".`;
54235
54235
  return err.statusCode === 401 ? (loadEnv.debug("No access to organization %s (401)", orgId), !1) : (loadEnv.debug("Error checking grants for organization %s: %s", orgId, err.message), !1);
54236
54236
  }
54237
54237
  }
54238
- function getOrganizationsWithAttachGrantInfo(organizations) {
54238
+ function getOrganizationsWithAttachGrantInfo2(organizations) {
54239
54239
  return pMap(
54240
54240
  organizations,
54241
54241
  async (organization) => ({
54242
- hasAttachGrant: await hasProjectAttachGrant(organization.id),
54242
+ hasAttachGrant: await hasProjectAttachGrant2(organization.id),
54243
54243
  organization
54244
54244
  }),
54245
54245
  { concurrency: 3 }
@@ -54379,7 +54379,7 @@ function getImportCommand(outputPath, studioVersion) {
54379
54379
  );
54380
54380
  }
54381
54381
  }
54382
- const helpText$7 = `
54382
+ const helpText$8 = `
54383
54383
  Options
54384
54384
  -y, --yes Use unattended mode, accepting defaults and using only flags for choices
54385
54385
  --project, --project-id <projectId> Project ID to use for the studio
@@ -54432,7 +54432,7 @@ Examples
54432
54432
  name: "init",
54433
54433
  signature: "",
54434
54434
  description: "Initializes a new Sanity Studio and/or project",
54435
- helpText: helpText$7,
54435
+ helpText: helpText$8,
54436
54436
  action: async (args, context) => {
54437
54437
  const [type2] = args.argsWithoutOptions;
54438
54438
  if (type2)
@@ -54470,7 +54470,7 @@ Examples
54470
54470
  const { output } = context, { print } = output, url = "https://www.sanity.io/learn";
54471
54471
  print(`Opening ${url}`), await open(url);
54472
54472
  }
54473
- }, helpText$6 = `
54473
+ }, helpText$7 = `
54474
54474
  Options
54475
54475
  --sso <slug> Log in using Single Sign On, using the given slug
54476
54476
  --provider <providerId> Authenticate against a specific provider
@@ -54488,16 +54488,16 @@ Examples
54488
54488
  `, loginCommand = {
54489
54489
  name: "login",
54490
54490
  signature: "[--sso <slug>] [--provider <providerId>] [--no-open]",
54491
- helpText: helpText$6,
54491
+ helpText: helpText$7,
54492
54492
  description: "Authenticates the CLI for access to Sanity projects",
54493
54493
  action: login
54494
- }, helpText$5 = `
54494
+ }, helpText$6 = `
54495
54495
  Examples
54496
54496
  # Log out of the CLI
54497
54497
  sanity logout
54498
54498
  `, logoutCommand = {
54499
54499
  name: "logout",
54500
- helpText: helpText$5,
54500
+ helpText: helpText$6,
54501
54501
  signature: "logout",
54502
54502
  description: "Logs out the CLI from the current user session",
54503
54503
  async action(args, { output, apiClient }) {
@@ -54527,6 +54527,239 @@ ${err.message}`));
54527
54527
  const { output, cliConfig } = context, { print } = output, projectId = cliConfig?.api?.projectId, url = projectId ? `https://www.sanity.io/manage/project/${projectId}` : "https://www.sanity.io/manage/";
54528
54528
  print(`Opening ${url}`), await open(url);
54529
54529
  }
54530
+ };
54531
+ async function hasProjectAttachGrant(orgId, context) {
54532
+ const requiredGrantGroup = "sanity.organization.projects", requiredGrant = "attach", client2 = context.apiClient({ requireProject: !1, requireUser: !0 }).withConfig({ apiVersion: "v2021-06-07" });
54533
+ try {
54534
+ return ((await client2.request({ uri: `organizations/${orgId}/grants` }))[requiredGrantGroup] || []).some(
54535
+ (resource) => resource.grants && resource.grants.some((grant) => grant.name === requiredGrant)
54536
+ );
54537
+ } catch {
54538
+ return !1;
54539
+ }
54540
+ }
54541
+ function getOrganizationsWithAttachGrantInfo(organizations, context) {
54542
+ return pMap(
54543
+ organizations,
54544
+ async (organization) => ({
54545
+ hasAttachGrant: await hasProjectAttachGrant(organization.id, context),
54546
+ organization
54547
+ }),
54548
+ { concurrency: 3 }
54549
+ );
54550
+ }
54551
+ function getOrganizationChoices(withGrantInfo, prompt2) {
54552
+ const choices2 = withGrantInfo.map(({ organization, hasAttachGrant }) => ({
54553
+ value: organization.id,
54554
+ name: `${organization.name} [${organization.id}]`,
54555
+ disabled: hasAttachGrant ? !1 : "Insufficient permissions"
54556
+ }));
54557
+ return prompt2 && choices2.push(
54558
+ new prompt2.Separator(),
54559
+ { value: "-new-", name: "Create new organization", disabled: !1 },
54560
+ new prompt2.Separator()
54561
+ ), choices2;
54562
+ }
54563
+ async function createOrganization(context, user, props = {}) {
54564
+ const { prompt: prompt2, apiClient } = context, name = props.name || await prompt2.single({
54565
+ type: "input",
54566
+ message: "Organization name:",
54567
+ default: void 0,
54568
+ validate(input2) {
54569
+ return input2.length === 0 ? "Organization name cannot be empty" : input2.length > 100 ? "Organization name cannot be longer than 100 characters" : !0;
54570
+ }
54571
+ }), spinner = context.output.spinner("Creating organization").start(), organization = await apiClient({ requireProject: !1, requireUser: !0 }).request({
54572
+ uri: "/organizations",
54573
+ method: "POST",
54574
+ body: { name }
54575
+ });
54576
+ return spinner.succeed(), organization;
54577
+ }
54578
+ async function promptForOrganizationSelection(choices2, defaultChoice, context) {
54579
+ return context.prompt.single({
54580
+ message: "Select organization:",
54581
+ type: "list",
54582
+ choices: choices2,
54583
+ default: defaultChoice
54584
+ });
54585
+ }
54586
+ async function getOrganization(context, user, unattended, specifiedOrgId) {
54587
+ const { apiClient, output } = context, client2 = apiClient({ requireUser: !0, requireProject: !1 }), spinner = output.spinner("Loading organizations").start();
54588
+ let organizations;
54589
+ try {
54590
+ organizations = await client2.request({ uri: "/organizations" });
54591
+ } catch (error2) {
54592
+ throw spinner.fail(), error2;
54593
+ }
54594
+ if (specifiedOrgId) {
54595
+ const org = organizations.find((o) => o.id === specifiedOrgId || o.slug === specifiedOrgId);
54596
+ if (!org)
54597
+ throw spinner.fail(), new Error(`Organization "${specifiedOrgId}" not found or you don't have access to it`);
54598
+ return spinner.succeed(), org;
54599
+ }
54600
+ if (organizations.length === 0)
54601
+ return spinner.succeed(), output.print("You need to create an organization to create projects."), createOrganization(context).then((org) => ({
54602
+ id: org.id,
54603
+ name: org.name,
54604
+ slug: org.slug || org.id
54605
+ }));
54606
+ const withGrantInfo = await getOrganizationsWithAttachGrantInfo(organizations, context);
54607
+ spinner.succeed();
54608
+ const withAttach = withGrantInfo.filter(({ hasAttachGrant }) => hasAttachGrant);
54609
+ if (unattended || !isInteractive$1)
54610
+ return withAttach.length > 0 ? withAttach[0].organization : void 0;
54611
+ const organizationChoices = getOrganizationChoices(withGrantInfo, context.prompt), defaultOrganizationId = withAttach.length === 1 ? withAttach[0].organization.id : organizations.find((org) => org.name === user?.name)?.id, chosenOrg = await promptForOrganizationSelection(
54612
+ organizationChoices,
54613
+ defaultOrganizationId,
54614
+ context
54615
+ );
54616
+ return chosenOrg === "-new-" ? createOrganization(context).then((org) => ({
54617
+ id: org.id,
54618
+ name: org.name,
54619
+ slug: org.slug || org.id
54620
+ })) : organizations.find((org) => org.id === chosenOrg) || void 0;
54621
+ }
54622
+ function validateProjectName(input2) {
54623
+ return !input2 || input2.trim() === "" ? "Project name cannot be empty" : input2.length > 80 ? "Project name cannot be longer than 80 characters" : !0;
54624
+ }
54625
+ async function promptForProjectName(prompt2) {
54626
+ return prompt2.single({
54627
+ type: "input",
54628
+ message: "Project name:",
54629
+ default: "My Sanity Project",
54630
+ validate: validateProjectName
54631
+ });
54632
+ }
54633
+ const DATASET_INFO_TEXT = `Your content will be stored in a dataset that can be public or private, depending on
54634
+ whether you want to query your content with or without authentication.
54635
+ The default dataset configuration has a public dataset named "production".`;
54636
+ async function promptAndCreateDataset(options2) {
54637
+ const { context, datasetName, datasetVisibility, unattended } = options2, { prompt: prompt2, output } = context;
54638
+ let finalDatasetName, finalVisibility, useDefaultConfig = !1;
54639
+ return datasetName ? finalDatasetName = datasetName : unattended ? (finalDatasetName = "production", useDefaultConfig = !0) : (output.print(DATASET_INFO_TEXT), useDefaultConfig = await promptForDefaultConfig(prompt2), useDefaultConfig ? finalDatasetName = "production" : finalDatasetName = await promptForDatasetName(prompt2, {
54640
+ message: "Name of your first dataset:"
54641
+ })), datasetVisibility ? finalVisibility = datasetVisibility : unattended || useDefaultConfig ? finalVisibility = "public" : finalVisibility = await promptForAclMode(prompt2, output), { name: finalDatasetName, visibility: finalVisibility };
54642
+ }
54643
+ async function createDatasetForProject(context, projectId, datasetName, visibility) {
54644
+ const { apiClient, output } = context, spinner = output.spinner("Creating dataset").start();
54645
+ try {
54646
+ return await apiClient({ api: { projectId } }).datasets.create(datasetName, { aclMode: visibility }), spinner.succeed(), { name: datasetName, visibility };
54647
+ } catch (err) {
54648
+ throw spinner.fail(), err;
54649
+ }
54650
+ }
54651
+ async function createProjectWithMetadata(apiClient, displayName, organizationId, context, extraMetadata = {}) {
54652
+ const { output } = context, spinner = output.spinner("Creating project").start();
54653
+ try {
54654
+ const createOptions = {
54655
+ displayName,
54656
+ organizationId,
54657
+ metadata: {
54658
+ integration: "cli",
54659
+ ...extraMetadata
54660
+ }
54661
+ }, result = await createProject(apiClient, createOptions);
54662
+ return spinner.succeed(), result;
54663
+ } catch (error2) {
54664
+ throw spinner.fail(), error2;
54665
+ }
54666
+ }
54667
+ function formatProjectUrl(projectId, apiHost) {
54668
+ return `https://www.${new URL(apiHost).hostname.split(".").slice(-2).join(".")}/manage/project/${projectId}`;
54669
+ }
54670
+ function printProjectCreationSuccess(result, format, context) {
54671
+ const { output, apiClient } = context;
54672
+ if (format === "json") {
54673
+ output.print(JSON.stringify(result, null, 2));
54674
+ return;
54675
+ }
54676
+ output.print("Project created successfully!"), output.print(`ID: ${result.projectId}`), output.print(`Name: ${result.displayName}`), output.print(`Organization: ${result.organization?.name || "Personal"}`), result.dataset && output.print(`Dataset: ${result.dataset.name} (${result.dataset.visibility})`);
54677
+ const { apiHost } = apiClient({
54678
+ requireProject: !1,
54679
+ requireUser: !1
54680
+ }).config();
54681
+ output.print(""), output.print(`Manage your project: ${formatProjectUrl(result.projectId, apiHost)}`);
54682
+ }
54683
+ async function createProjectAction(options2, context) {
54684
+ const { apiClient, prompt: prompt2 } = context;
54685
+ apiClient({ requireUser: !0, requireProject: !1 });
54686
+ const projectName = options2.projectName || (options2.unattended || !isInteractive$1 ? "My Sanity Project" : await promptForProjectName(prompt2)), organization = await getOrganization(
54687
+ context,
54688
+ void 0,
54689
+ // user - not needed for projects create
54690
+ options2.unattended,
54691
+ options2.organizationId
54692
+ ), project = await createProjectWithMetadata(apiClient, projectName, organization?.id, context), result = {
54693
+ projectId: project.projectId,
54694
+ displayName: project.displayName,
54695
+ organization
54696
+ };
54697
+ if (options2.createDataset) {
54698
+ const { name: datasetName, visibility } = await promptAndCreateDataset({
54699
+ context,
54700
+ datasetName: options2.datasetName,
54701
+ datasetVisibility: options2.datasetVisibility,
54702
+ unattended: options2.unattended || !isInteractive$1
54703
+ });
54704
+ try {
54705
+ const dataset = await createDatasetForProject(
54706
+ context,
54707
+ project.projectId,
54708
+ datasetName,
54709
+ visibility
54710
+ );
54711
+ result.dataset = dataset;
54712
+ } catch (err) {
54713
+ context.output.warn(`Project created but dataset creation failed: ${err.message}`);
54714
+ }
54715
+ }
54716
+ return result;
54717
+ }
54718
+ const helpText$5 = `
54719
+ Examples
54720
+ sanity projects create
54721
+ sanity projects create "My New Project"
54722
+ sanity projects create "My Project" --organization=my-org
54723
+ sanity projects create "My Project" --dataset
54724
+ sanity projects create "My Project" --dataset=staging --dataset-visibility=private
54725
+ sanity projects create "CI Project" --yes --json
54726
+
54727
+ Options
54728
+ --organization <slug|id> Organization to create the project in
54729
+ --dataset [name] Create a dataset. Prompts for name/visibility unless specified or --yes used
54730
+ --dataset-visibility <mode> Dataset visibility: public or private
54731
+ --json JSON output format
54732
+ -y, --yes Skip prompts and use defaults (project: "My Sanity Project", dataset: production, visibility: public)
54733
+ `, createProjectCommand = {
54734
+ name: "create",
54735
+ group: "projects",
54736
+ signature: "[PROJECT_NAME]",
54737
+ helpText: helpText$5,
54738
+ description: "Create a new Sanity project",
54739
+ action: async (args, context) => {
54740
+ const [projectName] = args.argsWithoutOptions, {
54741
+ organization,
54742
+ dataset,
54743
+ "dataset-visibility": datasetVisibility,
54744
+ json: json2,
54745
+ yes,
54746
+ y
54747
+ } = args.extOptions;
54748
+ let datasetName, createDataset = !1;
54749
+ dataset === !0 ? (createDataset = !0, datasetName = void 0) : typeof dataset == "string" && (createDataset = !0, datasetName = dataset);
54750
+ const result = await createProjectAction(
54751
+ {
54752
+ projectName,
54753
+ organizationId: organization,
54754
+ createDataset,
54755
+ datasetName,
54756
+ datasetVisibility,
54757
+ unattended: y || yes
54758
+ },
54759
+ context
54760
+ );
54761
+ printProjectCreationSuccess(result, json2 ? "json" : "text", context);
54762
+ }
54530
54763
  }, headings = ["id", "members", "name", "url", "created"], helpText$4 = `
54531
54764
  Options
54532
54765
  --sort <field> Sort output by specified column
@@ -54567,7 +54800,7 @@ Examples
54567
54800
  name: "projects",
54568
54801
  signature: "[COMMAND]",
54569
54802
  isGroupRoot: !0,
54570
- description: "Lists all projects associated with your logged-in account"
54803
+ description: "Manage Sanity projects - list, create"
54571
54804
  }, helpText$3 = `
54572
54805
  Examples
54573
54806
  # Check telemetry consent status for your logged in user
@@ -54788,6 +55021,7 @@ const baseCommands = [
54788
55021
  projectGroup,
54789
55022
  learnCommand,
54790
55023
  listProjectsCommand,
55024
+ createProjectCommand,
54791
55025
  codemodCommand,
54792
55026
  telemetryGroup,
54793
55027
  disableTelemetryCommand,