@sanity/cli 6.3.1 → 6.4.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 (193) hide show
  1. package/README.md +311 -452
  2. package/dist/actions/build/decorateIndexWithStagingScript.js +16 -0
  3. package/dist/actions/build/decorateIndexWithStagingScript.js.map +1 -0
  4. package/dist/actions/build/writeSanityRuntime.js +3 -2
  5. package/dist/actions/build/writeSanityRuntime.js.map +1 -1
  6. package/dist/actions/dataset/create.js +4 -0
  7. package/dist/actions/dataset/create.js.map +1 -1
  8. package/dist/actions/deploy/findUserApplicationForApp.js +1 -0
  9. package/dist/actions/deploy/findUserApplicationForApp.js.map +1 -1
  10. package/dist/actions/deploy/types.js +1 -1
  11. package/dist/actions/deploy/types.js.map +1 -1
  12. package/dist/actions/init/bootstrapLocalTemplate.js +16 -1
  13. package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
  14. package/dist/actions/init/initApp.js +72 -0
  15. package/dist/actions/init/initApp.js.map +1 -0
  16. package/dist/actions/init/initHelpers.js +37 -0
  17. package/dist/actions/init/initHelpers.js.map +1 -0
  18. package/dist/actions/init/initNextJs.js +246 -0
  19. package/dist/actions/init/initNextJs.js.map +1 -0
  20. package/dist/actions/init/initStudio.js +127 -0
  21. package/dist/actions/init/initStudio.js.map +1 -0
  22. package/dist/actions/init/scaffoldTemplate.js +114 -0
  23. package/dist/actions/init/scaffoldTemplate.js.map +1 -0
  24. package/dist/actions/init/templates/appQuickstart.js +2 -1
  25. package/dist/actions/init/templates/appQuickstart.js.map +1 -1
  26. package/dist/actions/init/templates/appSanityUi.js +2 -1
  27. package/dist/actions/init/templates/appSanityUi.js.map +1 -1
  28. package/dist/actions/init/templates/nextjs/index.js +1 -2
  29. package/dist/actions/init/templates/nextjs/index.js.map +1 -1
  30. package/dist/actions/init/templates/shopify.js +6 -6
  31. package/dist/actions/init/templates/shopify.js.map +1 -1
  32. package/dist/actions/init/templates/shopifyOnline.js +2 -2
  33. package/dist/actions/init/templates/shopifyOnline.js.map +1 -1
  34. package/dist/actions/manifest/types.js +1 -1
  35. package/dist/actions/manifest/types.js.map +1 -1
  36. package/dist/actions/mcp/detectAvailableEditors.js +16 -3
  37. package/dist/actions/mcp/detectAvailableEditors.js.map +1 -1
  38. package/dist/actions/mcp/editorConfigs.js +192 -132
  39. package/dist/actions/mcp/editorConfigs.js.map +1 -1
  40. package/dist/actions/mcp/setupMCP.js +4 -1
  41. package/dist/actions/mcp/setupMCP.js.map +1 -1
  42. package/dist/actions/mcp/writeMCPConfig.js +2 -2
  43. package/dist/actions/mcp/writeMCPConfig.js.map +1 -1
  44. package/dist/actions/schema/extractSchema.js +5 -7
  45. package/dist/actions/schema/extractSchema.js.map +1 -1
  46. package/dist/actions/schema/types.js +3 -3
  47. package/dist/actions/schema/types.js.map +1 -1
  48. package/dist/actions/users/validateEmail.js +2 -2
  49. package/dist/actions/users/validateEmail.js.map +1 -1
  50. package/dist/commands/backups/disable.js +1 -1
  51. package/dist/commands/backups/disable.js.map +1 -1
  52. package/dist/commands/backups/download.js +1 -1
  53. package/dist/commands/backups/download.js.map +1 -1
  54. package/dist/commands/backups/enable.js +1 -1
  55. package/dist/commands/backups/enable.js.map +1 -1
  56. package/dist/commands/backups/list.js +1 -1
  57. package/dist/commands/backups/list.js.map +1 -1
  58. package/dist/commands/build.js +1 -1
  59. package/dist/commands/build.js.map +1 -1
  60. package/dist/commands/cors/add.js +1 -1
  61. package/dist/commands/cors/add.js.map +1 -1
  62. package/dist/commands/cors/delete.js +1 -1
  63. package/dist/commands/cors/delete.js.map +1 -1
  64. package/dist/commands/cors/list.js +2 -2
  65. package/dist/commands/cors/list.js.map +1 -1
  66. package/dist/commands/datasets/alias/create.js +1 -1
  67. package/dist/commands/datasets/alias/create.js.map +1 -1
  68. package/dist/commands/datasets/alias/delete.js +1 -1
  69. package/dist/commands/datasets/alias/delete.js.map +1 -1
  70. package/dist/commands/datasets/alias/link.js +1 -1
  71. package/dist/commands/datasets/alias/link.js.map +1 -1
  72. package/dist/commands/datasets/alias/unlink.js +1 -1
  73. package/dist/commands/datasets/alias/unlink.js.map +1 -1
  74. package/dist/commands/datasets/copy.js +15 -1
  75. package/dist/commands/datasets/copy.js.map +1 -1
  76. package/dist/commands/datasets/create.js +1 -1
  77. package/dist/commands/datasets/create.js.map +1 -1
  78. package/dist/commands/datasets/delete.js +1 -1
  79. package/dist/commands/datasets/delete.js.map +1 -1
  80. package/dist/commands/datasets/embeddings/enable.js +11 -0
  81. package/dist/commands/datasets/embeddings/enable.js.map +1 -1
  82. package/dist/commands/datasets/export.js +2 -2
  83. package/dist/commands/datasets/export.js.map +1 -1
  84. package/dist/commands/datasets/list.js +2 -2
  85. package/dist/commands/datasets/list.js.map +1 -1
  86. package/dist/commands/debug.js +1 -1
  87. package/dist/commands/debug.js.map +1 -1
  88. package/dist/commands/deploy.js +3 -3
  89. package/dist/commands/deploy.js.map +1 -1
  90. package/dist/commands/dev.js +5 -5
  91. package/dist/commands/dev.js.map +1 -1
  92. package/dist/commands/docs/browse.js +1 -1
  93. package/dist/commands/docs/browse.js.map +1 -1
  94. package/dist/commands/documents/delete.js +1 -1
  95. package/dist/commands/documents/delete.js.map +1 -1
  96. package/dist/commands/exec.js +2 -2
  97. package/dist/commands/exec.js.map +1 -1
  98. package/dist/commands/graphql/deploy.js +2 -2
  99. package/dist/commands/graphql/deploy.js.map +1 -1
  100. package/dist/commands/graphql/list.js +2 -2
  101. package/dist/commands/graphql/list.js.map +1 -1
  102. package/dist/commands/hooks/create.js +2 -2
  103. package/dist/commands/hooks/create.js.map +1 -1
  104. package/dist/commands/hooks/delete.js +5 -5
  105. package/dist/commands/hooks/delete.js.map +1 -1
  106. package/dist/commands/hooks/list.js +3 -3
  107. package/dist/commands/hooks/list.js.map +1 -1
  108. package/dist/commands/hooks/logs.js +5 -5
  109. package/dist/commands/hooks/logs.js.map +1 -1
  110. package/dist/commands/init.js +175 -490
  111. package/dist/commands/init.js.map +1 -1
  112. package/dist/commands/install.js +1 -1
  113. package/dist/commands/install.js.map +1 -1
  114. package/dist/commands/learn.js +1 -1
  115. package/dist/commands/learn.js.map +1 -1
  116. package/dist/commands/login.js +1 -1
  117. package/dist/commands/login.js.map +1 -1
  118. package/dist/commands/logout.js +1 -1
  119. package/dist/commands/logout.js.map +1 -1
  120. package/dist/commands/manage.js +1 -1
  121. package/dist/commands/manage.js.map +1 -1
  122. package/dist/commands/manifest/extract.js +2 -2
  123. package/dist/commands/manifest/extract.js.map +1 -1
  124. package/dist/commands/mcp/configure.js +1 -1
  125. package/dist/commands/mcp/configure.js.map +1 -1
  126. package/dist/commands/media/delete-aspect.js +1 -1
  127. package/dist/commands/media/delete-aspect.js.map +1 -1
  128. package/dist/commands/media/export.js +1 -1
  129. package/dist/commands/media/export.js.map +1 -1
  130. package/dist/commands/preview.js +3 -3
  131. package/dist/commands/preview.js.map +1 -1
  132. package/dist/commands/projects/list.js +4 -2
  133. package/dist/commands/projects/list.js.map +1 -1
  134. package/dist/commands/schemas/deploy.js +3 -4
  135. package/dist/commands/schemas/deploy.js.map +1 -1
  136. package/dist/commands/schemas/extract.js +3 -3
  137. package/dist/commands/schemas/extract.js.map +1 -1
  138. package/dist/commands/schemas/list.js +4 -5
  139. package/dist/commands/schemas/list.js.map +1 -1
  140. package/dist/commands/telemetry/disable.js +2 -2
  141. package/dist/commands/telemetry/disable.js.map +1 -1
  142. package/dist/commands/telemetry/enable.js +2 -2
  143. package/dist/commands/telemetry/enable.js.map +1 -1
  144. package/dist/commands/telemetry/status.js +2 -2
  145. package/dist/commands/telemetry/status.js.map +1 -1
  146. package/dist/commands/tokens/add.js +1 -1
  147. package/dist/commands/tokens/add.js.map +1 -1
  148. package/dist/commands/tokens/delete.js +1 -1
  149. package/dist/commands/tokens/delete.js.map +1 -1
  150. package/dist/commands/tokens/list.js +2 -2
  151. package/dist/commands/tokens/list.js.map +1 -1
  152. package/dist/commands/users/list.js +1 -1
  153. package/dist/commands/users/list.js.map +1 -1
  154. package/dist/commands/versions.js +1 -1
  155. package/dist/commands/versions.js.map +1 -1
  156. package/dist/hooks/prerun/injectEnvVariables.js +3 -5
  157. package/dist/hooks/prerun/injectEnvVariables.js.map +1 -1
  158. package/dist/server/vite/plugin-sanity-build-entries.js +3 -2
  159. package/dist/server/vite/plugin-sanity-build-entries.js.map +1 -1
  160. package/dist/services/datasets.js +2 -1
  161. package/dist/services/datasets.js.map +1 -1
  162. package/dist/telemetry/init.telemetry.js.map +1 -1
  163. package/dist/util/packageManager/installationInfo/detectPackages.js +13 -7
  164. package/dist/util/packageManager/installationInfo/detectPackages.js.map +1 -1
  165. package/dist/util/telemetry/createTelemetryStore.js +27 -12
  166. package/dist/util/telemetry/createTelemetryStore.js.map +1 -1
  167. package/dist/util/update/fetchUpdateInfo.js +40 -0
  168. package/dist/util/update/fetchUpdateInfo.js.map +1 -0
  169. package/dist/util/update/fetchUpdateInfo.worker.js +19 -0
  170. package/dist/util/update/fetchUpdateInfo.worker.js.map +1 -0
  171. package/dist/util/update/getRunnerUpdateCommand.js +33 -0
  172. package/dist/util/update/getRunnerUpdateCommand.js.map +1 -0
  173. package/dist/util/update/getUpdateCommand.js +6 -7
  174. package/dist/util/update/getUpdateCommand.js.map +1 -1
  175. package/dist/util/update/packageRunner.js +10 -0
  176. package/dist/util/update/packageRunner.js.map +1 -0
  177. package/dist/util/update/resolveRunnerPackage.js +45 -0
  178. package/dist/util/update/resolveRunnerPackage.js.map +1 -0
  179. package/dist/util/update/resolveUpdateTarget.js +31 -0
  180. package/dist/util/update/resolveUpdateTarget.js.map +1 -0
  181. package/dist/util/update/showNotificationUpdate.js +8 -6
  182. package/dist/util/update/showNotificationUpdate.js.map +1 -1
  183. package/dist/util/update/updateChecker.js +73 -38
  184. package/dist/util/update/updateChecker.js.map +1 -1
  185. package/dist/util/validateProjection.js +121 -0
  186. package/dist/util/validateProjection.js.map +1 -0
  187. package/oclif.manifest.json +698 -681
  188. package/package.json +24 -23
  189. package/templates/app-quickstart/src/App.tsx +2 -2
  190. package/templates/app-sanity-ui/src/App.tsx +2 -2
  191. package/templates/shopify/schemaTypes/objects/hotspot/imageWithProductHotspotsType.ts +1 -1
  192. package/dist/util/update/fetchLatestVersion.js +0 -21
  193. package/dist/util/update/fetchLatestVersion.js.map +0 -1
