@sanity/cli 3.93.1-next.9.198ab74452 → 3.94.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 (149) hide show
  1. package/lib/_chunks-cjs/cli.js +1 -1
  2. package/lib/_chunks-cjs/cli.js.map +1 -1
  3. package/package.json +10 -11
  4. package/templates/blog/README.md +1 -1
  5. package/templates/clean/README.md +1 -1
  6. package/templates/ecommerce/README.md +1 -1
  7. package/templates/get-started/README.md +1 -1
  8. package/templates/moviedb/README.md +1 -1
  9. package/templates/quickstart/README.md +1 -1
  10. package/src/CommandRunner.ts +0 -219
  11. package/src/__telemetry__/cli.telemetry.ts +0 -29
  12. package/src/__telemetry__/init.telemetry.ts +0 -95
  13. package/src/actions/codemod/codemodAction.ts +0 -109
  14. package/src/actions/codemod/mods/deskRename.ts +0 -19
  15. package/src/actions/codemod/mods/index.ts +0 -9
  16. package/src/actions/codemod/mods/partsTypeDirective.ts +0 -28
  17. package/src/actions/codemod/mods/reactIconsV3.ts +0 -54
  18. package/src/actions/codemod/types.ts +0 -10
  19. package/src/actions/init-plugin/bootstrapFromTemplate.ts +0 -196
  20. package/src/actions/init-project/bootstrapLocalTemplate.ts +0 -201
  21. package/src/actions/init-project/bootstrapRemoteTemplate.ts +0 -118
  22. package/src/actions/init-project/createAppCliConfig.ts +0 -24
  23. package/src/actions/init-project/createCliConfig.ts +0 -31
  24. package/src/actions/init-project/createPackageManifest.ts +0 -102
  25. package/src/actions/init-project/createStudioConfig.ts +0 -53
  26. package/src/actions/init-project/determineAppTemplate.ts +0 -13
  27. package/src/actions/init-project/fsUtils.ts +0 -40
  28. package/src/actions/init-project/git.ts +0 -59
  29. package/src/actions/init-project/initProject.ts +0 -1708
  30. package/src/actions/init-project/processTemplate.ts +0 -55
  31. package/src/actions/init-project/promptForDatasetName.ts +0 -68
  32. package/src/actions/init-project/prompts/index.ts +0 -51
  33. package/src/actions/init-project/prompts/nextjs.ts +0 -59
  34. package/src/actions/init-project/readPackageJson.ts +0 -17
  35. package/src/actions/init-project/templates/appQuickstart.ts +0 -23
  36. package/src/actions/init-project/templates/appSanityUi.ts +0 -25
  37. package/src/actions/init-project/templates/blog.ts +0 -5
  38. package/src/actions/init-project/templates/clean.ts +0 -5
  39. package/src/actions/init-project/templates/getStarted.ts +0 -37
  40. package/src/actions/init-project/templates/index.ts +0 -24
  41. package/src/actions/init-project/templates/moviedb.ts +0 -35
  42. package/src/actions/init-project/templates/nextjs/index.ts +0 -238
  43. package/src/actions/init-project/templates/nextjs/schemaTypes/blog.ts +0 -252
  44. package/src/actions/init-project/templates/quickstart.ts +0 -5
  45. package/src/actions/init-project/templates/shopify.ts +0 -78
  46. package/src/actions/init-project/templates/shopifyOnline.ts +0 -50
  47. package/src/actions/init-project/updateInitialTemplateMetadata.ts +0 -24
  48. package/src/actions/login/login.telemetry.ts +0 -18
  49. package/src/actions/login/login.ts +0 -350
  50. package/src/actions/login/types.ts +0 -19
  51. package/src/actions/project/createProject.ts +0 -36
  52. package/src/actions/telemetry/setTelemetryConsent.ts +0 -101
  53. package/src/actions/typegen/generate.telemetry.ts +0 -20
  54. package/src/actions/typegen/generateAction.ts +0 -210
  55. package/src/actions/versions/findSanityModuleVersions.ts +0 -185
  56. package/src/actions/yarn/events.ts +0 -73
  57. package/src/cli.ts +0 -350
  58. package/src/cliClient.ts +0 -62
  59. package/src/commands/blueprints/addBlueprintsCommand.ts +0 -155
  60. package/src/commands/blueprints/blueprintsGroup.ts +0 -10
  61. package/src/commands/blueprints/configBlueprintsCommand.ts +0 -86
  62. package/src/commands/blueprints/deployBlueprintsCommand.ts +0 -63
  63. package/src/commands/blueprints/destroyBlueprintsCommand.ts +0 -78
  64. package/src/commands/blueprints/infoBlueprintsCommand.ts +0 -55
  65. package/src/commands/blueprints/initBlueprintsCommand.ts +0 -99
  66. package/src/commands/blueprints/logsBlueprintsCommand.ts +0 -66
  67. package/src/commands/blueprints/planBlueprintsCommand.ts +0 -51
  68. package/src/commands/blueprints/stacksBlueprintsCommand.ts +0 -66
  69. package/src/commands/codemod/codemodCommand.ts +0 -32
  70. package/src/commands/debug/debugCommand.ts +0 -26
  71. package/src/commands/debug/printDebugInfo.ts +0 -243
  72. package/src/commands/docs/docsCommand.ts +0 -20
  73. package/src/commands/functions/devFunctionsCommand.ts +0 -73
  74. package/src/commands/functions/envFunctionsCommand.ts +0 -105
  75. package/src/commands/functions/functionsGroup.ts +0 -10
  76. package/src/commands/functions/logsFunctionsCommand.ts +0 -94
  77. package/src/commands/functions/testFunctionsCommand.ts +0 -93
  78. package/src/commands/help/helpCommand.ts +0 -21
  79. package/src/commands/help/showHelp.ts +0 -58
  80. package/src/commands/index.ts +0 -72
  81. package/src/commands/init/initCommand.ts +0 -123
  82. package/src/commands/install/installCommand.ts +0 -38
  83. package/src/commands/learn/learnCommand.ts +0 -20
  84. package/src/commands/login/loginCommand.ts +0 -29
  85. package/src/commands/logout/logoutCommand.ts +0 -52
  86. package/src/commands/manage/manageCommand.ts +0 -24
  87. package/src/commands/projects/listProjectsCommand.ts +0 -62
  88. package/src/commands/projects/projectsGroup.ts +0 -10
  89. package/src/commands/telemetry/disableTelemetryCommand.ts +0 -19
  90. package/src/commands/telemetry/enableTelemetryCommand.ts +0 -19
  91. package/src/commands/telemetry/telemetryGroup.ts +0 -10
  92. package/src/commands/telemetry/telemetryStatusCommand.ts +0 -89
  93. package/src/commands/typegen/generateTypesCommand.ts +0 -56
  94. package/src/commands/typegen/typegenGroup.ts +0 -10
  95. package/src/commands/versions/printVersionResult.ts +0 -51
  96. package/src/commands/versions/versionsCommand.ts +0 -13
  97. package/src/config.ts +0 -14
  98. package/src/debug.ts +0 -3
  99. package/src/index.ts +0 -6
  100. package/src/outputters/cliOutputter.ts +0 -47
  101. package/src/packageManager/getInstallCommand.ts +0 -26
  102. package/src/packageManager/getUpgradeCommand.ts +0 -52
  103. package/src/packageManager/index.ts +0 -33
  104. package/src/packageManager/installPackages.ts +0 -99
  105. package/src/packageManager/packageManagerChoice.ts +0 -204
  106. package/src/packageManager/uninstallPackages.ts +0 -44
  107. package/src/packageManager/yarnStub.ts +0 -22
  108. package/src/prompters/cliPrompter.ts +0 -9
  109. package/src/run.ts +0 -8
  110. package/src/studioDependencies.ts +0 -25
  111. package/src/types.ts +0 -387
  112. package/src/util/canLaunchBrowser.ts +0 -12
  113. package/src/util/cliWorker.ts +0 -34
  114. package/src/util/clientWrapper.ts +0 -119
  115. package/src/util/copy.ts +0 -50
  116. package/src/util/createExpiringConfig.ts +0 -80
  117. package/src/util/createTelemetryStore.ts +0 -204
  118. package/src/util/detectRuntime.ts +0 -12
  119. package/src/util/dynamicRequire.ts +0 -17
  120. package/src/util/frameworkPort.ts +0 -63
  121. package/src/util/generateCommandsDocumentation.ts +0 -62
  122. package/src/util/getCliConfig.ts +0 -172
  123. package/src/util/getCliVersion.ts +0 -22
  124. package/src/util/getLocalVersion.ts +0 -35
  125. package/src/util/getProjectDefaults.ts +0 -103
  126. package/src/util/getProviderName.ts +0 -9
  127. package/src/util/getUserConfig.ts +0 -15
  128. package/src/util/isCi.ts +0 -7
  129. package/src/util/isCommandGroup.ts +0 -7
  130. package/src/util/isInteractive.ts +0 -3
  131. package/src/util/isTrueish.ts +0 -8
  132. package/src/util/journeyConfig.ts +0 -280
  133. package/src/util/loadEnv.ts +0 -110
  134. package/src/util/mergeCommands.ts +0 -78
  135. package/src/util/neatStack.ts +0 -30
  136. package/src/util/noSuchCommandText.ts +0 -91
  137. package/src/util/parseArguments.ts +0 -76
  138. package/src/util/pathExists.ts +0 -14
  139. package/src/util/readJson.ts +0 -6
  140. package/src/util/readdirRecursive.ts +0 -26
  141. package/src/util/remoteTemplate.ts +0 -320
  142. package/src/util/resolveLatestVersions.ts +0 -24
  143. package/src/util/resolveRootDir.ts +0 -59
  144. package/src/util/telemetryDisclosure.ts +0 -45
  145. package/src/util/updateNotifier.ts +0 -158
  146. package/src/util/writeJson.ts +0 -6
  147. package/src/workers/getAndWriteJourneySchema.ts +0 -7
  148. package/src/workers/getCliConfig.ts +0 -14
  149. package/src/workers/typegenGenerate.ts +0 -228
