@sanity/cli 3.74.0 → 3.74.2-canary.67

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.
@@ -46514,23 +46514,8 @@ var typescriptExports = requireTypescript(), typescript = /* @__PURE__ */ loadEn
46514
46514
  __proto__: null,
46515
46515
  default: typescript
46516
46516
  }, [typescriptExports]);
46517
- const defaultTemplate$1 = `
46518
- import {defineCliConfig} from 'sanity/cli'
46519
-
46520
- export default defineCliConfig({
46521
- api: {
46522
- projectId: '%projectId%',
46523
- dataset: '%dataset%'
46524
- },
46525
- /**
46526
- * Enable auto-updates for studios.
46527
- * Learn more at https://www.sanity.io/docs/cli#auto-updates
46528
- */
46529
- autoUpdates: __BOOL__autoUpdates__,
46530
- })
46531
- `;
46532
- function createCliConfig(options2) {
46533
- const variables = options2, template = defaultTemplate$1.trimStart(), ast = mainExports.parse(template, { parser });
46517
+ function processTemplate(options2) {
46518
+ const { template, variables, includeBooleanTransform = !1 } = options2, ast = mainExports.parse(template.trimStart(), { parser });
46534
46519
  return traverse__default.default(ast, {
46535
46520
  StringLiteral: {
46536
46521
  enter({ node }) {
@@ -46544,24 +46529,63 @@ function createCliConfig(options2) {
46544
46529
  node.value = typeof newValue == "string" ? newValue : "";
46545
46530
  }
46546
46531
  },
46547
- Identifier: {
46548
- enter(path2) {
46549
- if (!path2.node.name.startsWith("__BOOL__"))
46550
- return;
46551
- const variableName = path2.node.name.replace(
46552
- /^__BOOL__(.+?)__$/,
46553
- "$1"
46554
- );
46555
- if (!(variableName in variables))
46556
- throw new Error(`Template variable '${variableName}' not defined`);
46557
- const value = variables[variableName];
46558
- if (typeof value != "boolean")
46559
- throw new Error(`Expected boolean value for '${variableName}'`);
46560
- path2.replaceWith({ type: "BooleanLiteral", value });
46532
+ ...includeBooleanTransform && {
46533
+ Identifier: {
46534
+ enter(path2) {
46535
+ if (!path2.node.name.startsWith("__BOOL__"))
46536
+ return;
46537
+ const variableName = path2.node.name.replace(/^__BOOL__(.+?)__$/, "$1");
46538
+ if (!(variableName in variables))
46539
+ throw new Error(`Template variable '${variableName.toString()}' not defined`);
46540
+ const value = variables[variableName];
46541
+ if (typeof value != "boolean")
46542
+ throw new Error(`Expected boolean value for '${variableName.toString()}'`);
46543
+ path2.replaceWith({ type: "BooleanLiteral", value });
46544
+ }
46561
46545
  }
46562
46546
  }
46563
46547
  }), mainExports.print(ast, { quote: "single" }).code;
46564
46548
  }
46549
+ const defaultTemplate$1 = `
46550
+ import {defineCliConfig} from 'sanity/cli'
46551
+
46552
+ export default defineCliConfig({
46553
+ api: {
46554
+ projectId: '%projectId%',
46555
+ dataset: '%dataset%'
46556
+ },
46557
+ /**
46558
+ * Enable auto-updates for studios.
46559
+ * Learn more at https://www.sanity.io/docs/cli#auto-updates
46560
+ */
46561
+ autoUpdates: __BOOL__autoUpdates__,
46562
+ })
46563
+ `;
46564
+ function createCliConfig(options2) {
46565
+ return processTemplate({
46566
+ template: defaultTemplate$1,
46567
+ variables: options2,
46568
+ includeBooleanTransform: !0
46569
+ });
46570
+ }
46571
+ const defaultCoreAppTemplate = `
46572
+ import {defineCliConfig} from 'sanity/cli'
46573
+
46574
+ export default defineCliConfig({
46575
+ api: {
46576
+ organizationId: '%organizationId%'
46577
+ },
46578
+ __experimental_coreAppConfiguration: {
46579
+ appLocation: '%appLocation%'
46580
+ },
46581
+ })
46582
+ `;
46583
+ function createCoreAppCliConfig(options2) {
46584
+ return processTemplate({
46585
+ template: defaultCoreAppTemplate,
46586
+ variables: options2
46587
+ });
46588
+ }
46565
46589
  /*!
46566
46590
  * isobject <https://github.com/jonschlinkert/isobject>
46567
46591
  *
@@ -46630,7 +46654,7 @@ function createPackageManifest(data) {
46630
46654
  ...getCommonManifest(data),
46631
46655
  main: "package.json",
46632
46656
  keywords: ["sanity"],
46633
- scripts: {
46657
+ scripts: data.scripts || {
46634
46658
  dev: "sanity dev",
46635
46659
  start: "sanity start",
46636
46660
  build: "sanity build",
@@ -46699,25 +46723,42 @@ export default defineConfig({
46699
46723
  };
46700
46724
  function createStudioConfig(options2) {
46701
46725
  const variables = { ...defaultVariables, ...options2.variables };
46702
- if (typeof options2.template == "function")
46703
- return options2.template(variables).trimStart();
46704
- const template = (options2.template || defaultTemplate).trimStart(), ast = mainExports.parse(template, { parser });
46705
- return traverse__default.default(ast, {
46706
- StringLiteral: {
46707
- enter({ node }) {
46708
- const value = node.value;
46709
- if (!value.startsWith("%") || !value.endsWith("%"))
46710
- return;
46711
- const variableName = value.slice(1, -1);
46712
- if (!(variableName in variables))
46713
- throw new Error(`Template variable '${value}' not defined`);
46714
- const newValue = variables[variableName];
46715
- node.value = typeof newValue == "string" ? newValue : "";
46716
- }
46717
- }
46718
- }), mainExports.print(ast, { quote: "single" }).code;
46726
+ return typeof options2.template == "function" ? options2.template(variables).trimStart() : processTemplate({
46727
+ template: options2.template || defaultTemplate,
46728
+ variables
46729
+ });
46730
+ }
46731
+ const coreAppTemplates = ["core-app"];
46732
+ function determineCoreAppTemplate(templateName) {
46733
+ return coreAppTemplates.includes(templateName);
46719
46734
  }
46720
- const blogTemplate = {}, cleanTemplate = {}, configTemplate$3 = `
46735
+ const blogTemplate = {}, cleanTemplate = {}, coreAppTemplate = {
46736
+ dependencies: {
46737
+ "@sanity/sdk": "^0.0.0-alpha",
46738
+ "@sanity/sdk-react": "^0.0.0-alpha",
46739
+ react: "^19",
46740
+ "react-dom": "^19"
46741
+ },
46742
+ devDependencies: {
46743
+ /*
46744
+ * this will be changed to eslint-config sanity,
46745
+ * eslint.config generation will be a fast follow
46746
+ */
46747
+ "@sanity/eslint-config-studio": "^5.0.1",
46748
+ "@types/react": "^18.0.25",
46749
+ eslint: "^9.9.0",
46750
+ prettier: "^3.0.2",
46751
+ sanity: "^3",
46752
+ typescript: "^5.1.6"
46753
+ },
46754
+ appLocation: "./src/App.tsx",
46755
+ scripts: {
46756
+ // this will eventually run a concurrently process with another in-flight utility
46757
+ dev: "sanity app dev",
46758
+ build: "sanity app build",
46759
+ start: "sanity app start"
46760
+ }
46761
+ }, configTemplate$3 = `
46721
46762
  import {defineConfig, isDev} from 'sanity'
46722
46763
  import {visionTool} from '@sanity/vision'
46723
46764
  import {structureTool} from 'sanity/structure'
@@ -46895,6 +46936,7 @@ export default defineConfig({
46895
46936
  }, templates = {
46896
46937
  blog: blogTemplate,
46897
46938
  clean: cleanTemplate,
46939
+ "core-app": coreAppTemplate,
46898
46940
  "get-started": getStartedTemplate,
46899
46941
  moviedb: movieTemplate,
46900
46942
  shopify: shopifyTemplate$1,
@@ -46915,7 +46957,7 @@ async function updateInitialTemplateMetadata(apiClient, projectId, templateName)
46915
46957
  }
46916
46958
  }
46917
46959
  async function bootstrapLocalTemplate(opts, context) {
46918
- const { apiClient, cliRoot, output } = context, templatesDir = path__default.default.join(cliRoot, "templates"), { outputPath, templateName, useTypeScript, packageName, variables } = opts, sourceDir = path__default.default.join(templatesDir, templateName), sharedDir = path__default.default.join(templatesDir, "shared"), template = templates[templateName];
46960
+ const { apiClient, cliRoot, output } = context, templatesDir = path__default.default.join(cliRoot, "templates"), { outputPath, templateName, useTypeScript, packageName, variables } = opts, sourceDir = path__default.default.join(templatesDir, templateName), sharedDir = path__default.default.join(templatesDir, "shared"), isCoreAppTemplate = determineCoreAppTemplate(templateName), template = templates[templateName];
46919
46961
  if (!template)
46920
46962
  throw new Error(`Template "${templateName}" not defined`);
46921
46963
  loadEnv.debug('Copying files from template "%s" to "%s"', templateName, outputPath);
@@ -46930,19 +46972,20 @@ async function bootstrapLocalTemplate(opts, context) {
46930
46972
  schemaUrl: opts.schemaUrl
46931
46973
  })), spinner.succeed(), spinner = output.spinner("Resolving latest module versions").start();
46932
46974
  const dependencyVersions = await resolveLatestVersions({
46933
- ...studioDependencies.dependencies,
46934
- ...studioDependencies.devDependencies,
46935
- ...template.dependencies || {}
46975
+ ...isCoreAppTemplate ? {} : studioDependencies.dependencies,
46976
+ ...isCoreAppTemplate ? {} : studioDependencies.devDependencies,
46977
+ ...template.dependencies || {},
46978
+ ...template.devDependencies || {}
46936
46979
  });
46937
46980
  spinner.succeed();
46938
46981
  const dependencies = Object.keys({
46939
- ...studioDependencies.dependencies,
46982
+ ...isCoreAppTemplate ? {} : studioDependencies.dependencies,
46940
46983
  ...template.dependencies
46941
46984
  }).reduce(
46942
46985
  (deps, dependency) => (deps[dependency] = dependencyVersions[dependency], deps),
46943
46986
  {}
46944
46987
  ), devDependencies = Object.keys({
46945
- ...studioDependencies.devDependencies,
46988
+ ...isCoreAppTemplate ? {} : studioDependencies.devDependencies,
46946
46989
  ...template.devDependencies
46947
46990
  }).reduce(
46948
46991
  (deps, dependency) => (deps[dependency] = dependencyVersions[dependency], deps),
@@ -46952,27 +46995,33 @@ async function bootstrapLocalTemplate(opts, context) {
46952
46995
  const packageManifest = await createPackageManifest({
46953
46996
  name: packageName,
46954
46997
  dependencies,
46955
- devDependencies
46956
- }), studioConfig = await createStudioConfig({
46998
+ devDependencies,
46999
+ scripts: template.scripts
47000
+ }), studioConfig = createStudioConfig({
46957
47001
  template: template.configTemplate,
46958
47002
  variables
46959
- }), cliConfig = await createCliConfig({
47003
+ }), cliConfig = isCoreAppTemplate ? createCoreAppCliConfig({
47004
+ appLocation: template.appLocation,
47005
+ organizationId: variables.organizationId
47006
+ }) : createCliConfig({
46960
47007
  projectId: variables.projectId,
46961
47008
  dataset: variables.dataset,
46962
47009
  autoUpdates: variables.autoUpdates
46963
47010
  }), codeExt = useTypeScript ? "ts" : "js";
46964
- return await Promise.all([
46965
- writeFileIfNotExists(`sanity.config.${codeExt}`, studioConfig),
46966
- writeFileIfNotExists(`sanity.cli.${codeExt}`, cliConfig),
46967
- writeFileIfNotExists("package.json", packageManifest),
46968
- writeFileIfNotExists(
46969
- "eslint.config.mjs",
46970
- `import studio from '@sanity/eslint-config-studio'
47011
+ return await Promise.all(
47012
+ [
47013
+ isCoreAppTemplate ? Promise.resolve(null) : writeFileIfNotExists(`sanity.config.${codeExt}`, studioConfig),
47014
+ writeFileIfNotExists(`sanity.cli.${codeExt}`, cliConfig),
47015
+ writeFileIfNotExists("package.json", packageManifest),
47016
+ writeFileIfNotExists(
47017
+ "eslint.config.mjs",
47018
+ `import studio from '@sanity/eslint-config-studio'
46971
47019
 
46972
47020
  export default [...studio]
46973
47021
  `
46974
- )
46975
- ]), loadEnv.debug("Updating initial template metadata"), await updateInitialTemplateMetadata(apiClient, variables.projectId, `cli-${templateName}`), spinner.succeed(), template;
47022
+ )
47023
+ ].filter(Boolean)
47024
+ ), loadEnv.debug("Updating initial template metadata"), await updateInitialTemplateMetadata(apiClient, variables.projectId, `cli-${templateName}`), spinner.succeed(), template;
46976
47025
  async function writeFileIfNotExists(fileName, content) {
46977
47026
  const filePath = path__default.default.join(outputPath, fileName);
46978
47027
  try {
@@ -52591,7 +52640,7 @@ ${err.message}`);
52591
52640
  } else unattended || (trace.log({ step: "login" }), await getOrCreateUser());
52592
52641
  let introMessage = "Fetching existing projects";
52593
52642
  cliFlags.quickstart && (introMessage = "Eject your existing project's Sanity configuration"), success(introMessage), print("");
52594
- const flags = await prepareFlags(), { projectId, displayName, isFirstProject, datasetName, schemaUrl } = await getProjectDetails(), sluggedName = lodashExports.deburr(displayName.toLowerCase()).replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
52643
+ const flags = await prepareFlags(), isCoreAppTemplate = cliFlags.template ? determineCoreAppTemplate(cliFlags.template) : !1, { projectId, displayName, isFirstProject, datasetName, schemaUrl, organizationId } = await getProjectDetails(), sluggedName = lodashExports.deburr(displayName.toLowerCase()).replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
52595
52644
  if (bareOutput) {
52596
52645
  success("Below are your project details"), print(""), print(`Project ID: ${chalk2.cyan(projectId)}`), print(`Dataset: ${chalk2.cyan(datasetName)}`), print(
52597
52646
  `
@@ -52781,11 +52830,15 @@ ${chalk2.green("Success!")} Your Sanity configuration files has been added to th
52781
52830
  }[pkgManager];
52782
52831
  outputPath === process.cwd() ? (print(`
52783
52832
  ${chalk2.green("Success!")} Now, use this command to continue:
52784
- `), print(`${chalk2.cyan(devCommand)} - to run Sanity Studio
52785
- `)) : (print(`
52833
+ `), print(
52834
+ `${chalk2.cyan(devCommand)} - to run ${isCoreAppTemplate ? "your Sanity application" : "Sanity Studio"}
52835
+ `
52836
+ )) : (print(`
52786
52837
  ${chalk2.green("Success!")} Now, use these commands to continue:
52787
- `), print(`First: ${chalk2.cyan(`cd ${outputPath}`)} - to enter project\u2019s directory`), print(`Then: ${chalk2.cyan(devCommand)} - to run Sanity Studio
52788
- `)), print("Other helpful commands"), print("npx sanity docs - to open the documentation in a browser"), print("npx sanity manage - to open the project settings in a browser"), print("npx sanity help - to explore the CLI manual");
52838
+ `), print(`First: ${chalk2.cyan(`cd ${outputPath}`)} - to enter project\u2019s directory`), print(
52839
+ `Then: ${chalk2.cyan(devCommand)} -to run ${isCoreAppTemplate ? "your Sanity application" : "Sanity Studio"}
52840
+ `
52841
+ )), print("Other helpful commands"), print("npx sanity docs - to open the documentation in a browser"), print("npx sanity manage - to open the project settings in a browser"), print("npx sanity help - to explore the CLI manual");
52789
52842
  const sendInvite = isFirstProject && await prompt2.single({
52790
52843
  type: "confirm",
52791
52844
  message: "We have an excellent developer community, would you like us to send you an invitation to join?",
@@ -52812,6 +52865,16 @@ ${chalk2.green("Success!")} Now, use these commands to continue:
52812
52865
  isFirstProject: data.isFirstProject
52813
52866
  }), data;
52814
52867
  }
52868
+ if (isCoreAppTemplate) {
52869
+ const organizations = await apiClient({ requireUser: !0, requireProject: !1 }).request({ uri: "/organizations" });
52870
+ return {
52871
+ projectId: "",
52872
+ displayName: "",
52873
+ datasetName: "",
52874
+ isFirstProject: !1,
52875
+ organizationId: await getOrganizationId(organizations)
52876
+ };
52877
+ }
52815
52878
  loadEnv.debug("Prompting user to select or create a project");
52816
52879
  const project = await getOrCreateProject();
52817
52880
  loadEnv.debug(`Project with name ${project.displayName} selected`), loadEnv.debug("Prompting user to select or create a dataset");
@@ -53030,7 +53093,8 @@ The default dataset configuration has a public dataset named "production".`;
53030
53093
  autoUpdates,
53031
53094
  dataset: datasetName,
53032
53095
  projectId,
53033
- projectName: displayName || answers.projectName
53096
+ projectName: displayName || answers.projectName,
53097
+ organizationId
53034
53098
  };