@@ -0,0 +1,246 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { mkdir, writeFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { styleText } from 'node:util';
5
+ import { subdebug } from '@sanity/cli-core';
6
+ import { confirm } from '@sanity/cli-core/ux';
7
+ import { execa } from 'execa';
8
+ import { promptForAppendEnv, promptForEmbeddedStudio, promptForNextTemplate, promptForStudioPath } from '../../prompts/init/nextjs.js';
9
+ import { promptForTypeScript } from '../../prompts/init/promptForTypescript.js';
10
+ import { createCorsOrigin, listCorsOrigins } from '../../services/cors.js';
11
+ import { getPeerDependencies } from '../../util/packageManager/getPeerDependencies.js';
12
+ import { installNewPackages } from '../../util/packageManager/installPackages.js';
13
+ import { getPartialEnvWithNpmPath } from '../../util/packageManager/packageManagerChoice.js';
14
+ import { countNestedFolders } from './countNestedFolders.js';
15
+ import { createOrAppendEnvVars } from './env/createOrAppendEnvVars.js';
16
+ import { flagOrDefault, getPostInitMCPPrompt, shouldPrompt, writeStagingEnvIfNeeded } from './initHelpers.js';
17
+ import { resolvePackageManager } from './resolvePackageManager.js';
18
+ import { sanityCliTemplate, sanityConfigTemplate, sanityFolder, sanityStudioTemplate } from './templates/nextjs/index.js';
19
+ const debug = subdebug('init');
20
+ async function writeOrOverwrite(filePath, content, workDir, params) {
21
+ if (existsSync(filePath)) {
22
+ let overwrite = flagOrDefault(params.overwriteFiles, false);
23
+ if (shouldPrompt(params.unattended, params.overwriteFiles)) {
24
+ overwrite = await confirm({
25
+ default: false,
26
+ message: `File ${styleText('yellow', filePath.replace(workDir, ''))} already exists. Do you want to overwrite it?`
27
+ });
28
+ }
29
+ if (!overwrite) {
30
+ return;
31
+ }
32
+ }
33
+ // make folder if not exists
34
+ const folderPath = path.dirname(filePath);
35
+ try {
36
+ await mkdir(folderPath, {
37
+ recursive: true
38
+ });
39
+ } catch {
40
+ debug('Error creating folder %s', folderPath);
41
+ }
42
+ await writeFile(filePath, content, {
43
+ encoding: 'utf8'
44
+ });
45
+ }
46
+ // write sanity folder files
47
+ async function writeSourceFiles({ fileExtension, files, folderPath, params, srcFolderPrefix, workDir }) {
48
+ for (const [filePath, content] of Object.entries(files)){
49
+ // check if file ends with full stop to indicate it's file and not directory (this only works with our template tree structure)
50
+ if (filePath.includes('.') && typeof content === 'string') {
51
+ await writeOrOverwrite(path.join(workDir, srcFolderPrefix ? 'src' : '', 'sanity', folderPath || '', `${filePath}${fileExtension}`), content, workDir, params);
52
+ } else {
53
+ await mkdir(path.join(workDir, srcFolderPrefix ? 'src' : '', 'sanity', filePath), {
54
+ recursive: true
55
+ });
56
+ if (typeof content === 'object') {
57
+ await writeSourceFiles({
58
+ fileExtension,
59
+ files: content,
60
+ folderPath: filePath,
61
+ params,
62
+ srcFolderPrefix,
63
+ workDir
64
+ });
65
+ }
66
+ }
67
+ }
68
+ }
69
+ export async function initNextJs({ datasetName, detectedFramework, envFilename, mcpConfigured, nextjsAppendEnv, nextjsEmbedStudio, output, overwriteFiles, packageManager, projectId, template, trace, typescript, unattended, workDir }) {
70
+ let useTypeScript = flagOrDefault(typescript, true);
71
+ if (shouldPrompt(unattended, typescript)) {
72
+ useTypeScript = await promptForTypeScript();
73
+ }
74
+ trace.log({
75
+ selectedOption: useTypeScript ? 'yes' : 'no',
76
+ step: 'useTypeScript'
77
+ });
78
+ const fileExtension = useTypeScript ? 'ts' : 'js';
79
+ let embeddedStudio = flagOrDefault(nextjsEmbedStudio, true);
80
+ if (shouldPrompt(unattended, nextjsEmbedStudio)) {
81
+ embeddedStudio = await promptForEmbeddedStudio();
82
+ }
83
+ let hasSrcFolder = false;
84
+ const writeParams = {
85
+ overwriteFiles,
86
+ unattended
87
+ };
88
+ if (embeddedStudio) {
89
+ // find source path (app or src/app)
90
+ const appDir = 'app';
91
+ let srcPath = path.join(workDir, appDir);
92
+ if (!existsSync(srcPath)) {
93
+ srcPath = path.join(workDir, 'src', appDir);
94
+ hasSrcFolder = true;
95
+ if (!existsSync(srcPath)) {
96
+ try {
97
+ await mkdir(srcPath, {
98
+ recursive: true
99
+ });
100
+ } catch {
101
+ debug('Error creating folder %s', srcPath);
102
+ }
103
+ }
104
+ }
105
+ const studioPath = unattended ? '/studio' : await promptForStudioPath();
106
+ const embeddedStudioRouteFilePath = path.join(srcPath, `${studioPath}/`, `[[...tool]]/page.${fileExtension}x`);
107
+ // this selects the correct template string based on whether the user is using the app or pages directory and
108
+ // replaces the ":configPath:" placeholder in the template with the correct path to the sanity.config.ts file.
109
+ // we account for the user-defined embeddedStudioPath (default /studio) is accounted for by creating enough "../"
110
+ // relative paths to reach the root level of the project
111
+ await writeOrOverwrite(embeddedStudioRouteFilePath, sanityStudioTemplate.replace(':configPath:', `${'../'.repeat(countNestedFolders(path.dirname(embeddedStudioRouteFilePath.slice(workDir.length))))}sanity.config`), workDir, writeParams);
112
+ const sanityConfigPath = path.join(workDir, `sanity.config.${fileExtension}`);
113
+ await writeOrOverwrite(sanityConfigPath, sanityConfigTemplate(hasSrcFolder).replace(':route:', embeddedStudioRouteFilePath.slice(workDir.length).replace('src/', '')).replace(':basePath:', studioPath), workDir, writeParams);
114
+ }
115
+ const sanityCliPath = path.join(workDir, `sanity.cli.${fileExtension}`);
116
+ await writeOrOverwrite(sanityCliPath, sanityCliTemplate, workDir, writeParams);
117
+ let templateToUse = template ?? 'clean';
118
+ if (shouldPrompt(unattended, template)) {
119
+ templateToUse = await promptForNextTemplate();
120
+ }
121
+ await writeSourceFiles({
122
+ fileExtension,
123
+ files: sanityFolder(useTypeScript, templateToUse),
124
+ folderPath: undefined,
125
+ params: writeParams,
126
+ srcFolderPrefix: hasSrcFolder,
127
+ workDir
128
+ });
129
+ let appendEnv = flagOrDefault(nextjsAppendEnv, true);
130
+ if (shouldPrompt(unattended, nextjsAppendEnv)) {
131
+ appendEnv = await promptForAppendEnv(envFilename);
132
+ }
133
+ if (appendEnv) {
134
+ await createOrAppendEnvVars({
135
+ envVars: {
136
+ DATASET: datasetName,
137
+ PROJECT_ID: projectId
138
+ },
139
+ filename: envFilename,
140
+ framework: detectedFramework,
141
+ log: true,
142
+ output,
143
+ outputPath: workDir
144
+ });
145
+ }
146
+ if (embeddedStudio) {
147
+ const nextjsLocalDevOrigin = 'http://localhost:3000';
148
+ const existingCorsOrigins = await listCorsOrigins(projectId);
149
+ const hasExistingCorsOrigin = existingCorsOrigins.some((item)=>item.origin === nextjsLocalDevOrigin);
150
+ if (!hasExistingCorsOrigin) {
151
+ try {
152
+ const createCorsRes = await createCorsOrigin({
153
+ allowCredentials: true,
154
+ origin: nextjsLocalDevOrigin,
155
+ projectId
156
+ });
157
+ output.log(createCorsRes.id ? `Added ${nextjsLocalDevOrigin} to CORS origins` : `Failed to add ${nextjsLocalDevOrigin} to CORS origins`);
158
+ } catch (corsError) {
159
+ debug(`Error creating new CORS Origin ${nextjsLocalDevOrigin}: ${corsError}`);
160
+ output.error(`Failed to add ${nextjsLocalDevOrigin} to CORS origins: ${corsError}`, {
161
+ exit: 1
162
+ });
163
+ }
164
+ }
165
+ }
166
+ const chosen = await resolvePackageManager({
167
+ interactive: !unattended,
168
+ output,
169
+ packageManager: packageManager,
170
+ targetDir: workDir
171
+ });
172
+ trace.log({
173
+ selectedOption: chosen,
174
+ step: 'selectPackageManager'
175
+ });
176
+ const packages = [
177
+ '@sanity/vision@5',
178
+ 'sanity@5',
179
+ '@sanity/image-url@2',
180
+ 'styled-components@6'
181
+ ];
182
+ if (templateToUse === 'blog') {
183
+ packages.push('@sanity/icons');
184
+ }
185
+ await installNewPackages({
186
+ packageManager: chosen,
187
+ packages
188
+ }, {
189
+ output,
190
+ workDir
191
+ });
192
+ // will refactor this later
193
+ const execOptions = {
194
+ cwd: workDir,
195
+ encoding: 'utf8',
196
+ env: getPartialEnvWithNpmPath(workDir),
197
+ stdio: 'inherit'
198
+ };
199
+ switch(chosen){
200
+ case 'npm':
201
+ {
202
+ await execa('npm', [
203
+ 'install',
204
+ 'next-sanity@12'
205
+ ], execOptions);
206
+ break;
207
+ }
208
+ case 'pnpm':
209
+ {
210
+ await execa('pnpm', [
211
+ 'install',
212
+ 'next-sanity@12'
213
+ ], execOptions);
214
+ break;
215
+ }
216
+ case 'yarn':
217
+ {
218
+ const peerDeps = await getPeerDependencies('next-sanity@12', workDir);
219
+ await installNewPackages({
220
+ packageManager: 'yarn',
221
+ packages: [
222
+ 'next-sanity@12',
223
+ ...peerDeps
224
+ ]
225
+ }, {
226
+ output,
227
+ workDir
228
+ });
229
+ break;
230
+ }
231
+ default:
232
+ {
233
+ break;
234
+ }
235
+ }
236
+ output.log(`\n${styleText('green', 'Success!')} Your Sanity configuration files has been added to this project`);
237
+ if (mcpConfigured && mcpConfigured.length > 0) {
238
+ const message = await getPostInitMCPPrompt(mcpConfigured);
239
+ output.log(`\n${message}`);
240
+ output.log(`\nLearn more: ${styleText('cyan', 'https://mcp.sanity.io')}`);
241
+ output.log(`\nHave feedback? Tell us in the community: ${styleText('cyan', 'https://www.sanity.io/community/join')}`);
242
+ }
243
+ await writeStagingEnvIfNeeded(output, workDir);
244
+ }
245
+
246
+ //# sourceMappingURL=initNextJs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/init/initNextJs.ts"],"sourcesContent":["import {existsSync} from 'node:fs'\nimport {mkdir, writeFile} from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {type Output, subdebug, type TelemetryUserProperties} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {type TelemetryTrace} from '@sanity/telemetry'\nimport {execa, type Options} from 'execa'\n\nimport {\n promptForAppendEnv,\n promptForEmbeddedStudio,\n promptForNextTemplate,\n promptForStudioPath,\n} from '../../prompts/init/nextjs.js'\nimport {promptForTypeScript} from '../../prompts/init/promptForTypescript.js'\nimport {createCorsOrigin, listCorsOrigins} from '../../services/cors.js'\nimport {type InitStepResult} from '../../telemetry/init.telemetry.js'\nimport {getPeerDependencies} from '../../util/packageManager/getPeerDependencies.js'\nimport {installNewPackages} from '../../util/packageManager/installPackages.js'\nimport {\n getPartialEnvWithNpmPath,\n type PackageManager,\n} from '../../util/packageManager/packageManagerChoice.js'\nimport {type EditorName} from '../mcp/editorConfigs.js'\nimport {countNestedFolders} from './countNestedFolders.js'\nimport {createOrAppendEnvVars} from './env/createOrAppendEnvVars.js'\nimport {\n flagOrDefault,\n getPostInitMCPPrompt,\n shouldPrompt,\n writeStagingEnvIfNeeded,\n} from './initHelpers.js'\nimport {resolvePackageManager} from './resolvePackageManager.js'\nimport {\n sanityCliTemplate,\n sanityConfigTemplate,\n sanityFolder,\n sanityStudioTemplate,\n} from './templates/nextjs/index.js'\nimport {type VersionedFramework} from './types.js'\n\nconst debug = subdebug('init')\n\nasync function writeOrOverwrite(\n filePath: string,\n content: string,\n workDir: string,\n params: {overwriteFiles?: boolean; unattended: boolean},\n) {\n if (existsSync(filePath)) {\n let overwrite = flagOrDefault(params.overwriteFiles, false)\n if (shouldPrompt(params.unattended, params.overwriteFiles)) {\n overwrite = await confirm({\n default: false,\n message: `File ${styleText(\n 'yellow',\n filePath.replace(workDir, ''),\n )} already exists. Do you want to overwrite it?`,\n })\n }\n\n if (!overwrite) {\n return\n }\n }\n\n // make folder if not exists\n const folderPath = path.dirname(filePath)\n\n try {\n await mkdir(folderPath, {recursive: true})\n } catch {\n debug('Error creating folder %s', folderPath)\n }\n\n await writeFile(filePath, content, {\n encoding: 'utf8',\n })\n}\n\n// write sanity folder files\nasync function writeSourceFiles({\n fileExtension,\n files,\n folderPath,\n params,\n srcFolderPrefix,\n workDir,\n}: {\n fileExtension: string\n files: Record<string, Record<string, string> | string>\n folderPath?: string\n params: {overwriteFiles?: boolean; unattended: boolean}\n srcFolderPrefix?: boolean\n workDir: string\n}) {\n for (const [filePath, content] of Object.entries(files)) {\n // check if file ends with full stop to indicate it's file and not directory (this only works with our template tree structure)\n if (filePath.includes('.') && typeof content === 'string') {\n await writeOrOverwrite(\n path.join(\n workDir,\n srcFolderPrefix ? 'src' : '',\n 'sanity',\n folderPath || '',\n `${filePath}${fileExtension}`,\n ),\n content,\n workDir,\n params,\n )\n } else {\n await mkdir(path.join(workDir, srcFolderPrefix ? 'src' : '', 'sanity', filePath), {\n recursive: true,\n })\n if (typeof content === 'object') {\n await writeSourceFiles({\n fileExtension,\n files: content,\n folderPath: filePath,\n params,\n srcFolderPrefix,\n workDir,\n })\n }\n }\n }\n}\n\nexport async function initNextJs({\n datasetName,\n detectedFramework,\n envFilename,\n mcpConfigured,\n nextjsAppendEnv,\n nextjsEmbedStudio,\n output,\n overwriteFiles,\n packageManager,\n projectId,\n template,\n trace,\n typescript,\n unattended,\n workDir,\n}: {\n datasetName: string\n detectedFramework: VersionedFramework | null\n envFilename: string\n mcpConfigured: EditorName[]\n nextjsAppendEnv?: boolean\n nextjsEmbedStudio?: boolean\n output: Output\n overwriteFiles?: boolean\n packageManager?: string\n projectId: string\n template?: string\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>\n typescript?: boolean\n unattended: boolean\n workDir: string\n}): Promise<void> {\n let useTypeScript = flagOrDefault(typescript, true)\n if (shouldPrompt(unattended, typescript)) {\n useTypeScript = await promptForTypeScript()\n }\n trace.log({\n selectedOption: useTypeScript ? 'yes' : 'no',\n step: 'useTypeScript',\n })\n\n const fileExtension = useTypeScript ? 'ts' : 'js'\n let embeddedStudio = flagOrDefault(nextjsEmbedStudio, true)\n if (shouldPrompt(unattended, nextjsEmbedStudio)) {\n embeddedStudio = await promptForEmbeddedStudio()\n }\n let hasSrcFolder = false\n\n const writeParams = {overwriteFiles, unattended}\n\n if (embeddedStudio) {\n // find source path (app or src/app)\n const appDir = 'app'\n let srcPath = path.join(workDir, appDir)\n\n if (!existsSync(srcPath)) {\n srcPath = path.join(workDir, 'src', appDir)\n hasSrcFolder = true\n if (!existsSync(srcPath)) {\n try {\n await mkdir(srcPath, {recursive: true})\n } catch {\n debug('Error creating folder %s', srcPath)\n }\n }\n }\n\n const studioPath = unattended ? '/studio' : await promptForStudioPath()\n\n const embeddedStudioRouteFilePath = path.join(\n srcPath,\n `${studioPath}/`,\n `[[...tool]]/page.${fileExtension}x`,\n )\n\n // this selects the correct template string based on whether the user is using the app or pages directory and\n // replaces the \":configPath:\" placeholder in the template with the correct path to the sanity.config.ts file.\n // we account for the user-defined embeddedStudioPath (default /studio) is accounted for by creating enough \"../\"\n // relative paths to reach the root level of the project\n await writeOrOverwrite(\n embeddedStudioRouteFilePath,\n sanityStudioTemplate.replace(\n ':configPath:',\n `${'../'.repeat(countNestedFolders(path.dirname(embeddedStudioRouteFilePath.slice(workDir.length))))}sanity.config`,\n ),\n workDir,\n writeParams,\n )\n\n const sanityConfigPath = path.join(workDir, `sanity.config.${fileExtension}`)\n await writeOrOverwrite(\n sanityConfigPath,\n sanityConfigTemplate(hasSrcFolder)\n .replace(':route:', embeddedStudioRouteFilePath.slice(workDir.length).replace('src/', ''))\n .replace(':basePath:', studioPath),\n workDir,\n writeParams,\n )\n }\n\n const sanityCliPath = path.join(workDir, `sanity.cli.${fileExtension}`)\n await writeOrOverwrite(sanityCliPath, sanityCliTemplate, workDir, writeParams)\n\n let templateToUse = template ?? 'clean'\n if (shouldPrompt(unattended, template)) {\n templateToUse = await promptForNextTemplate()\n }\n\n await writeSourceFiles({\n fileExtension,\n files: sanityFolder(useTypeScript, templateToUse as 'blog' | 'clean'),\n folderPath: undefined,\n params: writeParams,\n srcFolderPrefix: hasSrcFolder,\n workDir,\n })\n\n let appendEnv = flagOrDefault(nextjsAppendEnv, true)\n if (shouldPrompt(unattended, nextjsAppendEnv)) {\n appendEnv = await promptForAppendEnv(envFilename)\n }\n\n if (appendEnv) {\n await createOrAppendEnvVars({\n envVars: {\n DATASET: datasetName,\n PROJECT_ID: projectId,\n },\n filename: envFilename,\n framework: detectedFramework,\n log: true,\n output,\n outputPath: workDir,\n })\n }\n\n if (embeddedStudio) {\n const nextjsLocalDevOrigin = 'http://localhost:3000'\n const existingCorsOrigins = await listCorsOrigins(projectId)\n const hasExistingCorsOrigin = existingCorsOrigins.some(\n (item: {origin: string}) => item.origin === nextjsLocalDevOrigin,\n )\n if (!hasExistingCorsOrigin) {\n try {\n const createCorsRes = await createCorsOrigin({\n allowCredentials: true,\n origin: nextjsLocalDevOrigin,\n projectId,\n })\n\n output.log(\n createCorsRes.id\n ? `Added ${nextjsLocalDevOrigin} to CORS origins`\n : `Failed to add ${nextjsLocalDevOrigin} to CORS origins`,\n )\n } catch (corsError) {\n debug(`Error creating new CORS Origin ${nextjsLocalDevOrigin}: ${corsError}`)\n output.error(`Failed to add ${nextjsLocalDevOrigin} to CORS origins: ${corsError}`, {\n exit: 1,\n })\n }\n }\n }\n\n const chosen = await resolvePackageManager({\n interactive: !unattended,\n output,\n packageManager: packageManager as PackageManager,\n targetDir: workDir,\n })\n trace.log({selectedOption: chosen, step: 'selectPackageManager'})\n const packages = ['@sanity/vision@5', 'sanity@5', '@sanity/image-url@2', 'styled-components@6']\n if (templateToUse === 'blog') {\n packages.push('@sanity/icons')\n }\n await installNewPackages(\n {\n packageManager: chosen,\n packages,\n },\n {\n output,\n workDir,\n },\n )\n\n // will refactor this later\n const execOptions: Options = {\n cwd: workDir,\n encoding: 'utf8',\n env: getPartialEnvWithNpmPath(workDir),\n stdio: 'inherit',\n }\n\n switch (chosen) {\n case 'npm': {\n await execa('npm', ['install', 'next-sanity@12'], execOptions)\n break\n }\n case 'pnpm': {\n await execa('pnpm', ['install', 'next-sanity@12'], execOptions)\n break\n }\n case 'yarn': {\n const peerDeps = await getPeerDependencies('next-sanity@12', workDir)\n await installNewPackages(\n {packageManager: 'yarn', packages: ['next-sanity@12', ...peerDeps]},\n {output, workDir},\n )\n break\n }\n default: {\n // bun and manual - do nothing or handle differently\n break\n }\n }\n\n output.log(\n `\\n${styleText('green', 'Success!')} Your Sanity configuration files has been added to this project`,\n )\n if (mcpConfigured && mcpConfigured.length > 0) {\n const message = await getPostInitMCPPrompt(mcpConfigured)\n output.log(`\\n${message}`)\n output.log(`\\nLearn more: ${styleText('cyan', 'https://mcp.sanity.io')}`)\n output.log(\n `\\nHave feedback? Tell us in the community: ${styleText('cyan', 'https://www.sanity.io/community/join')}`,\n )\n }\n\n await writeStagingEnvIfNeeded(output, workDir)\n}\n"],"names":["existsSync","mkdir","writeFile","path","styleText","subdebug","confirm","execa","promptForAppendEnv","promptForEmbeddedStudio","promptForNextTemplate","promptForStudioPath","promptForTypeScript","createCorsOrigin","listCorsOrigins","getPeerDependencies","installNewPackages","getPartialEnvWithNpmPath","countNestedFolders","createOrAppendEnvVars","flagOrDefault","getPostInitMCPPrompt","shouldPrompt","writeStagingEnvIfNeeded","resolvePackageManager","sanityCliTemplate","sanityConfigTemplate","sanityFolder","sanityStudioTemplate","debug","writeOrOverwrite","filePath","content","workDir","params","overwrite","overwriteFiles","unattended","default","message","replace","folderPath","dirname","recursive","encoding","writeSourceFiles","fileExtension","files","srcFolderPrefix","Object","entries","includes","join","initNextJs","datasetName","detectedFramework","envFilename","mcpConfigured","nextjsAppendEnv","nextjsEmbedStudio","output","packageManager","projectId","template","trace","typescript","useTypeScript","log","selectedOption","step","embeddedStudio","hasSrcFolder","writeParams","appDir","srcPath","studioPath","embeddedStudioRouteFilePath","repeat","slice","length","sanityConfigPath","sanityCliPath","templateToUse","undefined","appendEnv","envVars","DATASET","PROJECT_ID","filename","framework","outputPath","nextjsLocalDevOrigin","existingCorsOrigins","hasExistingCorsOrigin","some","item","origin","createCorsRes","allowCredentials","id","corsError","error","exit","chosen","interactive","targetDir","packages","push","execOptions","cwd","env","stdio","peerDeps"],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ import { styleText } from 'node:util';
2
+ import { getCliToken, subdebug } from '@sanity/cli-core';
3
+ import { confirm } from '@sanity/cli-core/ux';
4
+ import { ImportDatasetCommand } from '../../commands/datasets/import.js';
5
+ import { updateProjectInitializedAt } from '../../services/projects.js';
6
+ import { getPostInitMCPPrompt } from './initHelpers.js';
7
+ import { scaffoldAndInstall, selectTemplate } from './scaffoldTemplate.js';
8
+ const debug = subdebug('init');
9
+ async function promptForDatasetImport(message) {
10
+ return confirm({
11
+ default: true,
12
+ message: message || 'This template includes a sample dataset, would you like to use it?'
13
+ });
14
+ }
15
+ export async function initStudio({ autoUpdates, datasetName, defaults, displayName, error, git, importDataset, isFirstProject, mcpConfigured, noGit, organizationId, output, outputPath, overwriteFiles, packageManager, projectId, remoteTemplateInfo, sluggedName, template, templateToken, trace, typescript, unattended, workDir }) {
16
+ const { template: resolvedTemplate, templateName, useTypeScript } = await selectTemplate({
17
+ remoteTemplateInfo,
18
+ template,
19
+ trace,
20
+ typescript,
21
+ unattended
22
+ });
23
+ if (!remoteTemplateInfo && !resolvedTemplate) {
24
+ error(`Template "${templateName}" not found`, {
25
+ exit: 1
26
+ });
27
+ }
28
+ // If the template has a sample dataset, prompt the user whether or not we should import it
29
+ const shouldImport = resolvedTemplate?.datasetUrl && (importDataset ?? (!unattended && await promptForDatasetImport(resolvedTemplate.importPrompt)));
30
+ trace.log({
31
+ selectedOption: shouldImport ? 'yes' : 'no',
32
+ step: 'importTemplateDataset'
33
+ });
34
+ try {
35
+ await updateProjectInitializedAt(projectId);
36
+ } catch (err) {
37
+ // Non-critical update
38
+ debug('Failed to update cliInitializedAt metadata', err);
39
+ }
40
+ const { pkgManager } = await scaffoldAndInstall({
41
+ autoUpdates,
42
+ datasetName,
43
+ defaults,
44
+ displayName,
45
+ git,
46
+ noGit,
47
+ organizationId,
48
+ output,
49
+ outputPath,
50
+ overwriteFiles,
51
+ packageManager,
52
+ projectId,
53
+ remoteTemplateInfo,
54
+ sluggedName,
55
+ templateName,
56
+ templateToken,
57
+ trace,
58
+ unattended,
59
+ useTypeScript,
60
+ workDir
61
+ });
62
+ // Prompt for dataset import (if a dataset is defined)
63
+ if (shouldImport && resolvedTemplate?.datasetUrl) {
64
+ const token = await getCliToken();
65
+ if (!token) {
66
+ return error('Authentication required to import dataset', {
67
+ exit: 1
68
+ });
69
+ }
70
+ await ImportDatasetCommand.run([
71
+ resolvedTemplate.datasetUrl,
72
+ '--project-id',
73
+ projectId,
74
+ '--dataset',
75
+ datasetName,
76
+ '--token',
77
+ token,
78
+ '--missing'
79
+ ], {
80
+ root: outputPath
81
+ });
82
+ output.log('');
83
+ output.log('If you want to delete the imported data, use');
84
+ output.log(` ${styleText('cyan', `npx sanity dataset delete ${datasetName}`)}`);
85
+ output.log('and create a new clean dataset with');
86
+ output.log(` ${styleText('cyan', `npx sanity dataset create <name>`)}\n`);
87
+ }
88
+ const devCommandMap = {
89
+ bun: 'bun dev',
90
+ manual: 'npm run dev',
91
+ npm: 'npm run dev',
92
+ pnpm: 'pnpm dev',
93
+ yarn: 'yarn dev'
94
+ };
95
+ const devCommand = devCommandMap[pkgManager];
96
+ const isCurrentDir = outputPath === process.cwd();
97
+ const goToProjectDir = `\n(${styleText('cyan', `cd ${outputPath}`)} to navigate to your new project directory)`;
98
+ //output for Studios here
99
+ output.log(`\u2705 ${styleText([
100
+ 'green',
101
+ 'bold'
102
+ ], 'Success!')} Your Studio has been created.`);
103
+ if (!isCurrentDir) output.log(goToProjectDir);
104
+ output.log(`\nGet started by running ${styleText('cyan', devCommand)} to launch your Studio's development server`);
105
+ if (mcpConfigured && mcpConfigured.length > 0) {
106
+ const message = await getPostInitMCPPrompt(mcpConfigured);
107
+ output.log(`\n${message}`);
108
+ output.log(`\nLearn more: ${styleText('cyan', 'https://mcp.sanity.io')}`);
109
+ output.log(`\nHave feedback? Tell us in the community: ${styleText('cyan', 'https://www.sanity.io/community/join')}`);
110
+ }
111
+ output.log('\n');
112
+ output.log(`Other helpful commands:`);
113
+ output.log(`npx sanity docs browse to open the documentation in a browser`);
114
+ output.log(`npx sanity manage to open the project settings in a browser`);
115
+ output.log(`npx sanity help to explore the CLI manual`);
116
+ if (isFirstProject) {
117
+ trace.log({
118
+ selectedOption: 'yes',
119
+ step: 'sendCommunityInvite'
120
+ });
121
+ const DISCORD_INVITE_LINK = 'https://www.sanity.io/community/join';
122
+ output.log(`\nJoin the Sanity community: ${styleText('cyan', DISCORD_INVITE_LINK)}`);
123
+ output.log('We look forward to seeing you there!\n');
124
+ }
125
+ }
126
+
127
+ //# sourceMappingURL=initStudio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/init/initStudio.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {getCliToken, type Output, subdebug, type TelemetryUserProperties} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {type TelemetryTrace} from '@sanity/telemetry'\n\nimport {ImportDatasetCommand} from '../../commands/datasets/import.js'\nimport {updateProjectInitializedAt} from '../../services/projects.js'\nimport {type InitStepResult} from '../../telemetry/init.telemetry.js'\nimport {type PackageManager} from '../../util/packageManager/packageManagerChoice.js'\nimport {type EditorName} from '../mcp/editorConfigs.js'\nimport {getPostInitMCPPrompt} from './initHelpers.js'\nimport {type RepoInfo} from './remoteTemplate.js'\nimport {scaffoldAndInstall, selectTemplate} from './scaffoldTemplate.js'\n\nconst debug = subdebug('init')\n\nasync function promptForDatasetImport(message?: string): Promise<boolean> {\n return confirm({\n default: true,\n message: message || 'This template includes a sample dataset, would you like to use it?',\n })\n}\n\nexport async function initStudio({\n autoUpdates,\n datasetName,\n defaults,\n displayName,\n error,\n git,\n importDataset,\n isFirstProject,\n mcpConfigured,\n noGit,\n organizationId,\n output,\n outputPath,\n overwriteFiles,\n packageManager,\n projectId,\n remoteTemplateInfo,\n sluggedName,\n template,\n templateToken,\n trace,\n typescript,\n unattended,\n workDir,\n}: {\n autoUpdates: boolean\n datasetName: string\n defaults: {projectName: string}\n displayName: string\n error: Output['error']\n git?: boolean | string\n importDataset?: boolean\n isFirstProject: boolean\n mcpConfigured: EditorName[]\n noGit?: boolean\n organizationId: string | undefined\n output: Output\n outputPath: string\n overwriteFiles?: boolean\n packageManager?: string\n projectId: string\n remoteTemplateInfo: RepoInfo | undefined\n sluggedName: string\n template?: string\n templateToken?: string\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>\n typescript?: boolean\n unattended: boolean\n workDir: string\n}): Promise<void> {\n const {\n template: resolvedTemplate,\n templateName,\n useTypeScript,\n } = await selectTemplate({\n remoteTemplateInfo,\n template,\n trace,\n typescript,\n unattended,\n })\n\n if (!remoteTemplateInfo && !resolvedTemplate) {\n error(`Template \"${templateName}\" not found`, {exit: 1})\n }\n\n // If the template has a sample dataset, prompt the user whether or not we should import it\n const shouldImport =\n resolvedTemplate?.datasetUrl &&\n (importDataset ??\n (!unattended && (await promptForDatasetImport(resolvedTemplate.importPrompt))))\n\n trace.log({\n selectedOption: shouldImport ? 'yes' : 'no',\n step: 'importTemplateDataset',\n })\n\n try {\n await updateProjectInitializedAt(projectId)\n } catch (err) {\n // Non-critical update\n debug('Failed to update cliInitializedAt metadata', err)\n }\n\n const {pkgManager} = await scaffoldAndInstall({\n autoUpdates,\n datasetName,\n defaults,\n displayName,\n git,\n noGit,\n organizationId,\n output,\n outputPath,\n overwriteFiles,\n packageManager,\n projectId,\n remoteTemplateInfo,\n sluggedName,\n templateName,\n templateToken,\n trace,\n unattended,\n useTypeScript,\n workDir,\n })\n\n // Prompt for dataset import (if a dataset is defined)\n if (shouldImport && resolvedTemplate?.datasetUrl) {\n const token = await getCliToken()\n if (!token) {\n return error('Authentication required to import dataset', {exit: 1})\n }\n await ImportDatasetCommand.run(\n [\n resolvedTemplate.datasetUrl,\n '--project-id',\n projectId,\n '--dataset',\n datasetName,\n '--token',\n token,\n '--missing',\n ],\n {\n root: outputPath,\n },\n )\n\n output.log('')\n output.log('If you want to delete the imported data, use')\n output.log(` ${styleText('cyan', `npx sanity dataset delete ${datasetName}`)}`)\n output.log('and create a new clean dataset with')\n output.log(` ${styleText('cyan', `npx sanity dataset create <name>`)}\\n`)\n }\n\n const devCommandMap: Record<PackageManager, string> = {\n bun: 'bun dev',\n manual: 'npm run dev',\n npm: 'npm run dev',\n pnpm: 'pnpm dev',\n yarn: 'yarn dev',\n }\n const devCommand = devCommandMap[pkgManager]\n\n const isCurrentDir = outputPath === process.cwd()\n const goToProjectDir = `\\n(${styleText('cyan', `cd ${outputPath}`)} to navigate to your new project directory)`\n\n //output for Studios here\n output.log(`\\u2705 ${styleText(['green', 'bold'], 'Success!')} Your Studio has been created.`)\n if (!isCurrentDir) output.log(goToProjectDir)\n output.log(\n `\\nGet started by running ${styleText('cyan', devCommand)} to launch your Studio's development server`,\n )\n if (mcpConfigured && mcpConfigured.length > 0) {\n const message = await getPostInitMCPPrompt(mcpConfigured)\n output.log(`\\n${message}`)\n output.log(`\\nLearn more: ${styleText('cyan', 'https://mcp.sanity.io')}`)\n output.log(\n `\\nHave feedback? Tell us in the community: ${styleText('cyan', 'https://www.sanity.io/community/join')}`,\n )\n }\n output.log('\\n')\n output.log(`Other helpful commands:`)\n output.log(`npx sanity docs browse to open the documentation in a browser`)\n output.log(`npx sanity manage to open the project settings in a browser`)\n output.log(`npx sanity help to explore the CLI manual`)\n\n if (isFirstProject) {\n trace.log({selectedOption: 'yes', step: 'sendCommunityInvite'})\n\n const DISCORD_INVITE_LINK = 'https://www.sanity.io/community/join'\n\n output.log(`\\nJoin the Sanity community: ${styleText('cyan', DISCORD_INVITE_LINK)}`)\n output.log('We look forward to seeing you there!\\n')\n }\n}\n"],"names":["styleText","getCliToken","subdebug","confirm","ImportDatasetCommand","updateProjectInitializedAt","getPostInitMCPPrompt","scaffoldAndInstall","selectTemplate","debug","promptForDatasetImport","message","default","initStudio","autoUpdates","datasetName","defaults","displayName","error","git","importDataset","isFirstProject","mcpConfigured","noGit","organizationId","output","outputPath","overwriteFiles","packageManager","projectId","remoteTemplateInfo","sluggedName","template","templateToken","trace","typescript","unattended","workDir","resolvedTemplate","templateName","useTypeScript","exit","shouldImport","datasetUrl","importPrompt","log","selectedOption","step","err","pkgManager","token","run","root","devCommandMap","bun","manual","npm","pnpm","yarn","devCommand","isCurrentDir","process","cwd","goToProjectDir","length","DISCORD_INVITE_LINK"],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ import { select } from '@sanity/cli-core/ux';
2
+ import { promptForTypeScript } from '../../prompts/init/promptForTypescript.js';
3
+ import { installDeclaredPackages } from '../../util/packageManager/installPackages.js';
4
+ import { bootstrapTemplate } from './bootstrapTemplate.js';
5
+ import { tryGitInit } from './git.js';
6
+ import { writeStagingEnvIfNeeded } from './initHelpers.js';
7
+ import { resolvePackageManager } from './resolvePackageManager.js';
8
+ import templates from './templates/index.js';
9
+ async function promptForTemplate(params) {
10
+ const defaultTemplate = params.unattended || params.template ? params.template || 'clean' : null;
11
+ if (defaultTemplate) {
12
+ return defaultTemplate;
13
+ }
14
+ return select({
15
+ choices: [
16
+ {
17
+ name: 'Clean project with no predefined schema types',
18
+ value: 'clean'
19
+ },
20
+ {
21
+ name: 'Blog (schema)',
22
+ value: 'blog'
23
+ },
24
+ {
25
+ name: 'E-commerce (Shopify)',
26
+ value: 'shopify'
27
+ },
28
+ {
29
+ name: 'Movie project (schema + sample data)',
30
+ value: 'moviedb'
31
+ }
32
+ ],
33
+ message: 'Select project template'
34
+ });
35
+ }
36
+ export async function selectTemplate({ remoteTemplateInfo, template, trace, typescript, unattended }) {
37
+ const templateName = await promptForTemplate({
38
+ template,
39
+ unattended
40
+ });
41
+ trace.log({
42
+ selectedOption: templateName,
43
+ step: 'selectProjectTemplate'
44
+ });
45
+ const resolvedTemplate = templates[templateName];
46
+ let useTypeScript = typescript;
47
+ if (!remoteTemplateInfo && resolvedTemplate && resolvedTemplate.typescriptOnly === true) {
48
+ useTypeScript = true;
49
+ } else if (!unattended && typescript === undefined) {
50
+ useTypeScript = await promptForTypeScript();
51
+ trace.log({
52
+ selectedOption: useTypeScript ? 'yes' : 'no',
53
+ step: 'useTypeScript'
54
+ });
55
+ }
56
+ return {
57
+ template: resolvedTemplate,
58
+ templateName,
59
+ useTypeScript
60
+ };
61
+ }
62
+ export async function scaffoldAndInstall({ autoUpdates, datasetName, defaults, displayName, git, noGit, organizationId, output, outputPath, overwriteFiles, packageManager, projectId, remoteTemplateInfo, sluggedName, templateName, templateToken, trace, unattended, useTypeScript, workDir }) {
63
+ try {
64
+ await bootstrapTemplate({
65
+ autoUpdates,
66
+ bearerToken: templateToken,
67
+ dataset: datasetName,
68
+ organizationId,
69
+ output,
70
+ outputPath,
71
+ overwriteFiles: overwriteFiles,
72
+ packageName: sluggedName,
73
+ projectId,
74
+ projectName: displayName || defaults.projectName,
75
+ remoteTemplateInfo,
76
+ templateName,
77
+ useTypeScript: useTypeScript
78
+ });
79
+ } catch (error) {
80
+ if (error instanceof Error) {
81
+ throw error;
82
+ }
83
+ throw new Error(String(error), {
84
+ cause: error
85
+ });
86
+ }
87
+ const pkgManager = await resolvePackageManager({
88
+ interactive: !unattended,
89
+ output,
90
+ packageManager: packageManager,
91
+ targetDir: outputPath
92
+ });
93
+ trace.log({
94
+ selectedOption: pkgManager,
95
+ step: 'selectPackageManager'
96
+ });
97
+ // Now for the slow part... installing dependencies
98
+ await installDeclaredPackages(outputPath, pkgManager, {
99
+ output,
100
+ workDir
101
+ });
102
+ const useGit = !noGit && (git === undefined || Boolean(git));
103
+ const commitMessage = git;
104
+ await writeStagingEnvIfNeeded(output, outputPath);
105
+ // Try initializing a git repository
106
+ if (useGit) {
107
+ tryGitInit(outputPath, typeof commitMessage === 'string' ? commitMessage : undefined);
108
+ }
109
+ return {
110
+ pkgManager
111
+ };
112
+ }
113
+
114
+ //# sourceMappingURL=scaffoldTemplate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/init/scaffoldTemplate.ts"],"sourcesContent":["import {type Output, type TelemetryUserProperties} from '@sanity/cli-core'\nimport {select} from '@sanity/cli-core/ux'\nimport {type TelemetryTrace} from '@sanity/telemetry'\n\nimport {promptForTypeScript} from '../../prompts/init/promptForTypescript.js'\nimport {type InitStepResult} from '../../telemetry/init.telemetry.js'\nimport {installDeclaredPackages} from '../../util/packageManager/installPackages.js'\nimport {type PackageManager} from '../../util/packageManager/packageManagerChoice.js'\nimport {bootstrapTemplate} from './bootstrapTemplate.js'\nimport {tryGitInit} from './git.js'\nimport {writeStagingEnvIfNeeded} from './initHelpers.js'\nimport {type RepoInfo} from './remoteTemplate.js'\nimport {resolvePackageManager} from './resolvePackageManager.js'\nimport templates from './templates/index.js'\nimport {type ProjectTemplate} from './types.js'\n\ninterface SelectedTemplate {\n template: ProjectTemplate | undefined\n templateName: string\n useTypeScript: boolean | undefined\n}\n\nasync function promptForTemplate(params: {\n template?: string\n unattended: boolean\n}): Promise<string> {\n const defaultTemplate = params.unattended || params.template ? params.template || 'clean' : null\n if (defaultTemplate) {\n return defaultTemplate\n }\n\n return select({\n choices: [\n {\n name: 'Clean project with no predefined schema types',\n value: 'clean',\n },\n {\n name: 'Blog (schema)',\n value: 'blog',\n },\n {\n name: 'E-commerce (Shopify)',\n value: 'shopify',\n },\n {\n name: 'Movie project (schema + sample data)',\n value: 'moviedb',\n },\n ],\n message: 'Select project template',\n })\n}\n\nexport async function selectTemplate({\n remoteTemplateInfo,\n template,\n trace,\n typescript,\n unattended,\n}: {\n remoteTemplateInfo: RepoInfo | undefined\n template?: string\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>\n typescript?: boolean\n unattended: boolean\n}): Promise<SelectedTemplate> {\n const templateName = await promptForTemplate({template, unattended})\n trace.log({\n selectedOption: templateName,\n step: 'selectProjectTemplate',\n })\n\n const resolvedTemplate = templates[templateName]\n\n let useTypeScript = typescript\n if (!remoteTemplateInfo && resolvedTemplate && resolvedTemplate.typescriptOnly === true) {\n useTypeScript = true\n } else if (!unattended && typescript === undefined) {\n useTypeScript = await promptForTypeScript()\n trace.log({\n selectedOption: useTypeScript ? 'yes' : 'no',\n step: 'useTypeScript',\n })\n }\n\n return {\n template: resolvedTemplate,\n templateName,\n useTypeScript,\n }\n}\n\nexport async function scaffoldAndInstall({\n autoUpdates,\n datasetName,\n defaults,\n displayName,\n git,\n noGit,\n organizationId,\n output,\n outputPath,\n overwriteFiles,\n packageManager,\n projectId,\n remoteTemplateInfo,\n sluggedName,\n templateName,\n templateToken,\n trace,\n unattended,\n useTypeScript,\n workDir,\n}: {\n autoUpdates: boolean\n datasetName: string\n defaults: {projectName: string}\n displayName: string\n git?: boolean | string\n noGit?: boolean\n organizationId: string | undefined\n output: Output\n outputPath: string\n overwriteFiles?: boolean\n packageManager?: string\n projectId: string\n remoteTemplateInfo: RepoInfo | undefined\n sluggedName: string\n templateName: string\n templateToken?: string\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>\n unattended: boolean\n useTypeScript: boolean | undefined\n workDir: string\n}): Promise<{pkgManager: PackageManager}> {\n try {\n await bootstrapTemplate({\n autoUpdates,\n bearerToken: templateToken,\n dataset: datasetName,\n organizationId,\n output,\n outputPath,\n overwriteFiles: overwriteFiles as boolean,\n packageName: sluggedName,\n projectId,\n projectName: displayName || defaults.projectName,\n remoteTemplateInfo,\n templateName,\n useTypeScript: useTypeScript as boolean,\n })\n } catch (error) {\n if (error instanceof Error) {\n throw error\n }\n throw new Error(String(error), {cause: error})\n }\n\n const pkgManager = await resolvePackageManager({\n interactive: !unattended,\n output,\n packageManager: packageManager as PackageManager,\n targetDir: outputPath,\n })\n\n trace.log({\n selectedOption: pkgManager,\n step: 'selectPackageManager',\n })\n\n // Now for the slow part... installing dependencies\n await installDeclaredPackages(outputPath, pkgManager, {\n output,\n workDir,\n })\n\n const useGit = !noGit && (git === undefined || Boolean(git))\n const commitMessage = git\n await writeStagingEnvIfNeeded(output, outputPath)\n\n // Try initializing a git repository\n if (useGit) {\n tryGitInit(outputPath, typeof commitMessage === 'string' ? commitMessage : undefined)\n }\n\n return {pkgManager}\n}\n"],"names":["select","promptForTypeScript","installDeclaredPackages","bootstrapTemplate","tryGitInit","writeStagingEnvIfNeeded","resolvePackageManager","templates","promptForTemplate","params","defaultTemplate","unattended","template","choices","name","value","message","selectTemplate","remoteTemplateInfo","trace","typescript","templateName","log","selectedOption","step","resolvedTemplate","useTypeScript","typescriptOnly","undefined","scaffoldAndInstall","autoUpdates","datasetName","defaults","displayName","git","noGit","organizationId","output","outputPath","overwriteFiles","packageManager","projectId","sluggedName","templateToken","workDir","bearerToken","dataset","packageName","projectName","error","Error","String","cause","pkgManager","interactive","targetDir","useGit","Boolean","commitMessage"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  const appTemplate = {
2
2
  entry: './src/App.tsx',
3
- type: 'module'
3
+ type: 'module',
4
+ typescriptOnly: true
4
5
  };