@@ -1,55 +0,0 @@
1
- import traverse from '@babel/traverse'
2
- import {parse, print} from 'recast'
3
- import * as parser from 'recast/parsers/typescript'
4
-
5
- interface TemplateOptions<T> {
6
- template: string
7
- variables: T
8
- includeBooleanTransform?: boolean
9
- }
10
-
11
- export function processTemplate<T extends object>(options: TemplateOptions<T>): string {
12
- const {template, variables, includeBooleanTransform = false} = options
13
- const ast = parse(template.trimStart(), {parser})
14
-
15
- traverse(ast, {
16
- StringLiteral: {
17
- enter({node}) {
18
- const value = node.value
19
- if (!value.startsWith('%') || !value.endsWith('%')) {
20
- return
21
- }
22
- const variableName = value.slice(1, -1) as keyof T
23
- if (!(variableName in variables)) {
24
- throw new Error(`Template variable '${value}' not defined`)
25
- }
26
- const newValue = variables[variableName]
27
- /*
28
- * although there are valid non-strings in our config,
29
- * they're not in StringLiteral nodes, so assume undefined
30
- */
31
- node.value = typeof newValue === 'string' ? newValue : ''
32
- },
33
- },
34
- ...(includeBooleanTransform && {
35
- Identifier: {
36
- enter(path) {
37
- if (!path.node.name.startsWith('__BOOL__')) {
38
- return
39
- }
40
- const variableName = path.node.name.replace(/^__BOOL__(.+?)__$/, '$1') as keyof T
41
- if (!(variableName in variables)) {
42
- throw new Error(`Template variable '${variableName.toString()}' not defined`)
43
- }
44
- const value = variables[variableName]
45
- if (typeof value !== 'boolean') {
46
- throw new Error(`Expected boolean value for '${variableName.toString()}'`)
47
- }
48
- path.replaceWith({type: 'BooleanLiteral', value})
49
- },
50
- },
51
- }),
52
- })
53
-
54
- return print(ast, {quote: 'single'}).code
55
- }
@@ -1,68 +0,0 @@
1
- import chalk from 'chalk'
2
-
3
- import {type CliPrompter} from '../../types'
4
-
5
- const MAX_DATASET_NAME_LENGTH = 64
6
-
7
- const datasetNameError =
8
- 'Dataset names can only contain lowercase characters,' +
9
- 'numbers, underscores and dashes' +
10
- `and can be at most ${MAX_DATASET_NAME_LENGTH} characters.`
11
-
12
- export function promptForDatasetName(
13
- prompt: CliPrompter,
14
- options: {message?: string} = {},
15
- existingDatasets: string[] = [],
16
- ): Promise<string> {
17
- return prompt.single({
18
- type: 'input',
19
- message: 'Dataset name:',
20
- validate: (name) => {
21
- if (existingDatasets.includes(name)) {
22
- return 'Dataset name already exists'
23
- }
24
-
25
- if (!name || name.length < 2 || name.length > MAX_DATASET_NAME_LENGTH) {
26
- return `Dataset name must be between 2 and ${MAX_DATASET_NAME_LENGTH} characters`
27
- }
28
-
29
- if (name.toLowerCase() !== name) {
30
- return 'Dataset name must be lowercase'
31
- }
32
-
33
- if (name.replace(/\s/g, '') !== name) {
34
- return 'Dataset name cannot contain whitespace'
35
- }
36
-
37
- if (/^[^a-z0-9]/.test(name)) {
38
- return 'Dataset name must start with a character or letter'
39
- }
40
-
41
- if (/[-_]$/.test(name)) {
42
- return 'Dataset name must not end with a dash or an underscore'
43
- }
44
-
45
- const isValid = /^[a-z0-9][-\w]+$/.test(name)
46
- if (isValid) {
47
- return true
48
- }
49
-
50
- const invalid = name.match(/[^-\w]/g) || []
51
- return invalid.length > 0
52
- ? `Disallowed characters found: ${formatInvalid(name, invalid)}`
53
- : datasetNameError
54
- },
55
- ...options,
56
- })
57
- }
58
-
59
- function formatInvalid(name: string, invalid: string[]): string {
60
- return invalid.reduce(
61
- (acc, char) => acc.replace(new RegExp(escapeRegex(char), 'g'), chalk.red.bold(char)),
62
- name,
63
- )
64
- }
65
-
66
- function escapeRegex(str: string): string {
67
- return `${str}`.replace(/([?!${}*:()|=^[\]/\\.+])/g, '\\$1')
68
- }
@@ -1,51 +0,0 @@
1
- import {type CliOutputter, type CliPrompter} from '../../../types'
2
-
3
- export function promptForTypeScript(prompt: CliPrompter): Promise<boolean> {
4
- return prompt.single({
5
- type: 'confirm',
6
- message: 'Do you want to use TypeScript?',
7
- default: true,
8
- })
9
- }
10
-
11
- export function promptForDefaultConfig(prompt: CliPrompter): Promise<boolean> {
12
- return prompt.single({
13
- type: 'confirm',
14
- message: 'Use the default dataset configuration?',
15
- default: true,
16
- })
17
- }
18
-
19
- export function promptImplicitReconfigure(prompt: CliPrompter): Promise<boolean> {
20
- return prompt.single({
21
- type: 'confirm',
22
- message:
23
- 'The current folder contains a configured Sanity studio. Would you like to reconfigure it?',
24
- default: true,
25
- })
26
- }
27
-
28
- export async function promptForAclMode(prompt: CliPrompter, output: CliOutputter): Promise<string> {
29
- const mode = await prompt.single({
30
- type: 'list',
31
- message: 'Choose dataset visibility – this can be changed later',
32
- choices: [
33
- {
34
- value: 'public',
35
- name: 'Public (world readable)',
36
- },
37
- {
38
- value: 'private',
39
- name: 'Private (authenticated requests only)',
40
- },
41
- ],
42
- })
43
-
44
- if (mode === 'private') {
45
- output.print(
46
- 'Please note that while documents are private, assets (files and images) are still public\n',
47
- )
48
- }
49
-
50
- return mode
51
- }
@@ -1,59 +0,0 @@
1
- import {type CliPrompter} from '../../../types'
2
-
3
- export function promptForEmbeddedStudio(prompt: CliPrompter): Promise<string> {
4
- return prompt.single({
5
- type: 'confirm',
6
- message: `Would you like an embedded Sanity Studio?`,
7
- default: true,
8
- })
9
- }
10
-
11
- export function promptForStudioPath(prompt: CliPrompter): Promise<string> {
12
- return prompt.single({
13
- type: 'input',
14
- message: 'What route do you want to use for the Studio?',
15
- default: '/studio',
16
- validate(input) {
17
- if (!input.startsWith('/')) {
18
- return 'Must start with /'
19
- }
20
-
21
- if (input.endsWith('/')) {
22
- return 'Must not end with /'
23
- }
24
-
25
- // a-Z, 0-9, -, _ and /
26
- if (!/^[a-zA-Z0-9-_\\/]+$/.test(input)) {
27
- return 'Must only contain a-Z, 0-9, -, _ and /'
28
- }
29
-
30
- return true
31
- },
32
- })
33
- }
34
-
35
- export function promptForNextTemplate(prompt: CliPrompter): Promise<'clean' | 'blog'> {
36
- return prompt.single({
37
- message: 'Select project template to use',
38
- type: 'list',
39
- choices: [
40
- {
41
- value: 'blog',
42
- name: 'Blog (schema)',
43
- },
44
- {
45
- value: 'clean',
46
- name: 'Clean project with no predefined schema types',
47
- },
48
- ],
49
- default: 'blog',
50
- })
51
- }
52
-
53
- export function promptForAppendEnv(prompt: CliPrompter, envFilename: string): Promise<string> {
54
- return prompt.single({
55
- type: 'confirm',
56
- message: `Would you like to add the project ID and dataset to your ${envFilename} file?`,
57
- default: true,
58
- })
59
- }
@@ -1,17 +0,0 @@
1
- import fs from 'node:fs'
2
-
3
- import {type PackageJson} from '../../types'
4
-
5
- /**
6
- * Read the `package.json` file at the given path
7
- *
8
- * @param filePath - Path to package.json to read
9
- * @returns The parsed package.json
10
- */
11
- export function readPackageJson(filePath: string): PackageJson | undefined {
12
- try {
13
- return JSON.parse(fs.readFileSync(filePath, 'utf8'))
14
- } catch {
15
- return undefined
16
- }
17
- }
@@ -1,23 +0,0 @@
1
- import {type ProjectTemplate} from '../initProject'
2
-
3
- const appTemplate: ProjectTemplate = {
4
- dependencies: {
5
- '@sanity/sdk': '^2',
6
- '@sanity/sdk-react': '^2',
7
- 'react': '^19',
8
- 'react-dom': '^19',
9
- },
10
- devDependencies: {
11
- '@types/react': '^19',
12
- 'sanity': '^3',
13
- 'typescript': '^5.1.6',
14
- },
15
- entry: './src/App.tsx',
16
- scripts: {
17
- dev: 'sanity dev',
18
- build: 'sanity build',
19
- start: 'sanity start',
20
- },
21
- }
22
-
23
- export default appTemplate
@@ -1,25 +0,0 @@
1
- import {type ProjectTemplate} from '../initProject'
2
-
3
- const appSanityUiTemplate: ProjectTemplate = {
4
- dependencies: {
5
- '@sanity/sdk': '^2',
6
- '@sanity/sdk-react': '^2',
7
- '@sanity/ui': '^2',
8
- 'react': '^19',
9
- 'react-dom': '^19',
10
- 'styled-components': '^6.1.17',
11
- },
12
- devDependencies: {
13
- '@types/react': '^19',
14
- 'sanity': '^3',
15
- 'typescript': '^5.1.6',
16
- },
17
- entry: './src/App.tsx',
18
- scripts: {
19
- dev: 'sanity dev',
20
- build: 'sanity build',
21
- start: 'sanity start',
22
- },
23
- }
24
-
25
- export default appSanityUiTemplate
@@ -1,5 +0,0 @@
1
- import {type ProjectTemplate} from '../initProject'
2
-
3
- const blogTemplate: ProjectTemplate = {}
4
-
5
- export default blogTemplate
@@ -1,5 +0,0 @@
1
- import {type ProjectTemplate} from '../initProject'
2
-
3
- const cleanTemplate: ProjectTemplate = {}
4
-
5
- export default cleanTemplate
@@ -1,37 +0,0 @@
1
- import {type ProjectTemplate} from '../initProject'
2
-
3
- const configTemplate = `
4
- import {defineConfig, isDev} from 'sanity'
5
- import {visionTool} from '@sanity/vision'
6
- import {structureTool} from 'sanity/structure'
7
- import {schemaTypes} from './schemaTypes'
8
- import {getStartedPlugin} from './plugins/sanity-plugin-tutorial'
9
-
10
- const devOnlyPlugins = [getStartedPlugin()]
11
-
12
- export default defineConfig({
13
- name: '%sourceName%',
14
- title: '%projectName%',
15
-
16
- projectId: '%projectId%',
17
- dataset: '%dataset%',
18
-
19
- plugins: [structureTool(), visionTool(), ...(isDev ? devOnlyPlugins : [])],
20
-
21
- schema: {
22
- types: schemaTypes,
23
- },
24
- })
25
-
26
- `
27
-
28
- const getStartedTemplate: ProjectTemplate = {
29
- configTemplate,
30
- typescriptOnly: true,
31
- dependencies: {
32
- '@sanity/icons': '^2.11.0',
33
- '@sanity/ui': '^2.0.0',
34
- },
35
- }
36
-
37
- export default getStartedTemplate
@@ -1,24 +0,0 @@
1
- import {type ProjectTemplate} from '../initProject'
2
- import appTemplate from './appQuickstart'
3
- import appSanityUiTemplate from './appSanityUi'
4
- import blog from './blog'
5
- import clean from './clean'
6
- import getStartedTemplate from './getStarted'
7
- import moviedb from './moviedb'
8
- import quickstart from './quickstart'
9
- import shopify from './shopify'
10
- import shopifyOnline from './shopifyOnline'
11
-
12
- const templates: Record<string, ProjectTemplate | undefined> = {
13
- blog,
14
- clean,
15
- 'app-quickstart': appTemplate,
16
- 'app-sanity-ui': appSanityUiTemplate,
17
- 'get-started': getStartedTemplate,
18
- moviedb,
19
- shopify,
20
- 'shopify-online-storefront': shopifyOnline,
21
- quickstart, // empty project that dynamically imports its own schema
22
- }
23
-
24
- export default templates
@@ -1,35 +0,0 @@
1
- import {type ProjectTemplate} from '../initProject'
2
-
3
- const configTemplate = `
4
- import {defineConfig} from 'sanity'
5
- import {structureTool} from 'sanity/structure'
6
- import {visionTool} from '@sanity/vision'
7
- import {schemaTypes} from './schemaTypes'
8
-
9
- export default defineConfig({
10
- name: '%sourceName%',
11
- title: '%projectName%',
12
-
13
- projectId: '%projectId%',
14
- dataset: '%dataset%',
15
-
16
- plugins: [
17
- structureTool(),
18
- visionTool(),
19
- ],
20
-
21
- schema: {
22
- types: schemaTypes,
23
- },
24
- })
25
- `
26
-
27
- const movieTemplate: ProjectTemplate = {
28
- configTemplate,
29
- importPrompt: 'Add a sampling of sci-fi movies to your dataset on the hosted backend?',
30
- datasetUrl: 'https://public.sanity.io/moviesdb-2018-03-06.tar.gz',
31
- dependencies: {
32
- 'react-icons': '^3.11.0',
33
- },
34
- }
35
- export default movieTemplate
@@ -1,238 +0,0 @@
1
- import {blogSchemaFolder, blogSchemaJS, blogSchemaTS} from './schemaTypes/blog'
2
-
3
- export const sanityConfigTemplate = (hasSrcFolder = false): string => `'use client'
4
-
5
- /**
6
- * This configuration is used to for the Sanity Studio that’s mounted on the \`:route:\` route
7
- */
8
-
9
- import {visionTool} from '@sanity/vision'
10
- import {defineConfig} from 'sanity'
11
- import {structureTool} from 'sanity/structure'
12
-
13
- // Go to https://www.sanity.io/docs/api-versioning to learn how API versioning works
14
- import {apiVersion, dataset, projectId} from ${hasSrcFolder ? "'./src/sanity/env'" : "'./sanity/env'"}
15
- import {schema} from ${hasSrcFolder ? "'./src/sanity/schemaTypes'" : "'./sanity/schemaTypes'"}
16
- import {structure} from ${hasSrcFolder ? "'./src/sanity/structure'" : "'./sanity/structure'"}
17
-
18
- export default defineConfig({
19
- basePath: ':basePath:',
20
- projectId,
21
- dataset,
22
- // Add and edit the content schema in the './sanity/schemaTypes' folder
23
- schema,
24
- plugins: [
25
- structureTool({structure}),
26
- // Vision is for querying with GROQ from inside the Studio
27
- // https://www.sanity.io/docs/the-vision-plugin
28
- visionTool({defaultApiVersion: apiVersion}),
29
- ],
30
- })
31
- `
32
-
33
- export const sanityCliTemplate = `/**
34
- * This configuration file lets you run \`$ sanity [command]\` in this folder
35
- * Go to https://www.sanity.io/docs/cli to learn more.
36
- **/
37
- import { defineCliConfig } from 'sanity/cli'
38
-
39
- const projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID
40
- const dataset = process.env.NEXT_PUBLIC_SANITY_DATASET
41
-
42
- export default defineCliConfig({ api: { projectId, dataset } })
43
- `
44
-
45
- export const sanityStudioTemplate = `/**
46
- * This route is responsible for the built-in authoring environment using Sanity Studio.
47
- * All routes under your studio path is handled by this file using Next.js' catch-all routes:
48
- * https://nextjs.org/docs/routing/dynamic-routes#catch-all-routes
49
- *
50
- * You can learn more about the next-sanity package here:
51
- * https://github.com/sanity-io/next-sanity
52
- */
53
-
54
- import { NextStudio } from 'next-sanity/studio'
55
- import config from ':configPath:'
56
-
57
- export const dynamic = 'force-static'
58
-
59
- export { metadata, viewport } from 'next-sanity/studio'
60
-
61
- export default function StudioPage() {
62
- return <NextStudio config={config} />
63
- }
64
- `
65
-
66
- // Format today's date like YYYY-MM-DD
67
- const envTS = `export const apiVersion =
68
- process.env.NEXT_PUBLIC_SANITY_API_VERSION || '${new Date().toISOString().split('T')[0]}'
69
-
70
- export const dataset = assertValue(
71
- process.env.NEXT_PUBLIC_SANITY_DATASET,
72
- 'Missing environment variable: NEXT_PUBLIC_SANITY_DATASET'
73
- )
74
-
75
- export const projectId = assertValue(
76
- process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
77
- 'Missing environment variable: NEXT_PUBLIC_SANITY_PROJECT_ID'
78
- )
79
-
80
- function assertValue<T>(v: T | undefined, errorMessage: string): T {
81
- if (v === undefined) {
82
- throw new Error(errorMessage)
83
- }
84
-
85
- return v
86
- }
87
- `
88
-
89
- const envJS = `export const apiVersion =
90
- process.env.NEXT_PUBLIC_SANITY_API_VERSION || '${new Date().toISOString().split('T')[0]}'
91
-
92
- export const dataset = process.env.NEXT_PUBLIC_SANITY_DATASET;
93
- export const projectId = process.env.NEXT_PUBLIC_SANITY_PROJECT_ID;
94
- `
95
-
96
- const schemaTS = `import { type SchemaTypeDefinition } from 'sanity'
97
-
98
- export const schema: { types: SchemaTypeDefinition[] } = {
99
- types: [],
100
- }
101
- `
102
-
103
- const schemaJS = `export const schema = {
104
- types: [],
105
- }
106
- `
107
-
108
- const blogStructureTS = `import type {StructureResolver} from 'sanity/structure'
109
-
110
- // https://www.sanity.io/docs/structure-builder-cheat-sheet
111
- export const structure: StructureResolver = (S) =>
112
- S.list()
113
- .title('Blog')
114
- .items([
115
- S.documentTypeListItem('post').title('Posts'),
116
- S.documentTypeListItem('category').title('Categories'),
117
- S.documentTypeListItem('author').title('Authors'),
118
- S.divider(),
119
- ...S.documentTypeListItems().filter(
120
- (item) => item.getId() && !['post', 'category', 'author'].includes(item.getId()!),
121
- ),
122
- ])
123
- `
124
-
125
- const blogStructureJS = `// https://www.sanity.io/docs/structure-builder-cheat-sheet
126
- export const structure = (S) =>
127
- S.list()
128
- .title('Blog')
129
- .items([
130
- S.documentTypeListItem('post').title('Posts'),
131
- S.documentTypeListItem('category').title('Categories'),
132
- S.documentTypeListItem('author').title('Authors'),
133
- S.divider(),
134
- ...S.documentTypeListItems().filter(
135
- (item) => item.getId() && !['post', 'category', 'author'].includes(item.getId()),
136
- ),
137
- ])
138
- `
139
-
140
- const structureTS = `import type {StructureResolver} from 'sanity/structure'
141
-
142
- // https://www.sanity.io/docs/structure-builder-cheat-sheet
143
- export const structure: StructureResolver = (S) =>
144
- S.list()
145
- .title('Content')
146
- .items(S.documentTypeListItems())
147
- `
148
-
149
- const structureJS = `// https://www.sanity.io/docs/structure-builder-cheat-sheet
150
- export const structure = (S) =>
151
- S.list()
152
- .title('Content')
153
- .items(S.documentTypeListItems())
154
- `
155
-
156
- const client = `import { createClient } from 'next-sanity'
157
-
158
- import { apiVersion, dataset, projectId } from '../env'
159
-
160
- export const client = createClient({
161
- projectId,
162
- dataset,
163
- apiVersion,
164
- useCdn: true, // Set to false if statically generating pages, using ISR or tag-based revalidation
165
- })
166
- `
167
-
168
- const live = `// Querying with "sanityFetch" will keep content automatically updated
169
- // Before using it, import and render "<SanityLive />" in your layout, see
170
- // https://github.com/sanity-io/next-sanity#live-content-api for more information.
171
- import { defineLive } from "next-sanity";
172
- import { client } from './client'
173
-
174
- export const { sanityFetch, SanityLive } = defineLive({
175
- client: client.withConfig({
176
- // Live content is currently only available on the experimental API
177
- // https://www.sanity.io/docs/api-versioning
178
- apiVersion: 'vX'
179
- })
180
- });
181
- `
182
-
183
- const imageTS = `import createImageUrlBuilder from '@sanity/image-url'
184
- import { SanityImageSource } from "@sanity/image-url/lib/types/types";
185
-
186
- import { dataset, projectId } from '../env'
187
-
188
- // https://www.sanity.io/docs/image-url
189
- const builder = createImageUrlBuilder({ projectId, dataset })
190
-
191
- export const urlFor = (source: SanityImageSource) => {
192
- return builder.image(source)
193
- }
194
- `
195
-
196
- const imageJS = `import createImageUrlBuilder from '@sanity/image-url'
197
-
198
- import { dataset, projectId } from '../env'
199
-
200
- // https://www.sanity.io/docs/image-url
201
- const builder = createImageUrlBuilder({ projectId, dataset })
202
-
203
- export const urlFor = (source) => {
204
- return builder.image(source)
205
- }
206
- `
207
-
208
- type FolderStructure = Record<string, string | Record<string, string>>
209
-
210
- export const sanityFolder = (
211
- useTypeScript: boolean,
212
- template?: 'clean' | 'blog',
213
- ): FolderStructure => {
214
- // Files used in both templates
215
- const structure: FolderStructure = {
216
- 'env.': useTypeScript ? envTS : envJS,
217
- 'lib': {
218
- 'client.': client,
219
- 'live.': live,
220
- 'image.': useTypeScript ? imageTS : imageJS,
221
- },
222
- }
223
-
224
- if (template === 'blog') {
225
- structure.schemaTypes = {
226
- ...blogSchemaFolder,
227
- 'index.': useTypeScript ? blogSchemaTS : blogSchemaJS,
228
- }
229
- structure['structure.'] = useTypeScript ? blogStructureTS : blogStructureJS
230
- } else {
231
- structure.schemaTypes = {
232
- 'index.': useTypeScript ? schemaTS : schemaJS,
233
- }
234
- structure['structure.'] = useTypeScript ? structureTS : structureJS
235
- }
236
-
237
- return structure
238
- }