53035
53099
  return remoteTemplateInfo ? bootstrapRemoteTemplate(
53036
53100
  {
@@ -53116,10 +53180,10 @@ The default dataset configuration has a public dataset named "production".`;
53116
53180
  return cliFlags;
53117
53181
  }
53118
53182
  async function getOrganizationId(organizations) {
53119
- let organizationId = flags.organization;
53183
+ let orgId = flags.organization;
53120
53184
  if (unattended)
53121
- return organizationId || void 0;
53122
- if (organizations.length > 0 && !organizationId) {
53185
+ return orgId || void 0;
53186
+ if (organizations.length > 0 && !orgId) {
53123
53187
  loadEnv.debug(`User has ${organizations.length} organization(s), checking attach access`);
53124
53188
  const withGrant = await getOrganizationsWithAttachGrant(organizations);
53125
53189
  if (withGrant.length === 0) {
@@ -53139,13 +53203,13 @@ The default dataset configuration has a public dataset named "production".`;
53139
53203
  type: "list",
53140
53204
  choices: organizationChoices
53141
53205
  });
53142
- chosenOrg && chosenOrg !== "none" && (organizationId = chosenOrg);
53143
- } else organizationId ? loadEnv.debug("User has defined organization flag explicitly (%s)", organizationId) : organizations.length === 0 && loadEnv.debug("User has no organizations, skipping selection prompt");
53144
- return organizationId || void 0;
53206
+ chosenOrg && chosenOrg !== "none" && (orgId = chosenOrg);
53207
+ } else orgId ? loadEnv.debug("User has defined organization flag explicitly (%s)", orgId) : organizations.length === 0 && loadEnv.debug("User has no organizations, skipping selection prompt");
53208
+ return orgId || void 0;
53145
53209
  }
53146
- async function hasProjectAttachGrant(organizationId) {
53210
+ async function hasProjectAttachGrant(orgId) {
53147
53211
  const requiredGrantGroup = "sanity.organization.projects", requiredGrant = "attach";
53148
- return ((await apiClient({ requireProject: !1, requireUser: !0 }).clone().config({ apiVersion: "v2021-06-07" }).request({ uri: `organizations/${organizationId}/grants` }))[requiredGrantGroup] || []).some(
53212
+ return ((await apiClient({ requireProject: !1, requireUser: !0 }).clone().config({ apiVersion: "v2021-06-07" }).request({ uri: `organizations/${orgId}/grants` }))[requiredGrantGroup] || []).some(
53149
53213
  (resource) => resource.grants && resource.grants.some((grant) => grant.name === requiredGrant)
53150
53214
  );
53151
53215
  }