5
6
  export default appTemplate;
6
7
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/actions/init/templates/appQuickstart.ts"],"sourcesContent":["import {type ProjectTemplate} from '../types.js'\n\nconst appTemplate: ProjectTemplate = {\n entry: './src/App.tsx',\n type: 'module',\n}\n\nexport default appTemplate\n"],"names":["appTemplate","entry","type"],"mappings":"AAEA,MAAMA,cAA+B;IACnCC,OAAO;IACPC,MAAM;AACR;AAEA,eAAeF,YAAW"}
1
+ {"version":3,"sources":["../../../../src/actions/init/templates/appQuickstart.ts"],"sourcesContent":["import {type ProjectTemplate} from '../types.js'\n\nconst appTemplate: ProjectTemplate = {\n entry: './src/App.tsx',\n type: 'module',\n typescriptOnly: true,\n}\n\nexport default appTemplate\n"],"names":["appTemplate","entry","type","typescriptOnly"],"mappings":"AAEA,MAAMA,cAA+B;IACnCC,OAAO;IACPC,MAAM;IACNC,gBAAgB;AAClB;AAEA,eAAeH,YAAW"}
@@ -4,7 +4,8 @@ const appSanityUiTemplate = {
4
4
  'styled-components': '^6.1.18'
5
5
  },
6
6
  entry: './src/App.tsx',
7
- type: 'module'
7
+ type: 'module',
8
+ typescriptOnly: true
8
9
  };
9
10
  export default appSanityUiTemplate;
10
11
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/actions/init/templates/appSanityUi.ts"],"sourcesContent":["import {type ProjectTemplate} from '../types.js'\n\nconst appSanityUiTemplate: ProjectTemplate = {\n dependencies: {\n '@sanity/ui': '^3',\n 'styled-components': '^6.1.18',\n },\n entry: './src/App.tsx',\n type: 'module',\n}\n\nexport default appSanityUiTemplate\n"],"names":["appSanityUiTemplate","dependencies","entry","type"],"mappings":"AAEA,MAAMA,sBAAuC;IAC3CC,cAAc;QACZ,cAAc;QACd,qBAAqB;IACvB;IACAC,OAAO;IACPC,MAAM;AACR;AAEA,eAAeH,oBAAmB"}
1
+ {"version":3,"sources":["../../../../src/actions/init/templates/appSanityUi.ts"],"sourcesContent":["import {type ProjectTemplate} from '../types.js'\n\nconst appSanityUiTemplate: ProjectTemplate = {\n dependencies: {\n '@sanity/ui': '^3',\n 'styled-components': '^6.1.18',\n },\n entry: './src/App.tsx',\n type: 'module',\n typescriptOnly: true,\n}\n\nexport default appSanityUiTemplate\n"],"names":["appSanityUiTemplate","dependencies","entry","type","typescriptOnly"],"mappings":"AAEA,MAAMA,sBAAuC;IAC3CC,cAAc;QACZ,cAAc;QACd,qBAAqB;IACvB;IACAC,OAAO;IACPC,MAAM;IACNC,gBAAgB;AAClB;AAEA,eAAeJ,oBAAmB"}
@@ -162,8 +162,7 @@ export const { sanityFetch, SanityLive } = defineLive({
162
162
  client,
163
163
  });
164
164
  `;
165
- const imageTS = `import createImageUrlBuilder from '@sanity/image-url'
166
- import type { SanityImageSource } from "@sanity/image-url";
165
+ const imageTS = `import { createImageUrlBuilder, type SanityImageSource } from '@sanity/image-url'
167
166
 
168
167
  import { dataset, projectId } from '../env'
169
168