@sanity/cli 8.0.3 → 8.2.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.
package/README.md CHANGED
@@ -3035,10 +3035,10 @@ DESCRIPTION
3035
3035
  the deadline and the project and its content are deleted.
3036
3036
 
3037
3037
  Two things to keep private: the claim link, because anyone who opens it
3038
- becomes the owner, and the access token saved in ./sanity/.env.local and
3039
- ./web/.env.local, because it can read and change everything in the project.
3040
- Keep both env files out of git, and never put the token in code that runs in
3041
- the browser.
3038
+ becomes the owner, and the access token saved in ./sanity/.env.local, because
3039
+ it can read and change everything in the project. ./web/.env.local has only
3040
+ the project ID and dataset. Keep both env files out of git, and never put the
3041
+ token in code that runs in the browser.
3042
3042
 
3043
3043
  Run this command with --instructions for the full agent setup guide.
3044
3044
 
@@ -7,9 +7,9 @@ export const sdkAppDependencies = {
7
7
  'react-dom': '^19.2.4'
8
8
  },
9
9
  devDependencies: {
10
- '@sanity/eslint-config-studio': '^6',
10
+ '@sanity/eslint-config-studio': '^7',
11
11
  '@types/react': '^19.2.14',
12
- eslint: '^9.28',
12
+ eslint: '^10.8.1',
13
13
  prettier: '^3.5',
14
14
  sanity: 'latest',
15
15
  typescript: '^5.8'
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/init/sdkAppDependencies.ts"],"sourcesContent":["export const sdkAppDependencies = {\n dependencies: {\n // change these to 'latest' as in studioDependencies.ts once SDK v3 is released\n '@sanity/sdk': '^2',\n '@sanity/sdk-react': '^2',\n react: '^19.2.4',\n 'react-dom': '^19.2.4',\n },\n\n devDependencies: {\n '@sanity/eslint-config-studio': '^6',\n '@types/react': '^19.2.14',\n eslint: '^9.28',\n prettier: '^3.5',\n sanity: 'latest',\n typescript: '^5.8', // Peer dependency of eslint-config-studio (implicitly)\n },\n}\n"],"names":["sdkAppDependencies","dependencies","react","devDependencies","eslint","prettier","sanity","typescript"],"mappings":"AAAA,OAAO,MAAMA,qBAAqB;IAChCC,cAAc;QACZ,+EAA+E;QAC/E,eAAe;QACf,qBAAqB;QACrBC,OAAO;QACP,aAAa;IACf;IAEAC,iBAAiB;QACf,gCAAgC;QAChC,gBAAgB;QAChBC,QAAQ;QACRC,UAAU;QACVC,QAAQ;QACRC,YAAY;IACd;AACF,EAAC"}
1
+ {"version":3,"sources":["../../../src/actions/init/sdkAppDependencies.ts"],"sourcesContent":["export const sdkAppDependencies = {\n dependencies: {\n // change these to 'latest' as in studioDependencies.ts once SDK v3 is released\n '@sanity/sdk': '^2',\n '@sanity/sdk-react': '^2',\n react: '^19.2.4',\n 'react-dom': '^19.2.4',\n },\n\n devDependencies: {\n '@sanity/eslint-config-studio': '^7',\n '@types/react': '^19.2.14',\n eslint: '^10.8.1',\n prettier: '^3.5',\n sanity: 'latest',\n typescript: '^5.8', // Peer dependency of eslint-config-studio (implicitly)\n },\n}\n"],"names":["sdkAppDependencies","dependencies","react","devDependencies","eslint","prettier","sanity","typescript"],"mappings":"AAAA,OAAO,MAAMA,qBAAqB;IAChCC,cAAc;QACZ,+EAA+E;QAC/E,eAAe;QACf,qBAAqB;QACrBC,OAAO;QACP,aAAa;IACf;IAEAC,iBAAiB;QACf,gCAAgC;QAChC,gBAAgB;QAChBC,QAAQ;QACRC,UAAU;QACVC,QAAQ;QACRC,YAAY;IACd;AACF,EAAC"}
@@ -12,10 +12,10 @@ export const studioDependencies = {
12
12
  },
13
13
  devDependencies: {
14
14
  // Linting/tooling
15
- '@sanity/eslint-config-studio': '^6',
15
+ '@sanity/eslint-config-studio': '^7',
16
16
  // When using typescript, we'll want the these types too, so might as well install them
17
17
  '@types/react': '^19.2.14',
18
- eslint: '^9.28',
18
+ eslint: '^10.8.1',
19
19
  prettier: '^3.5',
20
20
  typescript: '^5.8'
21
21
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/init/studioDependencies.ts"],"sourcesContent":["export const studioDependencies = {\n // Dependencies for a default Sanity installation\n dependencies: {\n // Official studio dependencies\n sanity: 'latest',\n\n // Official studio plugin dependencies\n '@sanity/vision': 'latest',\n\n // Non-Sanity dependencies\n react: '^19.2.4',\n 'react-dom': '^19.2.4',\n 'styled-components': '^6.1.18',\n },\n\n devDependencies: {\n // Linting/tooling\n '@sanity/eslint-config-studio': '^6',\n // When using typescript, we'll want the these types too, so might as well install them\n '@types/react': '^19.2.14',\n eslint: '^9.28',\n prettier: '^3.5',\n typescript: '^5.8', // Peer dependency of eslint-config-studio (implicitly)\n },\n}\n"],"names":["studioDependencies","dependencies","sanity","react","devDependencies","eslint","prettier","typescript"],"mappings":"AAAA,OAAO,MAAMA,qBAAqB;IAChC,iDAAiD;IACjDC,cAAc;QACZ,+BAA+B;QAC/BC,QAAQ;QAER,sCAAsC;QACtC,kBAAkB;QAElB,0BAA0B;QAC1BC,OAAO;QACP,aAAa;QACb,qBAAqB;IACvB;IAEAC,iBAAiB;QACf,kBAAkB;QAClB,gCAAgC;QAChC,uFAAuF;QACvF,gBAAgB;QAChBC,QAAQ;QACRC,UAAU;QACVC,YAAY;IACd;AACF,EAAC"}
1
+ {"version":3,"sources":["../../../src/actions/init/studioDependencies.ts"],"sourcesContent":["export const studioDependencies = {\n // Dependencies for a default Sanity installation\n dependencies: {\n // Official studio dependencies\n sanity: 'latest',\n\n // Official studio plugin dependencies\n '@sanity/vision': 'latest',\n\n // Non-Sanity dependencies\n react: '^19.2.4',\n 'react-dom': '^19.2.4',\n 'styled-components': '^6.1.18',\n },\n\n devDependencies: {\n // Linting/tooling\n '@sanity/eslint-config-studio': '^7',\n // When using typescript, we'll want the these types too, so might as well install them\n '@types/react': '^19.2.14',\n eslint: '^10.8.1',\n prettier: '^3.5',\n typescript: '^5.8', // Peer dependency of eslint-config-studio (implicitly)\n },\n}\n"],"names":["studioDependencies","dependencies","sanity","react","devDependencies","eslint","prettier","typescript"],"mappings":"AAAA,OAAO,MAAMA,qBAAqB;IAChC,iDAAiD;IACjDC,cAAc;QACZ,+BAA+B;QAC/BC,QAAQ;QAER,sCAAsC;QACtC,kBAAkB;QAElB,0BAA0B;QAC1BC,OAAO;QACP,aAAa;QACb,qBAAqB;IACvB;IAEAC,iBAAiB;QACf,kBAAkB;QAClB,gCAAgC;QAChC,uFAAuF;QACvF,gBAAgB;QAChBC,QAAQ;QACRC,UAAU;QACVC,YAAY;IACd;AACF,EAAC"}
@@ -61,13 +61,19 @@ export async function getUnavailableScaffoldTarget(workDir) {
61
61
  const { unavailableTarget } = await inspectScaffoldTargets(workDir);
62
62
  return unavailableTarget;
63
63
  }
64
- function createScaffoldEnv(dataset, projectId, token) {
64
+ function createStudioEnv(dataset, projectId, token) {
65
65
  return {
66
66
  SANITY_AUTH_TOKEN: token,
67
67
  SANITY_DATASET: dataset,
68
68
  SANITY_PROJECT_ID: projectId
69
69
  };
70
70
  }
71
+ function createFrontendEnv(dataset, projectId) {
72
+ return {
73
+ NEXT_PUBLIC_SANITY_DATASET: dataset,
74
+ NEXT_PUBLIC_SANITY_PROJECT_ID: projectId
75
+ };
76
+ }
71
77
  export async function scaffoldProject({ cancelSignal, dataset, displayName, output, packageManager, projectId, telemetry, token, workDir }) {
72
78
  cancelSignal?.throwIfAborted();
73
79
  const { detectedFramework: detected, unavailableTarget } = await inspectScaffoldTargets(workDir);
@@ -129,8 +135,7 @@ export async function scaffoldProject({ cancelSignal, dataset, displayName, outp
129
135
  throw err;
130
136
  }
131
137
  cancelSignal?.throwIfAborted();
132
- const scaffoldEnv = createScaffoldEnv(dataset, projectId, token);
133
- writeScaffoldEnv(path.join(studioPath, '.env.local'), scaffoldEnv, `Studio scaffold completed, but writing ./${STUDIO_ENV_FILE} failed`);
138
+ writeScaffoldEnv(path.join(studioPath, '.env.local'), createStudioEnv(dataset, projectId, token), `Studio scaffold completed, but writing ./${STUDIO_ENV_FILE} failed`, 'it holds a live project token');
134
139
  if (detected) {
135
140
  debug('Detected %s in %s, leaving the frontend alone', detected.name, workDir);
136
141
  return {
@@ -158,7 +163,7 @@ export async function scaffoldProject({ cancelSignal, dataset, displayName, outp
158
163
  throw err;
159
164
  }
160
165
  const frontendPath = path.join(workDir, FRONTEND_DIR);
161
- writeScaffoldEnv(path.join(frontendPath, '.env.local'), scaffoldEnv, `Website scaffold completed, but writing ./${FRONTEND_ENV_FILE} failed`);
166
+ writeScaffoldEnv(path.join(frontendPath, '.env.local'), createFrontendEnv(dataset, projectId), `Website scaffold completed, but writing ./${FRONTEND_ENV_FILE} failed`, 'it holds the project ID and dataset');
162
167
  let frontendDependenciesInstalled = resolvedPackageManager !== 'manual';
163
168
  let frontendDependencyError;
164
169
  if (frontendDependenciesInstalled) {
@@ -185,9 +190,9 @@ export async function scaffoldProject({ cancelSignal, dataset, displayName, outp
185
190
  studioPath
186
191
  };
187
192
  }
188
- function writeScaffoldEnv(envPath, values, errorContext) {
193
+ function writeScaffoldEnv(envPath, values, errorContext, gitignoreReason) {
189
194
  const lines = [
190
- '# Added by `sanity new`. Keep this file out of git: it holds a live project token.',
195
+ `# Added by \`sanity new\`. Keep this file out of git: ${gitignoreReason}.`,
191
196
  ...Object.entries(values).map(([key, value])=>`${key}="${value}"`)
192
197
  ];
193
198
  try {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/scaffold/scaffoldProject.ts"],"sourcesContent":["import {writeFileSync} from 'node:fs'\nimport {lstat} from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {type CLITelemetryStore, type Output, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {type Framework, frameworks} from '@vercel/frameworks'\n\nimport {CLIInitStepCompleted} from '../../telemetry/init.telemetry.js'\nimport {detectFrameworkRecord} from '../../util/detectFramework.js'\nimport {dirIsEmptyOrNonExistent} from '../../util/dirIsEmptyOrNonExistent.js'\nimport {getProjectDefaults} from '../../util/getProjectDefaults.js'\nimport {type PackageManager} from '../../util/packageManager/packageManagerChoice.js'\nimport {initStudio} from '../init/initStudio.js'\nimport {resolvePackageManager} from '../init/resolvePackageManager.js'\nimport {type InitOptions} from '../init/types.js'\nimport {createFrontend, FrontendScaffoldError, installFrontendDeps} from './createFrontend.js'\n\nconst debug = subdebug('scaffold')\n\nexport const STUDIO_DIR = 'sanity'\nexport const FRONTEND_DIR = 'web'\nexport const STUDIO_ENV_FILE = `${STUDIO_DIR}/.env.local`\nexport const FRONTEND_ENV_FILE = `${FRONTEND_DIR}/.env.local`\n\nconst STUDIO_PACKAGE_NAME = 'sanity-studio'\nconst STUDIO_PACKAGE_MANAGERS = new Set<PackageManager>(['npm', 'pnpm', 'yarn'])\n\nexport async function isStudioScaffoldTargetAvailable(workDir: string): Promise<boolean> {\n return isScaffoldTargetAvailable(workDir, STUDIO_DIR)\n}\n\nasync function isScaffoldTargetAvailable(workDir: string, targetDir: string): Promise<boolean> {\n const targetPath = path.join(workDir, targetDir)\n try {\n if (!(await lstat(targetPath)).isDirectory()) {\n return false\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw err\n }\n }\n\n return dirIsEmptyOrNonExistent(targetPath)\n}\n\nasync function inspectScaffoldTargets(workDir: string) {\n if (!(await isStudioScaffoldTargetAvailable(workDir))) {\n return {unavailableTarget: STUDIO_DIR}\n }\n\n const detectedFramework = await detectFrameworkRecord({\n frameworkList: frameworks as readonly Framework[],\n rootPath: workDir,\n })\n if (!detectedFramework && !(await isScaffoldTargetAvailable(workDir, FRONTEND_DIR))) {\n return {unavailableTarget: FRONTEND_DIR}\n }\n\n return {detectedFramework}\n}\n\nexport async function getUnavailableScaffoldTarget(workDir: string): Promise<string | undefined> {\n const {unavailableTarget} = await inspectScaffoldTargets(workDir)\n return unavailableTarget\n}\n\nexport interface ScaffoldResult {\n studioPath: string\n\n detectedFramework?: string\n frontendCreationError?: string\n frontendDependenciesInstalled?: boolean\n frontendDependencyError?: string\n frontendPackageManager?: PackageManager\n frontendPath?: string\n}\n\nfunction createScaffoldEnv(dataset: string, projectId: string, token: string) {\n return {\n SANITY_AUTH_TOKEN: token,\n SANITY_DATASET: dataset,\n SANITY_PROJECT_ID: projectId,\n }\n}\n\nexport async function scaffoldProject({\n cancelSignal,\n dataset,\n displayName,\n output,\n packageManager,\n projectId,\n telemetry,\n token,\n workDir,\n}: {\n cancelSignal?: AbortSignal\n dataset: string\n displayName: string\n output: Output\n packageManager?: PackageManager\n projectId: string\n telemetry: CLITelemetryStore\n token: string\n workDir: string\n}): Promise<ScaffoldResult> {\n cancelSignal?.throwIfAborted()\n const {detectedFramework: detected, unavailableTarget} = await inspectScaffoldTargets(workDir)\n const studioPath = path.join(workDir, STUDIO_DIR)\n if (unavailableTarget) {\n throw new Error(`./${unavailableTarget} is not an empty directory`)\n }\n\n const resolvedPackageManager = await resolvePackageManager({\n interactive: false,\n output,\n packageManager: packageManager as PackageManager,\n targetDir: workDir,\n })\n\n const options: InitOptions = {\n autoUpdates: true,\n bare: false,\n dataset,\n datasetDefault: true,\n fromCreate: false,\n git: false,\n mcpMode: 'skip',\n outputPath: studioPath,\n packageManager: STUDIO_PACKAGE_MANAGERS.has(resolvedPackageManager)\n ? (resolvedPackageManager as InitOptions['packageManager'])\n : undefined,\n project: projectId,\n skillsMode: 'skip',\n template: 'clean',\n typescript: true,\n unattended: true,\n }\n\n const trace = telemetry.trace(CLIInitStepCompleted)\n trace.start()\n try {\n // To avoid changing Studio initialization internals, we're deferring passing `cancelSignal`\n // until post `sanity new` launch.\n await initStudio({\n datasetName: dataset,\n defaults: await getProjectDefaults({isPlugin: false, workDir}),\n displayName,\n isFirstProject: false,\n mcpConfigured: [],\n options,\n organizationId: undefined,\n output,\n outputPath: studioPath,\n preclaim: true,\n projectId,\n remoteTemplateInfo: undefined,\n sluggedName: STUDIO_PACKAGE_NAME,\n trace,\n workbench: false,\n workDir,\n })\n trace.complete()\n } catch (err) {\n trace.error(err instanceof Error ? err : new Error(String(err)))\n throw err\n }\n\n cancelSignal?.throwIfAborted()\n const scaffoldEnv = createScaffoldEnv(dataset, projectId, token)\n writeScaffoldEnv(\n path.join(studioPath, '.env.local'),\n scaffoldEnv,\n `Studio scaffold completed, but writing ./${STUDIO_ENV_FILE} failed`,\n )\n\n if (detected) {\n debug('Detected %s in %s, leaving the frontend alone', detected.name, workDir)\n return {\n detectedFramework: detected.name,\n studioPath,\n }\n }\n\n try {\n await createFrontend({\n cancelSignal,\n dirName: FRONTEND_DIR,\n output,\n packageManager: resolvedPackageManager,\n workDir,\n })\n cancelSignal?.throwIfAborted()\n } catch (err) {\n if (err instanceof FrontendScaffoldError) {\n return {\n frontendCreationError: err.message,\n frontendPackageManager: resolvedPackageManager,\n studioPath,\n }\n }\n throw err\n }\n\n const frontendPath = path.join(workDir, FRONTEND_DIR)\n writeScaffoldEnv(\n path.join(frontendPath, '.env.local'),\n scaffoldEnv,\n `Website scaffold completed, but writing ./${FRONTEND_ENV_FILE} failed`,\n )\n\n let frontendDependenciesInstalled = resolvedPackageManager !== 'manual'\n let frontendDependencyError: string | undefined\n if (frontendDependenciesInstalled) {\n try {\n await installFrontendDeps({\n cancelSignal,\n dirName: FRONTEND_DIR,\n output,\n packageManager: resolvedPackageManager,\n workDir,\n })\n cancelSignal?.throwIfAborted()\n } catch (err) {\n if (!(err instanceof FrontendScaffoldError)) throw err\n frontendDependenciesInstalled = false\n frontendDependencyError = err.message\n }\n }\n\n return {\n frontendDependenciesInstalled,\n frontendDependencyError,\n frontendPackageManager: resolvedPackageManager,\n frontendPath,\n studioPath,\n }\n}\n\nfunction writeScaffoldEnv(\n envPath: string,\n values: Record<string, string>,\n errorContext: string,\n): void {\n const lines = [\n '# Added by `sanity new`. Keep this file out of git: it holds a live project token.',\n ...Object.entries(values).map(([key, value]) => `${key}=\"${value}\"`),\n ]\n try {\n writeFileSync(envPath, `${lines.join('\\n')}\\n`, 'utf8')\n } catch (err) {\n throw new Error(`${errorContext}: ${getErrorMessage(err)}`, {cause: err})\n }\n}\n"],"names":["writeFileSync","lstat","path","subdebug","getErrorMessage","frameworks","CLIInitStepCompleted","detectFrameworkRecord","dirIsEmptyOrNonExistent","getProjectDefaults","initStudio","resolvePackageManager","createFrontend","FrontendScaffoldError","installFrontendDeps","debug","STUDIO_DIR","FRONTEND_DIR","STUDIO_ENV_FILE","FRONTEND_ENV_FILE","STUDIO_PACKAGE_NAME","STUDIO_PACKAGE_MANAGERS","Set","isStudioScaffoldTargetAvailable","workDir","isScaffoldTargetAvailable","targetDir","targetPath","join","isDirectory","err","code","inspectScaffoldTargets","unavailableTarget","detectedFramework","frameworkList","rootPath","getUnavailableScaffoldTarget","createScaffoldEnv","dataset","projectId","token","SANITY_AUTH_TOKEN","SANITY_DATASET","SANITY_PROJECT_ID","scaffoldProject","cancelSignal","displayName","output","packageManager","telemetry","throwIfAborted","detected","studioPath","Error","resolvedPackageManager","interactive","options","autoUpdates","bare","datasetDefault","fromCreate","git","mcpMode","outputPath","has","undefined","project","skillsMode","template","typescript","unattended","trace","start","datasetName","defaults","isPlugin","isFirstProject","mcpConfigured","organizationId","preclaim","remoteTemplateInfo","sluggedName","workbench","complete","error","String","scaffoldEnv","writeScaffoldEnv","name","dirName","frontendCreationError","message","frontendPackageManager","frontendPath","frontendDependenciesInstalled","frontendDependencyError","envPath","values","errorContext","lines","Object","entries","map","key","value","cause"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/scaffold/scaffoldProject.ts"],"sourcesContent":["import {writeFileSync} from 'node:fs'\nimport {lstat} from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {type CLITelemetryStore, type Output, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {type Framework, frameworks} from '@vercel/frameworks'\n\nimport {CLIInitStepCompleted} from '../../telemetry/init.telemetry.js'\nimport {detectFrameworkRecord} from '../../util/detectFramework.js'\nimport {dirIsEmptyOrNonExistent} from '../../util/dirIsEmptyOrNonExistent.js'\nimport {getProjectDefaults} from '../../util/getProjectDefaults.js'\nimport {type PackageManager} from '../../util/packageManager/packageManagerChoice.js'\nimport {initStudio} from '../init/initStudio.js'\nimport {resolvePackageManager} from '../init/resolvePackageManager.js'\nimport {type InitOptions} from '../init/types.js'\nimport {createFrontend, FrontendScaffoldError, installFrontendDeps} from './createFrontend.js'\n\nconst debug = subdebug('scaffold')\n\nexport const STUDIO_DIR = 'sanity'\nexport const FRONTEND_DIR = 'web'\nexport const STUDIO_ENV_FILE = `${STUDIO_DIR}/.env.local`\nexport const FRONTEND_ENV_FILE = `${FRONTEND_DIR}/.env.local`\n\nconst STUDIO_PACKAGE_NAME = 'sanity-studio'\nconst STUDIO_PACKAGE_MANAGERS = new Set<PackageManager>(['npm', 'pnpm', 'yarn'])\n\nexport async function isStudioScaffoldTargetAvailable(workDir: string): Promise<boolean> {\n return isScaffoldTargetAvailable(workDir, STUDIO_DIR)\n}\n\nasync function isScaffoldTargetAvailable(workDir: string, targetDir: string): Promise<boolean> {\n const targetPath = path.join(workDir, targetDir)\n try {\n if (!(await lstat(targetPath)).isDirectory()) {\n return false\n }\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {\n throw err\n }\n }\n\n return dirIsEmptyOrNonExistent(targetPath)\n}\n\nasync function inspectScaffoldTargets(workDir: string) {\n if (!(await isStudioScaffoldTargetAvailable(workDir))) {\n return {unavailableTarget: STUDIO_DIR}\n }\n\n const detectedFramework = await detectFrameworkRecord({\n frameworkList: frameworks as readonly Framework[],\n rootPath: workDir,\n })\n if (!detectedFramework && !(await isScaffoldTargetAvailable(workDir, FRONTEND_DIR))) {\n return {unavailableTarget: FRONTEND_DIR}\n }\n\n return {detectedFramework}\n}\n\nexport async function getUnavailableScaffoldTarget(workDir: string): Promise<string | undefined> {\n const {unavailableTarget} = await inspectScaffoldTargets(workDir)\n return unavailableTarget\n}\n\nexport interface ScaffoldResult {\n studioPath: string\n\n detectedFramework?: string\n frontendCreationError?: string\n frontendDependenciesInstalled?: boolean\n frontendDependencyError?: string\n frontendPackageManager?: PackageManager\n frontendPath?: string\n}\n\nfunction createStudioEnv(dataset: string, projectId: string, token: string) {\n return {\n SANITY_AUTH_TOKEN: token,\n SANITY_DATASET: dataset,\n SANITY_PROJECT_ID: projectId,\n }\n}\n\nfunction createFrontendEnv(dataset: string, projectId: string) {\n return {\n NEXT_PUBLIC_SANITY_DATASET: dataset,\n NEXT_PUBLIC_SANITY_PROJECT_ID: projectId,\n }\n}\n\nexport async function scaffoldProject({\n cancelSignal,\n dataset,\n displayName,\n output,\n packageManager,\n projectId,\n telemetry,\n token,\n workDir,\n}: {\n cancelSignal?: AbortSignal\n dataset: string\n displayName: string\n output: Output\n packageManager?: PackageManager\n projectId: string\n telemetry: CLITelemetryStore\n token: string\n workDir: string\n}): Promise<ScaffoldResult> {\n cancelSignal?.throwIfAborted()\n const {detectedFramework: detected, unavailableTarget} = await inspectScaffoldTargets(workDir)\n const studioPath = path.join(workDir, STUDIO_DIR)\n if (unavailableTarget) {\n throw new Error(`./${unavailableTarget} is not an empty directory`)\n }\n\n const resolvedPackageManager = await resolvePackageManager({\n interactive: false,\n output,\n packageManager: packageManager as PackageManager,\n targetDir: workDir,\n })\n\n const options: InitOptions = {\n autoUpdates: true,\n bare: false,\n dataset,\n datasetDefault: true,\n fromCreate: false,\n git: false,\n mcpMode: 'skip',\n outputPath: studioPath,\n packageManager: STUDIO_PACKAGE_MANAGERS.has(resolvedPackageManager)\n ? (resolvedPackageManager as InitOptions['packageManager'])\n : undefined,\n project: projectId,\n skillsMode: 'skip',\n template: 'clean',\n typescript: true,\n unattended: true,\n }\n\n const trace = telemetry.trace(CLIInitStepCompleted)\n trace.start()\n try {\n // To avoid changing Studio initialization internals, we're deferring passing `cancelSignal`\n // until post `sanity new` launch.\n await initStudio({\n datasetName: dataset,\n defaults: await getProjectDefaults({isPlugin: false, workDir}),\n displayName,\n isFirstProject: false,\n mcpConfigured: [],\n options,\n organizationId: undefined,\n output,\n outputPath: studioPath,\n preclaim: true,\n projectId,\n remoteTemplateInfo: undefined,\n sluggedName: STUDIO_PACKAGE_NAME,\n trace,\n workbench: false,\n workDir,\n })\n trace.complete()\n } catch (err) {\n trace.error(err instanceof Error ? err : new Error(String(err)))\n throw err\n }\n\n cancelSignal?.throwIfAborted()\n writeScaffoldEnv(\n path.join(studioPath, '.env.local'),\n createStudioEnv(dataset, projectId, token),\n `Studio scaffold completed, but writing ./${STUDIO_ENV_FILE} failed`,\n 'it holds a live project token',\n )\n\n if (detected) {\n debug('Detected %s in %s, leaving the frontend alone', detected.name, workDir)\n return {\n detectedFramework: detected.name,\n studioPath,\n }\n }\n\n try {\n await createFrontend({\n cancelSignal,\n dirName: FRONTEND_DIR,\n output,\n packageManager: resolvedPackageManager,\n workDir,\n })\n cancelSignal?.throwIfAborted()\n } catch (err) {\n if (err instanceof FrontendScaffoldError) {\n return {\n frontendCreationError: err.message,\n frontendPackageManager: resolvedPackageManager,\n studioPath,\n }\n }\n throw err\n }\n\n const frontendPath = path.join(workDir, FRONTEND_DIR)\n writeScaffoldEnv(\n path.join(frontendPath, '.env.local'),\n createFrontendEnv(dataset, projectId),\n `Website scaffold completed, but writing ./${FRONTEND_ENV_FILE} failed`,\n 'it holds the project ID and dataset',\n )\n\n let frontendDependenciesInstalled = resolvedPackageManager !== 'manual'\n let frontendDependencyError: string | undefined\n if (frontendDependenciesInstalled) {\n try {\n await installFrontendDeps({\n cancelSignal,\n dirName: FRONTEND_DIR,\n output,\n packageManager: resolvedPackageManager,\n workDir,\n })\n cancelSignal?.throwIfAborted()\n } catch (err) {\n if (!(err instanceof FrontendScaffoldError)) throw err\n frontendDependenciesInstalled = false\n frontendDependencyError = err.message\n }\n }\n\n return {\n frontendDependenciesInstalled,\n frontendDependencyError,\n frontendPackageManager: resolvedPackageManager,\n frontendPath,\n studioPath,\n }\n}\n\nfunction writeScaffoldEnv(\n envPath: string,\n values: Record<string, string>,\n errorContext: string,\n gitignoreReason: string,\n): void {\n const lines = [\n `# Added by \\`sanity new\\`. Keep this file out of git: ${gitignoreReason}.`,\n ...Object.entries(values).map(([key, value]) => `${key}=\"${value}\"`),\n ]\n try {\n writeFileSync(envPath, `${lines.join('\\n')}\\n`, 'utf8')\n } catch (err) {\n throw new Error(`${errorContext}: ${getErrorMessage(err)}`, {cause: err})\n }\n}\n"],"names":["writeFileSync","lstat","path","subdebug","getErrorMessage","frameworks","CLIInitStepCompleted","detectFrameworkRecord","dirIsEmptyOrNonExistent","getProjectDefaults","initStudio","resolvePackageManager","createFrontend","FrontendScaffoldError","installFrontendDeps","debug","STUDIO_DIR","FRONTEND_DIR","STUDIO_ENV_FILE","FRONTEND_ENV_FILE","STUDIO_PACKAGE_NAME","STUDIO_PACKAGE_MANAGERS","Set","isStudioScaffoldTargetAvailable","workDir","isScaffoldTargetAvailable","targetDir","targetPath","join","isDirectory","err","code","inspectScaffoldTargets","unavailableTarget","detectedFramework","frameworkList","rootPath","getUnavailableScaffoldTarget","createStudioEnv","dataset","projectId","token","SANITY_AUTH_TOKEN","SANITY_DATASET","SANITY_PROJECT_ID","createFrontendEnv","NEXT_PUBLIC_SANITY_DATASET","NEXT_PUBLIC_SANITY_PROJECT_ID","scaffoldProject","cancelSignal","displayName","output","packageManager","telemetry","throwIfAborted","detected","studioPath","Error","resolvedPackageManager","interactive","options","autoUpdates","bare","datasetDefault","fromCreate","git","mcpMode","outputPath","has","undefined","project","skillsMode","template","typescript","unattended","trace","start","datasetName","defaults","isPlugin","isFirstProject","mcpConfigured","organizationId","preclaim","remoteTemplateInfo","sluggedName","workbench","complete","error","String","writeScaffoldEnv","name","dirName","frontendCreationError","message","frontendPackageManager","frontendPath","frontendDependenciesInstalled","frontendDependencyError","envPath","values","errorContext","gitignoreReason","lines","Object","entries","map","key","value","cause"],"mappings":"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"}
@@ -86,7 +86,7 @@ export class NewCommand extends SanityCommand {
86
86
  required: false
87
87
  })
88
88
  };
89
- static description = formatHelpDescription(`Sets up two folders here: ./${STUDIO_DIR}, a Studio where you write and edit your content, ` + `and ./${FRONTEND_DIR}, a Next.js website that reads it. Both are already connected to your ` + 'new project, so you can start them straight away. Use --no-scaffold if you just want the ' + 'project and nothing else.', `The project is real and works immediately, but it is only yours for ${CLAIM_WINDOW_HOURS} hours. Claim it with ` + 'a Sanity account before the deadline and everything you have built stays exactly as it is. ' + 'Claiming is free and takes about a minute. Miss the deadline and the project and its ' + 'content are deleted.', 'Two things to keep private: the claim link, because anyone who opens it becomes the owner, ' + `and the access token saved in ./${STUDIO_ENV_FILE} and ./${FRONTEND_ENV_FILE}, because it ` + 'can read and change everything in the project. Keep both env files out of git, and never ' + 'put the token in code that runs in the browser.', 'Run this command with --instructions for the full agent setup guide.');
89
+ static description = formatHelpDescription(`Sets up two folders here: ./${STUDIO_DIR}, a Studio where you write and edit your content, ` + `and ./${FRONTEND_DIR}, a Next.js website that reads it. Both are already connected to your ` + 'new project, so you can start them straight away. Use --no-scaffold if you just want the ' + 'project and nothing else.', `The project is real and works immediately, but it is only yours for ${CLAIM_WINDOW_HOURS} hours. Claim it with ` + 'a Sanity account before the deadline and everything you have built stays exactly as it is. ' + 'Claiming is free and takes about a minute. Miss the deadline and the project and its ' + 'content are deleted.', 'Two things to keep private: the claim link, because anyone who opens it becomes the owner, ' + `and the access token saved in ./${STUDIO_ENV_FILE}, because it can read and change ` + `everything in the project. ./${FRONTEND_ENV_FILE} has only the project ID and dataset. ` + 'Keep both env files out of git, and never put the token in code that runs in the browser.', 'Run this command with --instructions for the full agent setup guide.');
90
90
  static enableJsonFlag = true;
91
91
  static examples = [
92
92
  {
@@ -316,7 +316,6 @@ export class NewCommand extends SanityCommand {
316
316
  flow.line('The token signs you in: there is no account yet.');
317
317
  flow.gap();
318
318
  }
319
- flow.line('Your content is private until you claim, to read it, you need the token.');
320
319
  flow.line("Treat your token as a password and don't expose it publicly in your app.");
321
320
  flow.gap();
322
321
  flow.line('The claim link and token are printed above but you can recover them ' + `with ${styleText('cyan', 'sanity projects unclaimed')} before the timer runs out on ${formatClaimDeadline(project.expiresAt)}.`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/new.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {exitCodes} from '@sanity/cli-core'\nimport {SanityCommand} from '@sanity/cli-core/SanityCommand'\nimport {createFlow, input} from '@sanity/cli-core/ux'\n\nimport {\n FRONTEND_DIR,\n FRONTEND_ENV_FILE,\n getUnavailableScaffoldTarget,\n scaffoldProject,\n type ScaffoldResult,\n STUDIO_DIR,\n STUDIO_ENV_FILE,\n} from '../actions/scaffold/scaffoldProject.js'\nimport {type MintedProject, mintUnclaimedProject} from '../services/mintProject.js'\nimport {\n fetchNewInstructions,\n INSTRUCTIONS_URL,\n InstructionsUnavailableError,\n} from '../services/newInstructions.js'\nimport {formatClaimDeadline} from '../util/formatClaimDeadline.js'\nimport {CLAIM_WINDOW_HOURS, SANITY_NEW_URL} from '../util/mintProjectConstants.js'\nimport {renderNewCommandSplash} from '../util/newCommandSplash.js'\nimport {recordUnclaimedProject} from '../util/unclaimedProjects.js'\n\nconst DEFAULT_PROJECT_NAME = 'My Sanity project'\nconst HELP_DESCRIPTION_WIDTH = 78\n\n/**\n * Prepended to the fetched instructions so an agent cannot read this command's success as the\n * project already existing. The only addition to an otherwise verbatim document.\n */\nconst INSTRUCTIONS_HEADER = '# Nothing has been created yet — follow these steps.'\n\nfunction formatHelpDescription(...paragraphs: string[]): string {\n return paragraphs\n .map((paragraph) => {\n const lines: string[] = []\n let line = ''\n\n for (const word of paragraph.split(/\\s+/u)) {\n if (!line || line.length + word.length + 1 <= HELP_DESCRIPTION_WIDTH) {\n line = line ? `${line} ${word}` : word\n } else {\n lines.push(line)\n line = word\n }\n }\n\n if (line) lines.push(line)\n return lines.join('\\n')\n })\n .join('\\n\\n')\n}\n\nconst FRONTEND_DEV_COMMANDS: Record<\n NonNullable<ScaffoldResult['frontendPackageManager']>,\n string\n> = {\n bun: 'bun dev',\n manual: 'npm run dev',\n npm: 'npm run dev',\n pnpm: 'pnpm dev',\n yarn: 'yarn dev',\n}\n\nfunction frontendDevCommand(packageManager: ScaffoldResult['frontendPackageManager']): string {\n return packageManager ? FRONTEND_DEV_COMMANDS[packageManager] : 'npm run dev'\n}\n\nfunction frontendInstallCommand(packageManager: ScaffoldResult['frontendPackageManager']): string {\n switch (packageManager) {\n case 'bun': {\n return 'bun add next-sanity'\n }\n case 'pnpm': {\n return 'pnpm add --save-prod next-sanity'\n }\n case 'yarn': {\n return 'yarn add next-sanity'\n }\n default: {\n return 'npm install next-sanity'\n }\n }\n}\n\nexport interface NewProjectResult {\n apiHost: string\n claimApiUrl: string\n claimToken: string\n claimUrl: string\n dataset: string\n expiresAt: string\n projectId: string\n terms: {\n notice: string\n url: string\n }\n token: string\n}\n\nfunction toResult(project: MintedProject): NewProjectResult {\n return {\n apiHost: project.apiHost,\n claimApiUrl: project.claimApiUrl,\n claimToken: project.claimToken,\n claimUrl: project.claimUrl,\n dataset: project.datasetName,\n expiresAt: project.expiresAt,\n projectId: project.resourceId,\n terms: {notice: project.termsNotice, url: project.termsUrl},\n token: project.token,\n }\n}\n\nexport class NewCommand extends SanityCommand<typeof NewCommand> {\n static override args = {\n projectName: Args.string({\n description: 'Display name for the new project',\n required: false,\n }),\n }\n\n static override description = formatHelpDescription(\n `Sets up two folders here: ./${STUDIO_DIR}, a Studio where you write and edit your content, ` +\n `and ./${FRONTEND_DIR}, a Next.js website that reads it. Both are already connected to your ` +\n 'new project, so you can start them straight away. Use --no-scaffold if you just want the ' +\n 'project and nothing else.',\n `The project is real and works immediately, but it is only yours for ${CLAIM_WINDOW_HOURS} hours. Claim it with ` +\n 'a Sanity account before the deadline and everything you have built stays exactly as it is. ' +\n 'Claiming is free and takes about a minute. Miss the deadline and the project and its ' +\n 'content are deleted.',\n 'Two things to keep private: the claim link, because anyone who opens it becomes the owner, ' +\n `and the access token saved in ./${STUDIO_ENV_FILE} and ./${FRONTEND_ENV_FILE}, because it ` +\n 'can read and change everything in the project. Keep both env files out of git, and never ' +\n 'put the token in code that runs in the browser.',\n 'Run this command with --instructions for the full agent setup guide.',\n )\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Create a project with a Studio and a website',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"My New Project\"',\n description: 'Create a project called \"My New Project\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --yes',\n description: 'Create a project without being asked anything',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --no-scaffold',\n description: 'Create the project only, with no Studio or website',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --json',\n description: 'Create a project and print its details as JSON',\n },\n\n {\n command: '<%= config.bin %> <%= command.id %> --instructions',\n description: 'Print the full setup guide for an AI agent, without creating anything',\n },\n ]\n\n static override flags = {\n instructions: Flags.boolean({\n default: false,\n description: `Print the full setup guide from ${SANITY_NEW_URL} and exit, creating nothing`,\n }),\n scaffold: Flags.boolean({\n allowNo: true,\n default: true,\n description: `Set up a Studio in ./${STUDIO_DIR} and a Next.js website in ./${FRONTEND_DIR} (on by default)`,\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description: `Skip prompts and use defaults (project: \"${DEFAULT_PROJECT_NAME}\")`,\n }),\n }\n\n static override summary = `Create a Sanity project without an account, and claim it within ${CLAIM_WINDOW_HOURS} hours to keep it.`\n\n public async run(): Promise<NewProjectResult | undefined> {\n const {output} = this\n const json = this.jsonEnabled()\n const flow = createFlow(output.log)\n const invoked = [this.config.bin, ...(this.id?.split(':') ?? [])].join(' ')\n const cwd = process.cwd()\n\n // Runs before every precondition and side effect: this flag creates nothing.\n if (this.flags.instructions) {\n // oclif's `exclusive` does not cover the json flag added by enableJsonFlag, so guard it here.\n if (json) {\n throw new CLIError('--instructions cannot be combined with --json.', {\n code: 'INSTRUCTIONS_JSON_CONFLICT',\n exit: exitCodes.USAGE_ERROR,\n suggestions: [\n `Run \\`${invoked} --instructions\\` for the setup guide as markdown`,\n `Or run \\`${invoked} --json\\` to create a project and print its details as JSON`,\n ],\n })\n }\n\n await this.printInstructions()\n return undefined\n }\n\n const unavailableScaffoldTarget =\n !json && this.flags.scaffold ? await getUnavailableScaffoldTarget(cwd) : undefined\n if (unavailableScaffoldTarget) {\n throw new CLIError(\n `./${unavailableScaffoldTarget} is not an empty directory. No project was created.`,\n {\n code:\n unavailableScaffoldTarget === STUDIO_DIR\n ? 'EXISTING_STUDIO_DIRECTORY'\n : 'EXISTING_FRONTEND_DIRECTORY',\n exit: exitCodes.RUNTIME_ERROR,\n suggestions: [\n `Run this command where ./${unavailableScaffoldTarget} does not exist or is an empty directory`,\n `Or run \\`${invoked} --no-scaffold\\` to create the project without changing ./${unavailableScaffoldTarget}`,\n ],\n },\n )\n }\n\n if (!json) {\n renderNewCommandSplash(output.log)\n flow.intro('Setting up your Sanity project.')\n flow.gap()\n\n if (!this.isUnattended()) {\n flow.note(\n `${styleText('cyan', `${invoked} --yes`)} for a non-interactive flow with defaults.`,\n )\n flow.gap()\n }\n }\n\n let displayName = this.args.projectName?.trim()\n if (!displayName && this.isUnattended()) {\n displayName = DEFAULT_PROJECT_NAME\n } else if (!displayName) {\n displayName =\n (\n await input({\n default: DEFAULT_PROJECT_NAME,\n message: 'Project name',\n })\n ).trim() || DEFAULT_PROJECT_NAME\n }\n\n const spin = json ? undefined : flow.spin('Creating your project...')\n let project: MintedProject\n try {\n project = await mintUnclaimedProject({displayName})\n } catch (err) {\n spin?.fail('Creating your project failed.')\n throw err\n }\n\n const recorded = recordUnclaimedProject(project)\n spin?.succeed(`Created \"${displayName}\"`)\n\n if (!json) {\n flow.result(`Project ID: ${styleText('cyan', project.resourceId)}`)\n flow.result(`Dataset: ${styleText('cyan', project.datasetName)} (where your content lives)`)\n flow.result(`Token: ${styleText('cyan', project.token)}`)\n flow.link(project.claimUrl, {label: 'Claim link:'})\n flow.gap()\n flow.highlight(\n `Claim your project by ${styleText('yellow', formatClaimDeadline(project.expiresAt))} to avoid losing it.`,\n )\n flow.gap()\n flow.line('To use the Sanity CLI before claiming use your token by setting')\n flow.command(`SANITY_AUTH_TOKEN=\"${project.token}\" sanity \"command\"`)\n flow.gap()\n flow.note(\n styleText(\n 'dim',\n 'If you are an agent: give this claim URL to the person you are working for. They have ' +\n 'to open it themselves before the deadline.',\n ),\n )\n flow.gap()\n }\n\n const studioUrl =\n `http://localhost:3333/#token=${encodeURIComponent(project.token)}` +\n `&claim=${encodeURIComponent(project.claimUrl)}`\n\n const printStudioInstructions = () => {\n flow.highlight('Start your Studio:')\n flow.gap()\n flow.command(`cd ${STUDIO_DIR} && npx sanity@latest dev`)\n flow.gap()\n flow.link(studioUrl, {label: 'Then open this link:'})\n flow.gap()\n flow.line('The token signs you in: there is no account yet.')\n }\n const printWebsiteInstructions = (packageManager: ScaffoldResult['frontendPackageManager']) => {\n flow.highlight('In a separate terminal, start your website:')\n flow.gap()\n flow.command(`cd ${FRONTEND_DIR} && ${frontendDevCommand(packageManager)}`)\n flow.gap()\n flow.link('http://localhost:3000', {label: 'Then open this link:'})\n }\n\n let scaffold: ScaffoldResult | undefined\n if (!json && this.flags.scaffold) {\n const scaffoldController = new AbortController()\n const abortScaffold = () => scaffoldController.abort(new Error('SIGINT'))\n process.once('SIGINT', abortScaffold)\n try {\n scaffold = await scaffoldProject({\n cancelSignal: scaffoldController.signal,\n dataset: project.datasetName,\n displayName,\n output,\n projectId: project.resourceId,\n telemetry: this.telemetry,\n token: project.token,\n workDir: cwd,\n })\n scaffoldController.signal.throwIfAborted()\n } catch (err) {\n if (\n scaffoldController.signal.aborted ||\n (err instanceof Error && err.message === 'SIGINT')\n ) {\n throw err\n }\n // Scaffolding is best-effort and may leave files or directories behind when it fails.\n // Partial filesystem state does not prove the scaffold is runnable, so report the failure,\n // continue only with the project/token/claim handoff below, and do not attempt cleanup.\n flow.note(`Automatic setup did not finish: ${err instanceof Error ? err.message : err}`)\n flow.line('The project was created. You do not need to create another one.')\n flow.gap()\n } finally {\n process.off('SIGINT', abortScaffold)\n }\n }\n\n if (scaffold) {\n if (scaffold.frontendPath) {\n flow.result('Created two folders')\n flow.line(`./${STUDIO_DIR}: your Studio, where you write and edit content`)\n flow.line(`./${FRONTEND_DIR}: your website, a Next.js app that reads it`)\n flow.gap()\n printStudioInstructions()\n if (scaffold.frontendDependenciesInstalled === false) {\n flow.gap()\n if (scaffold.frontendDependencyError) {\n flow.line(`Installing website dependencies failed: ${scaffold.frontendDependencyError}`)\n flow.gap()\n }\n flow.highlight('Finish installing your website dependencies')\n flow.gap()\n flow.command(\n `cd ${FRONTEND_DIR} && ${frontendInstallCommand(scaffold.frontendPackageManager)}`,\n )\n }\n flow.gap()\n printWebsiteInstructions(scaffold.frontendPackageManager)\n } else if (scaffold.detectedFramework) {\n flow.result(`Created ./${STUDIO_DIR} for your existing ${scaffold.detectedFramework} app`)\n flow.line(`./${STUDIO_DIR}: your Studio, where you write and edit content`)\n flow.line(`Your existing ${scaffold.detectedFramework} frontend was left unchanged.`)\n flow.gap()\n printStudioInstructions()\n } else {\n flow.result(`Created ./${STUDIO_DIR}`)\n flow.line(`./${STUDIO_DIR}: your Studio, where you write and edit content`)\n flow.line(\n `The website was not created: ${scaffold.frontendCreationError ?? 'automatic setup did not finish'}`,\n )\n flow.gap()\n printStudioInstructions()\n }\n flow.gap()\n }\n\n if (recorded === false && !json) {\n flow.note('The local recovery record was not saved.')\n flow.line('Keep the claim URL and access token from this output.')\n flow.gap()\n }\n\n if (!json) {\n if (!scaffold && !this.flags.scaffold) {\n flow.result('Project created without scaffolding')\n flow.line(\n 'No folders or env files were created. Use the project ID and dataset above in your own setup.',\n )\n flow.gap()\n flow.link(studioUrl, {\n label: 'Once a Studio is running on http://localhost:3333, sign in with:',\n })\n flow.gap()\n flow.line('The token signs you in: there is no account yet.')\n flow.gap()\n }\n\n flow.line('Your content is private until you claim, to read it, you need the token.')\n flow.line(\"Treat your token as a password and don't expose it publicly in your app.\")\n flow.gap()\n flow.line(\n 'The claim link and token are printed above but you can recover them ' +\n `with ${styleText('cyan', 'sanity projects unclaimed')} before the timer runs out on ${formatClaimDeadline(project.expiresAt)}.`,\n )\n flow.gap()\n flow.line(project.termsNotice)\n flow.link(project.termsUrl, {label: 'Terms of Service:'})\n flow.gap()\n flow.line('For more information on how claiming works or how to build your app')\n flow.link(SANITY_NEW_URL, {label: 'visit', outro: true})\n }\n\n return toResult(project)\n }\n\n /**\n * Dumps the guide from sanity.new verbatim, so an agent gets the whole document rather than a\n * summary produced by whatever fetched it.\n */\n private async printInstructions(): Promise<void> {\n let instructions: string\n try {\n instructions = await fetchNewInstructions()\n } catch (err) {\n if (err instanceof InstructionsUnavailableError) {\n throw new CLIError(err.message, {\n code: 'INSTRUCTIONS_UNAVAILABLE',\n exit: exitCodes.RUNTIME_ERROR,\n suggestions: [\n `Fetch them directly: curl -sSL ${INSTRUCTIONS_URL}`,\n `Or open ${SANITY_NEW_URL} in a browser`,\n ],\n })\n }\n throw err\n }\n\n this.output.log(`${INSTRUCTIONS_HEADER}\\n\\n${instructions}`)\n }\n}\n"],"names":["styleText","Args","Flags","CLIError","exitCodes","SanityCommand","createFlow","input","FRONTEND_DIR","FRONTEND_ENV_FILE","getUnavailableScaffoldTarget","scaffoldProject","STUDIO_DIR","STUDIO_ENV_FILE","mintUnclaimedProject","fetchNewInstructions","INSTRUCTIONS_URL","InstructionsUnavailableError","formatClaimDeadline","CLAIM_WINDOW_HOURS","SANITY_NEW_URL","renderNewCommandSplash","recordUnclaimedProject","DEFAULT_PROJECT_NAME","HELP_DESCRIPTION_WIDTH","INSTRUCTIONS_HEADER","formatHelpDescription","paragraphs","map","paragraph","lines","line","word","split","length","push","join","FRONTEND_DEV_COMMANDS","bun","manual","npm","pnpm","yarn","frontendDevCommand","packageManager","frontendInstallCommand","toResult","project","apiHost","claimApiUrl","claimToken","claimUrl","dataset","datasetName","expiresAt","projectId","resourceId","terms","notice","termsNotice","url","termsUrl","token","NewCommand","args","projectName","string","description","required","enableJsonFlag","examples","command","flags","instructions","boolean","default","scaffold","allowNo","yes","char","summary","run","output","json","jsonEnabled","flow","log","invoked","config","bin","id","cwd","process","code","exit","USAGE_ERROR","suggestions","printInstructions","undefined","unavailableScaffoldTarget","RUNTIME_ERROR","intro","gap","isUnattended","note","displayName","trim","message","spin","err","fail","recorded","succeed","result","link","label","highlight","studioUrl","encodeURIComponent","printStudioInstructions","printWebsiteInstructions","scaffoldController","AbortController","abortScaffold","abort","Error","once","cancelSignal","signal","telemetry","workDir","throwIfAborted","aborted","off","frontendPath","frontendDependenciesInstalled","frontendDependencyError","frontendPackageManager","detectedFramework","frontendCreationError","outro"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/commands/new.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {exitCodes} from '@sanity/cli-core'\nimport {SanityCommand} from '@sanity/cli-core/SanityCommand'\nimport {createFlow, input} from '@sanity/cli-core/ux'\n\nimport {\n FRONTEND_DIR,\n FRONTEND_ENV_FILE,\n getUnavailableScaffoldTarget,\n scaffoldProject,\n type ScaffoldResult,\n STUDIO_DIR,\n STUDIO_ENV_FILE,\n} from '../actions/scaffold/scaffoldProject.js'\nimport {type MintedProject, mintUnclaimedProject} from '../services/mintProject.js'\nimport {\n fetchNewInstructions,\n INSTRUCTIONS_URL,\n InstructionsUnavailableError,\n} from '../services/newInstructions.js'\nimport {formatClaimDeadline} from '../util/formatClaimDeadline.js'\nimport {CLAIM_WINDOW_HOURS, SANITY_NEW_URL} from '../util/mintProjectConstants.js'\nimport {renderNewCommandSplash} from '../util/newCommandSplash.js'\nimport {recordUnclaimedProject} from '../util/unclaimedProjects.js'\n\nconst DEFAULT_PROJECT_NAME = 'My Sanity project'\nconst HELP_DESCRIPTION_WIDTH = 78\n\n/**\n * Prepended to the fetched instructions so an agent cannot read this command's success as the\n * project already existing. The only addition to an otherwise verbatim document.\n */\nconst INSTRUCTIONS_HEADER = '# Nothing has been created yet — follow these steps.'\n\nfunction formatHelpDescription(...paragraphs: string[]): string {\n return paragraphs\n .map((paragraph) => {\n const lines: string[] = []\n let line = ''\n\n for (const word of paragraph.split(/\\s+/u)) {\n if (!line || line.length + word.length + 1 <= HELP_DESCRIPTION_WIDTH) {\n line = line ? `${line} ${word}` : word\n } else {\n lines.push(line)\n line = word\n }\n }\n\n if (line) lines.push(line)\n return lines.join('\\n')\n })\n .join('\\n\\n')\n}\n\nconst FRONTEND_DEV_COMMANDS: Record<\n NonNullable<ScaffoldResult['frontendPackageManager']>,\n string\n> = {\n bun: 'bun dev',\n manual: 'npm run dev',\n npm: 'npm run dev',\n pnpm: 'pnpm dev',\n yarn: 'yarn dev',\n}\n\nfunction frontendDevCommand(packageManager: ScaffoldResult['frontendPackageManager']): string {\n return packageManager ? FRONTEND_DEV_COMMANDS[packageManager] : 'npm run dev'\n}\n\nfunction frontendInstallCommand(packageManager: ScaffoldResult['frontendPackageManager']): string {\n switch (packageManager) {\n case 'bun': {\n return 'bun add next-sanity'\n }\n case 'pnpm': {\n return 'pnpm add --save-prod next-sanity'\n }\n case 'yarn': {\n return 'yarn add next-sanity'\n }\n default: {\n return 'npm install next-sanity'\n }\n }\n}\n\nexport interface NewProjectResult {\n apiHost: string\n claimApiUrl: string\n claimToken: string\n claimUrl: string\n dataset: string\n expiresAt: string\n projectId: string\n terms: {\n notice: string\n url: string\n }\n token: string\n}\n\nfunction toResult(project: MintedProject): NewProjectResult {\n return {\n apiHost: project.apiHost,\n claimApiUrl: project.claimApiUrl,\n claimToken: project.claimToken,\n claimUrl: project.claimUrl,\n dataset: project.datasetName,\n expiresAt: project.expiresAt,\n projectId: project.resourceId,\n terms: {notice: project.termsNotice, url: project.termsUrl},\n token: project.token,\n }\n}\n\nexport class NewCommand extends SanityCommand<typeof NewCommand> {\n static override args = {\n projectName: Args.string({\n description: 'Display name for the new project',\n required: false,\n }),\n }\n\n static override description = formatHelpDescription(\n `Sets up two folders here: ./${STUDIO_DIR}, a Studio where you write and edit your content, ` +\n `and ./${FRONTEND_DIR}, a Next.js website that reads it. Both are already connected to your ` +\n 'new project, so you can start them straight away. Use --no-scaffold if you just want the ' +\n 'project and nothing else.',\n `The project is real and works immediately, but it is only yours for ${CLAIM_WINDOW_HOURS} hours. Claim it with ` +\n 'a Sanity account before the deadline and everything you have built stays exactly as it is. ' +\n 'Claiming is free and takes about a minute. Miss the deadline and the project and its ' +\n 'content are deleted.',\n 'Two things to keep private: the claim link, because anyone who opens it becomes the owner, ' +\n `and the access token saved in ./${STUDIO_ENV_FILE}, because it can read and change ` +\n `everything in the project. ./${FRONTEND_ENV_FILE} has only the project ID and dataset. ` +\n 'Keep both env files out of git, and never put the token in code that runs in the browser.',\n 'Run this command with --instructions for the full agent setup guide.',\n )\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Create a project with a Studio and a website',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"My New Project\"',\n description: 'Create a project called \"My New Project\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --yes',\n description: 'Create a project without being asked anything',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --no-scaffold',\n description: 'Create the project only, with no Studio or website',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --json',\n description: 'Create a project and print its details as JSON',\n },\n\n {\n command: '<%= config.bin %> <%= command.id %> --instructions',\n description: 'Print the full setup guide for an AI agent, without creating anything',\n },\n ]\n\n static override flags = {\n instructions: Flags.boolean({\n default: false,\n description: `Print the full setup guide from ${SANITY_NEW_URL} and exit, creating nothing`,\n }),\n scaffold: Flags.boolean({\n allowNo: true,\n default: true,\n description: `Set up a Studio in ./${STUDIO_DIR} and a Next.js website in ./${FRONTEND_DIR} (on by default)`,\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description: `Skip prompts and use defaults (project: \"${DEFAULT_PROJECT_NAME}\")`,\n }),\n }\n\n static override summary = `Create a Sanity project without an account, and claim it within ${CLAIM_WINDOW_HOURS} hours to keep it.`\n\n public async run(): Promise<NewProjectResult | undefined> {\n const {output} = this\n const json = this.jsonEnabled()\n const flow = createFlow(output.log)\n const invoked = [this.config.bin, ...(this.id?.split(':') ?? [])].join(' ')\n const cwd = process.cwd()\n\n // Runs before every precondition and side effect: this flag creates nothing.\n if (this.flags.instructions) {\n // oclif's `exclusive` does not cover the json flag added by enableJsonFlag, so guard it here.\n if (json) {\n throw new CLIError('--instructions cannot be combined with --json.', {\n code: 'INSTRUCTIONS_JSON_CONFLICT',\n exit: exitCodes.USAGE_ERROR,\n suggestions: [\n `Run \\`${invoked} --instructions\\` for the setup guide as markdown`,\n `Or run \\`${invoked} --json\\` to create a project and print its details as JSON`,\n ],\n })\n }\n\n await this.printInstructions()\n return undefined\n }\n\n const unavailableScaffoldTarget =\n !json && this.flags.scaffold ? await getUnavailableScaffoldTarget(cwd) : undefined\n if (unavailableScaffoldTarget) {\n throw new CLIError(\n `./${unavailableScaffoldTarget} is not an empty directory. No project was created.`,\n {\n code:\n unavailableScaffoldTarget === STUDIO_DIR\n ? 'EXISTING_STUDIO_DIRECTORY'\n : 'EXISTING_FRONTEND_DIRECTORY',\n exit: exitCodes.RUNTIME_ERROR,\n suggestions: [\n `Run this command where ./${unavailableScaffoldTarget} does not exist or is an empty directory`,\n `Or run \\`${invoked} --no-scaffold\\` to create the project without changing ./${unavailableScaffoldTarget}`,\n ],\n },\n )\n }\n\n if (!json) {\n renderNewCommandSplash(output.log)\n flow.intro('Setting up your Sanity project.')\n flow.gap()\n\n if (!this.isUnattended()) {\n flow.note(\n `${styleText('cyan', `${invoked} --yes`)} for a non-interactive flow with defaults.`,\n )\n flow.gap()\n }\n }\n\n let displayName = this.args.projectName?.trim()\n if (!displayName && this.isUnattended()) {\n displayName = DEFAULT_PROJECT_NAME\n } else if (!displayName) {\n displayName =\n (\n await input({\n default: DEFAULT_PROJECT_NAME,\n message: 'Project name',\n })\n ).trim() || DEFAULT_PROJECT_NAME\n }\n\n const spin = json ? undefined : flow.spin('Creating your project...')\n let project: MintedProject\n try {\n project = await mintUnclaimedProject({displayName})\n } catch (err) {\n spin?.fail('Creating your project failed.')\n throw err\n }\n\n const recorded = recordUnclaimedProject(project)\n spin?.succeed(`Created \"${displayName}\"`)\n\n if (!json) {\n flow.result(`Project ID: ${styleText('cyan', project.resourceId)}`)\n flow.result(`Dataset: ${styleText('cyan', project.datasetName)} (where your content lives)`)\n flow.result(`Token: ${styleText('cyan', project.token)}`)\n flow.link(project.claimUrl, {label: 'Claim link:'})\n flow.gap()\n flow.highlight(\n `Claim your project by ${styleText('yellow', formatClaimDeadline(project.expiresAt))} to avoid losing it.`,\n )\n flow.gap()\n flow.line('To use the Sanity CLI before claiming use your token by setting')\n flow.command(`SANITY_AUTH_TOKEN=\"${project.token}\" sanity \"command\"`)\n flow.gap()\n flow.note(\n styleText(\n 'dim',\n 'If you are an agent: give this claim URL to the person you are working for. They have ' +\n 'to open it themselves before the deadline.',\n ),\n )\n flow.gap()\n }\n\n const studioUrl =\n `http://localhost:3333/#token=${encodeURIComponent(project.token)}` +\n `&claim=${encodeURIComponent(project.claimUrl)}`\n\n const printStudioInstructions = () => {\n flow.highlight('Start your Studio:')\n flow.gap()\n flow.command(`cd ${STUDIO_DIR} && npx sanity@latest dev`)\n flow.gap()\n flow.link(studioUrl, {label: 'Then open this link:'})\n flow.gap()\n flow.line('The token signs you in: there is no account yet.')\n }\n const printWebsiteInstructions = (packageManager: ScaffoldResult['frontendPackageManager']) => {\n flow.highlight('In a separate terminal, start your website:')\n flow.gap()\n flow.command(`cd ${FRONTEND_DIR} && ${frontendDevCommand(packageManager)}`)\n flow.gap()\n flow.link('http://localhost:3000', {label: 'Then open this link:'})\n }\n\n let scaffold: ScaffoldResult | undefined\n if (!json && this.flags.scaffold) {\n const scaffoldController = new AbortController()\n const abortScaffold = () => scaffoldController.abort(new Error('SIGINT'))\n process.once('SIGINT', abortScaffold)\n try {\n scaffold = await scaffoldProject({\n cancelSignal: scaffoldController.signal,\n dataset: project.datasetName,\n displayName,\n output,\n projectId: project.resourceId,\n telemetry: this.telemetry,\n token: project.token,\n workDir: cwd,\n })\n scaffoldController.signal.throwIfAborted()\n } catch (err) {\n if (\n scaffoldController.signal.aborted ||\n (err instanceof Error && err.message === 'SIGINT')\n ) {\n throw err\n }\n // Scaffolding is best-effort and may leave files or directories behind when it fails.\n // Partial filesystem state does not prove the scaffold is runnable, so report the failure,\n // continue only with the project/token/claim handoff below, and do not attempt cleanup.\n flow.note(`Automatic setup did not finish: ${err instanceof Error ? err.message : err}`)\n flow.line('The project was created. You do not need to create another one.')\n flow.gap()\n } finally {\n process.off('SIGINT', abortScaffold)\n }\n }\n\n if (scaffold) {\n if (scaffold.frontendPath) {\n flow.result('Created two folders')\n flow.line(`./${STUDIO_DIR}: your Studio, where you write and edit content`)\n flow.line(`./${FRONTEND_DIR}: your website, a Next.js app that reads it`)\n flow.gap()\n printStudioInstructions()\n if (scaffold.frontendDependenciesInstalled === false) {\n flow.gap()\n if (scaffold.frontendDependencyError) {\n flow.line(`Installing website dependencies failed: ${scaffold.frontendDependencyError}`)\n flow.gap()\n }\n flow.highlight('Finish installing your website dependencies')\n flow.gap()\n flow.command(\n `cd ${FRONTEND_DIR} && ${frontendInstallCommand(scaffold.frontendPackageManager)}`,\n )\n }\n flow.gap()\n printWebsiteInstructions(scaffold.frontendPackageManager)\n } else if (scaffold.detectedFramework) {\n flow.result(`Created ./${STUDIO_DIR} for your existing ${scaffold.detectedFramework} app`)\n flow.line(`./${STUDIO_DIR}: your Studio, where you write and edit content`)\n flow.line(`Your existing ${scaffold.detectedFramework} frontend was left unchanged.`)\n flow.gap()\n printStudioInstructions()\n } else {\n flow.result(`Created ./${STUDIO_DIR}`)\n flow.line(`./${STUDIO_DIR}: your Studio, where you write and edit content`)\n flow.line(\n `The website was not created: ${scaffold.frontendCreationError ?? 'automatic setup did not finish'}`,\n )\n flow.gap()\n printStudioInstructions()\n }\n flow.gap()\n }\n\n if (recorded === false && !json) {\n flow.note('The local recovery record was not saved.')\n flow.line('Keep the claim URL and access token from this output.')\n flow.gap()\n }\n\n if (!json) {\n if (!scaffold && !this.flags.scaffold) {\n flow.result('Project created without scaffolding')\n flow.line(\n 'No folders or env files were created. Use the project ID and dataset above in your own setup.',\n )\n flow.gap()\n flow.link(studioUrl, {\n label: 'Once a Studio is running on http://localhost:3333, sign in with:',\n })\n flow.gap()\n flow.line('The token signs you in: there is no account yet.')\n flow.gap()\n }\n\n flow.line(\"Treat your token as a password and don't expose it publicly in your app.\")\n flow.gap()\n flow.line(\n 'The claim link and token are printed above but you can recover them ' +\n `with ${styleText('cyan', 'sanity projects unclaimed')} before the timer runs out on ${formatClaimDeadline(project.expiresAt)}.`,\n )\n flow.gap()\n flow.line(project.termsNotice)\n flow.link(project.termsUrl, {label: 'Terms of Service:'})\n flow.gap()\n flow.line('For more information on how claiming works or how to build your app')\n flow.link(SANITY_NEW_URL, {label: 'visit', outro: true})\n }\n\n return toResult(project)\n }\n\n /**\n * Dumps the guide from sanity.new verbatim, so an agent gets the whole document rather than a\n * summary produced by whatever fetched it.\n */\n private async printInstructions(): Promise<void> {\n let instructions: string\n try {\n instructions = await fetchNewInstructions()\n } catch (err) {\n if (err instanceof InstructionsUnavailableError) {\n throw new CLIError(err.message, {\n code: 'INSTRUCTIONS_UNAVAILABLE',\n exit: exitCodes.RUNTIME_ERROR,\n suggestions: [\n `Fetch them directly: curl -sSL ${INSTRUCTIONS_URL}`,\n `Or open ${SANITY_NEW_URL} in a browser`,\n ],\n })\n }\n throw err\n }\n\n this.output.log(`${INSTRUCTIONS_HEADER}\\n\\n${instructions}`)\n }\n}\n"],"names":["styleText","Args","Flags","CLIError","exitCodes","SanityCommand","createFlow","input","FRONTEND_DIR","FRONTEND_ENV_FILE","getUnavailableScaffoldTarget","scaffoldProject","STUDIO_DIR","STUDIO_ENV_FILE","mintUnclaimedProject","fetchNewInstructions","INSTRUCTIONS_URL","InstructionsUnavailableError","formatClaimDeadline","CLAIM_WINDOW_HOURS","SANITY_NEW_URL","renderNewCommandSplash","recordUnclaimedProject","DEFAULT_PROJECT_NAME","HELP_DESCRIPTION_WIDTH","INSTRUCTIONS_HEADER","formatHelpDescription","paragraphs","map","paragraph","lines","line","word","split","length","push","join","FRONTEND_DEV_COMMANDS","bun","manual","npm","pnpm","yarn","frontendDevCommand","packageManager","frontendInstallCommand","toResult","project","apiHost","claimApiUrl","claimToken","claimUrl","dataset","datasetName","expiresAt","projectId","resourceId","terms","notice","termsNotice","url","termsUrl","token","NewCommand","args","projectName","string","description","required","enableJsonFlag","examples","command","flags","instructions","boolean","default","scaffold","allowNo","yes","char","summary","run","output","json","jsonEnabled","flow","log","invoked","config","bin","id","cwd","process","code","exit","USAGE_ERROR","suggestions","printInstructions","undefined","unavailableScaffoldTarget","RUNTIME_ERROR","intro","gap","isUnattended","note","displayName","trim","message","spin","err","fail","recorded","succeed","result","link","label","highlight","studioUrl","encodeURIComponent","printStudioInstructions","printWebsiteInstructions","scaffoldController","AbortController","abortScaffold","abort","Error","once","cancelSignal","signal","telemetry","workDir","throwIfAborted","aborted","off","frontendPath","frontendDependenciesInstalled","frontendDependencyError","frontendPackageManager","detectedFramework","frontendCreationError","outro"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/server/devServer.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {\n extendViteConfigWithUserConfig,\n getViteConfig,\n writeSanityRuntime,\n} from '@sanity/cli-build/_internal/build'\nimport {\n getAppEnvironmentVariables,\n getStudioEnvironmentVariables,\n} from '@sanity/cli-build/_internal/env'\nimport {CliConfig, getCliTelemetry, type UserViteConfig} from '@sanity/cli-core'\nimport {type WorkbenchExposes} from '@sanity/workbench-cli/build'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport {type FSWatcher} from 'chokidar'\nimport {createServer, type InlineConfig, type ViteDevServer} from 'vite'\n\nimport {serverDebug} from './serverDebug.js'\nimport {sanityTypegenPlugin} from './vite/plugin-typegen.js'\n\nconst debug = serverDebug.extend('dev')\n\nexport interface DevServerOptions {\n basePath: string\n cwd: string\n httpPort: number\n\n reactCompiler: boolean | ReactCompilerConfig | undefined\n reactStrictMode: boolean | undefined\n\n staticPath: string\n\n appTitle?: string\n /** Enable Vite's experimental bundled dev mode (`experimental.bundledDev`). */\n bundledDev?: boolean\n entry?: string\n exposes?: WorkbenchExposes\n httpHost?: string\n isApp?: boolean\n isWorkbenchApp?: boolean\n projectName?: string\n schemaExtraction?: CliConfig['schemaExtraction']\n typegen?: CliConfig['typegen']\n vite?: UserViteConfig\n /** The workbench app's bus identity (`__SANITY_APP_ID__`). */\n workbenchAppId?: string\n}\n\ninterface DevServer {\n close(): Promise<void>\n server: ViteDevServer\n\n watcher?: FSWatcher\n}\n\nexport async function startDevServer(options: DevServerOptions): Promise<DevServer> {\n const {\n appTitle,\n basePath,\n bundledDev,\n cwd,\n entry,\n exposes,\n httpHost,\n httpPort,\n isApp,\n isWorkbenchApp,\n reactCompiler,\n reactStrictMode,\n schemaExtraction,\n typegen,\n vite: extendViteConfig,\n workbenchAppId,\n } = options\n\n debug('Writing Sanity runtime files')\n const {entries, watcher} = await writeSanityRuntime({\n appTitle,\n basePath,\n cwd,\n entry,\n isApp,\n isWorkbenchApp,\n reactStrictMode,\n watch: true,\n })\n\n debug('Resolving vite config')\n const mode = 'development'\n\n function getEnvironmentVariables() {\n return isApp\n ? getAppEnvironmentVariables({jsonEncode: true, prefix: 'process.env.'})\n : getStudioEnvironmentVariables({jsonEncode: true, prefix: 'process.env.'})\n }\n\n let viteConfig: InlineConfig = await getViteConfig({\n additionalPlugins: [\n // Add typegen when enabled\n ...(typegen?.enabled\n ? [\n sanityTypegenPlugin({\n config: typegen,\n telemetryLogger: getCliTelemetry(),\n workDir: cwd,\n }),\n ]\n : []),\n ],\n basePath,\n cwd,\n entries,\n exposes,\n getEnvironmentVariables,\n isApp,\n isWorkbenchApp,\n mode: 'development',\n reactCompiler,\n schemaExtraction,\n server: {host: httpHost, port: httpPort},\n workbenchAppId,\n })\n\n // Opt into Vite's experimental bundled dev mode. Set before the user-config\n // extension below so a `vite` override in sanity.cli.ts still has final say.\n //\n // Bundled mode bundles the app up front from an HTML entry, defaulting to\n // `<root>/index.html`. Sanity has no such file — it serves a virtual document\n // rewritten to `.sanity/runtime/index.html` — so point the bundler at the real\n // runtime HTML, otherwise the build fails with UNRESOLVED_ENTRY.\n //\n // Also force `strictExecutionOrder` so shared chunks cannot evaluate before the\n // entry chunk's react-refresh preamble (which otherwise throws\n // \"@vitejs/plugin-react can't detect preamble\").\n // See https://github.com/vitejs/vite-plugin-react/issues/1191\n if (bundledDev) {\n const existingRolldown = viteConfig.build?.rolldownOptions\n const existingOutput = existingRolldown?.output\n viteConfig = {\n ...viteConfig,\n build: {\n ...viteConfig.build,\n rolldownOptions: {\n ...existingRolldown,\n input: path.join(cwd, '.sanity', 'runtime', 'index.html'),\n output: Array.isArray(existingOutput)\n ? existingOutput.map((entry) => ({...entry, strictExecutionOrder: true}))\n : {...existingOutput, strictExecutionOrder: true},\n },\n },\n experimental: {...viteConfig.experimental, bundledDev: true},\n }\n }\n\n // Extend Vite configuration with user-provided config\n if (extendViteConfig) {\n viteConfig = await extendViteConfigWithUserConfig(\n {command: 'serve', mode},\n viteConfig,\n extendViteConfig,\n )\n }\n\n debug('Creating vite server')\n const server = await createServer(viteConfig)\n\n debug('Listening on specified port')\n await server.listen()\n\n return {\n close: async () => {\n if (watcher) {\n await watcher.close()\n }\n await server.close()\n },\n server,\n watcher,\n }\n}\n"],"names":["path","extendViteConfigWithUserConfig","getViteConfig","writeSanityRuntime","getAppEnvironmentVariables","getStudioEnvironmentVariables","getCliTelemetry","createServer","serverDebug","sanityTypegenPlugin","debug","extend","startDevServer","options","appTitle","basePath","bundledDev","cwd","entry","exposes","httpHost","httpPort","isApp","isWorkbenchApp","reactCompiler","reactStrictMode","schemaExtraction","typegen","vite","extendViteConfig","workbenchAppId","entries","watcher","watch","mode","getEnvironmentVariables","jsonEncode","prefix","viteConfig","additionalPlugins","enabled","config","telemetryLogger","workDir","server","host","port","existingRolldown","build","rolldownOptions","existingOutput","output","input","join","Array","isArray","map","strictExecutionOrder","experimental","command","listen","close"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,SACEC,8BAA8B,EAC9BC,aAAa,EACbC,kBAAkB,QACb,oCAAmC;AAC1C,SACEC,0BAA0B,EAC1BC,6BAA6B,QACxB,kCAAiC;AACxC,SAAmBC,eAAe,QAA4B,mBAAkB;AAIhF,SAAQC,YAAY,QAA8C,OAAM;AAExE,SAAQC,WAAW,QAAO,mBAAkB;AAC5C,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,MAAMC,QAAQF,YAAYG,MAAM,CAAC;AAmCjC,OAAO,eAAeC,eAAeC,OAAyB;IAC5D,MAAM,EACJC,QAAQ,EACRC,QAAQ,EACRC,UAAU,EACVC,GAAG,EACHC,KAAK,EACLC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,cAAc,EACdC,aAAa,EACbC,eAAe,EACfC,gBAAgB,EAChBC,OAAO,EACPC,MAAMC,gBAAgB,EACtBC,cAAc,EACf,GAAGjB;IAEJH,MAAM;IACN,MAAM,EAACqB,OAAO,EAAEC,OAAO,EAAC,GAAG,MAAM7B,mBAAmB;QAClDW;QACAC;QACAE;QACAC;QACAI;QACAC;QACAE;QACAQ,OAAO;IACT;IAEAvB,MAAM;IACN,MAAMwB,OAAO;IAEb,SAASC;QACP,OAAOb,QACHlB,2BAA2B;YAACgC,YAAY;YAAMC,QAAQ;QAAc,KACpEhC,8BAA8B;YAAC+B,YAAY;YAAMC,QAAQ;QAAc;IAC7E;IAEA,IAAIC,aAA2B,MAAMpC,cAAc;QACjDqC,mBAAmB;YACjB,2BAA2B;eACvBZ,SAASa,UACT;gBACE/B,oBAAoB;oBAClBgC,QAAQd;oBACRe,iBAAiBpC;oBACjBqC,SAAS1B;gBACX;aACD,GACD,EAAE;SACP;QACDF;QACAE;QACAc;QACAZ;QACAgB;QACAb;QACAC;QACAW,MAAM;QACNV;QACAE;QACAkB,QAAQ;YAACC,MAAMzB;YAAU0B,MAAMzB;QAAQ;QACvCS;IACF;IAEA,4EAA4E;IAC5E,6EAA6E;IAC7E,EAAE;IACF,0EAA0E;IAC1E,8EAA8E;IAC9E,+EAA+E;IAC/E,iEAAiE;IACjE,EAAE;IACF,gFAAgF;IAChF,+DAA+D;IAC/D,iDAAiD;IACjD,8DAA8D;IAC9D,IAAId,YAAY;QACd,MAAM+B,mBAAmBT,WAAWU,KAAK,EAAEC;QAC3C,MAAMC,iBAAiBH,kBAAkBI;QACzCb,aAAa;YACX,GAAGA,UAAU;YACbU,OAAO;gBACL,GAAGV,WAAWU,KAAK;gBACnBC,iBAAiB;oBACf,GAAGF,gBAAgB;oBACnBK,OAAOpD,KAAKqD,IAAI,CAACpC,KAAK,WAAW,WAAW;oBAC5CkC,QAAQG,MAAMC,OAAO,CAACL,kBAClBA,eAAeM,GAAG,CAAC,CAACtC,QAAW,CAAA;4BAAC,GAAGA,KAAK;4BAAEuC,sBAAsB;wBAAI,CAAA,KACpE;wBAAC,GAAGP,cAAc;wBAAEO,sBAAsB;oBAAI;gBACpD;YACF;YACAC,cAAc;gBAAC,GAAGpB,WAAWoB,YAAY;gBAAE1C,YAAY;YAAI;QAC7D;IACF;IAEA,sDAAsD;IACtD,IAAIa,kBAAkB;QACpBS,aAAa,MAAMrC,+BACjB;YAAC0D,SAAS;YAASzB;QAAI,GACvBI,YACAT;IAEJ;IAEAnB,MAAM;IACN,MAAMkC,SAAS,MAAMrC,aAAa+B;IAElC5B,MAAM;IACN,MAAMkC,OAAOgB,MAAM;IAEnB,OAAO;QACLC,OAAO;YACL,IAAI7B,SAAS;gBACX,MAAMA,QAAQ6B,KAAK;YACrB;YACA,MAAMjB,OAAOiB,KAAK;QACpB;QACAjB;QACAZ;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/server/devServer.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {\n extendViteConfigWithUserConfig,\n getViteConfig,\n writeSanityRuntime,\n} from '@sanity/cli-build/_internal/build'\nimport {\n getAppEnvironmentVariables,\n getStudioEnvironmentVariables,\n} from '@sanity/cli-build/_internal/env'\nimport {CliConfig, getCliTelemetry, type UserViteConfig} from '@sanity/cli-core'\nimport {type WorkbenchExposes} from '@sanity/workbench-cli/build'\nimport {type FSWatcher} from 'chokidar'\nimport {createServer, type InlineConfig, type ViteDevServer} from 'vite'\n\nimport {serverDebug} from './serverDebug.js'\nimport {sanityTypegenPlugin} from './vite/plugin-typegen.js'\n\nconst debug = serverDebug.extend('dev')\n\nexport interface DevServerOptions {\n basePath: string\n cwd: string\n httpPort: number\n\n reactCompiler: CliConfig['reactCompiler']\n reactStrictMode: boolean | undefined\n\n staticPath: string\n\n appTitle?: string\n /** Enable Vite's experimental bundled dev mode (`experimental.bundledDev`). */\n bundledDev?: boolean\n entry?: string\n exposes?: WorkbenchExposes\n httpHost?: string\n isApp?: boolean\n isWorkbenchApp?: boolean\n projectName?: string\n schemaExtraction?: CliConfig['schemaExtraction']\n typegen?: CliConfig['typegen']\n vite?: UserViteConfig\n /** The workbench app's bus identity (`__SANITY_APP_ID__`). */\n workbenchAppId?: string\n}\n\ninterface DevServer {\n close(): Promise<void>\n server: ViteDevServer\n\n watcher?: FSWatcher\n}\n\nexport async function startDevServer(options: DevServerOptions): Promise<DevServer> {\n const {\n appTitle,\n basePath,\n bundledDev,\n cwd,\n entry,\n exposes,\n httpHost,\n httpPort,\n isApp,\n isWorkbenchApp,\n reactCompiler,\n reactStrictMode,\n schemaExtraction,\n typegen,\n vite: extendViteConfig,\n workbenchAppId,\n } = options\n\n debug('Writing Sanity runtime files')\n const {entries, watcher} = await writeSanityRuntime({\n appTitle,\n basePath,\n cwd,\n entry,\n isApp,\n isWorkbenchApp,\n reactStrictMode,\n watch: true,\n })\n\n debug('Resolving vite config')\n const mode = 'development'\n\n function getEnvironmentVariables() {\n return isApp\n ? getAppEnvironmentVariables({jsonEncode: true, prefix: 'process.env.'})\n : getStudioEnvironmentVariables({jsonEncode: true, prefix: 'process.env.'})\n }\n\n let viteConfig: InlineConfig = await getViteConfig({\n additionalPlugins: [\n // Add typegen when enabled\n ...(typegen?.enabled\n ? [\n sanityTypegenPlugin({\n config: typegen,\n telemetryLogger: getCliTelemetry(),\n workDir: cwd,\n }),\n ]\n : []),\n ],\n basePath,\n cwd,\n entries,\n exposes,\n getEnvironmentVariables,\n isApp,\n isWorkbenchApp,\n mode: 'development',\n reactCompiler,\n schemaExtraction,\n server: {host: httpHost, port: httpPort},\n workbenchAppId,\n })\n\n // Opt into Vite's experimental bundled dev mode. Set before the user-config\n // extension below so a `vite` override in sanity.cli.ts still has final say.\n //\n // Bundled mode bundles the app up front from an HTML entry, defaulting to\n // `<root>/index.html`. Sanity has no such file — it serves a virtual document\n // rewritten to `.sanity/runtime/index.html` — so point the bundler at the real\n // runtime HTML, otherwise the build fails with UNRESOLVED_ENTRY.\n //\n // Also force `strictExecutionOrder` so shared chunks cannot evaluate before the\n // entry chunk's react-refresh preamble (which otherwise throws\n // \"@vitejs/plugin-react can't detect preamble\").\n // See https://github.com/vitejs/vite-plugin-react/issues/1191\n if (bundledDev) {\n const existingRolldown = viteConfig.build?.rolldownOptions\n const existingOutput = existingRolldown?.output\n viteConfig = {\n ...viteConfig,\n build: {\n ...viteConfig.build,\n rolldownOptions: {\n ...existingRolldown,\n input: path.join(cwd, '.sanity', 'runtime', 'index.html'),\n output: Array.isArray(existingOutput)\n ? existingOutput.map((entry) => ({...entry, strictExecutionOrder: true}))\n : {...existingOutput, strictExecutionOrder: true},\n },\n },\n experimental: {...viteConfig.experimental, bundledDev: true},\n }\n }\n\n // Extend Vite configuration with user-provided config\n if (extendViteConfig) {\n viteConfig = await extendViteConfigWithUserConfig(\n {command: 'serve', mode},\n viteConfig,\n extendViteConfig,\n )\n }\n\n debug('Creating vite server')\n const server = await createServer(viteConfig)\n\n debug('Listening on specified port')\n await server.listen()\n\n return {\n close: async () => {\n if (watcher) {\n await watcher.close()\n }\n await server.close()\n },\n server,\n watcher,\n }\n}\n"],"names":["path","extendViteConfigWithUserConfig","getViteConfig","writeSanityRuntime","getAppEnvironmentVariables","getStudioEnvironmentVariables","getCliTelemetry","createServer","serverDebug","sanityTypegenPlugin","debug","extend","startDevServer","options","appTitle","basePath","bundledDev","cwd","entry","exposes","httpHost","httpPort","isApp","isWorkbenchApp","reactCompiler","reactStrictMode","schemaExtraction","typegen","vite","extendViteConfig","workbenchAppId","entries","watcher","watch","mode","getEnvironmentVariables","jsonEncode","prefix","viteConfig","additionalPlugins","enabled","config","telemetryLogger","workDir","server","host","port","existingRolldown","build","rolldownOptions","existingOutput","output","input","join","Array","isArray","map","strictExecutionOrder","experimental","command","listen","close"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,SACEC,8BAA8B,EAC9BC,aAAa,EACbC,kBAAkB,QACb,oCAAmC;AAC1C,SACEC,0BAA0B,EAC1BC,6BAA6B,QACxB,kCAAiC;AACxC,SAAmBC,eAAe,QAA4B,mBAAkB;AAGhF,SAAQC,YAAY,QAA8C,OAAM;AAExE,SAAQC,WAAW,QAAO,mBAAkB;AAC5C,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,MAAMC,QAAQF,YAAYG,MAAM,CAAC;AAmCjC,OAAO,eAAeC,eAAeC,OAAyB;IAC5D,MAAM,EACJC,QAAQ,EACRC,QAAQ,EACRC,UAAU,EACVC,GAAG,EACHC,KAAK,EACLC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,cAAc,EACdC,aAAa,EACbC,eAAe,EACfC,gBAAgB,EAChBC,OAAO,EACPC,MAAMC,gBAAgB,EACtBC,cAAc,EACf,GAAGjB;IAEJH,MAAM;IACN,MAAM,EAACqB,OAAO,EAAEC,OAAO,EAAC,GAAG,MAAM7B,mBAAmB;QAClDW;QACAC;QACAE;QACAC;QACAI;QACAC;QACAE;QACAQ,OAAO;IACT;IAEAvB,MAAM;IACN,MAAMwB,OAAO;IAEb,SAASC;QACP,OAAOb,QACHlB,2BAA2B;YAACgC,YAAY;YAAMC,QAAQ;QAAc,KACpEhC,8BAA8B;YAAC+B,YAAY;YAAMC,QAAQ;QAAc;IAC7E;IAEA,IAAIC,aAA2B,MAAMpC,cAAc;QACjDqC,mBAAmB;YACjB,2BAA2B;eACvBZ,SAASa,UACT;gBACE/B,oBAAoB;oBAClBgC,QAAQd;oBACRe,iBAAiBpC;oBACjBqC,SAAS1B;gBACX;aACD,GACD,EAAE;SACP;QACDF;QACAE;QACAc;QACAZ;QACAgB;QACAb;QACAC;QACAW,MAAM;QACNV;QACAE;QACAkB,QAAQ;YAACC,MAAMzB;YAAU0B,MAAMzB;QAAQ;QACvCS;IACF;IAEA,4EAA4E;IAC5E,6EAA6E;IAC7E,EAAE;IACF,0EAA0E;IAC1E,8EAA8E;IAC9E,+EAA+E;IAC/E,iEAAiE;IACjE,EAAE;IACF,gFAAgF;IAChF,+DAA+D;IAC/D,iDAAiD;IACjD,8DAA8D;IAC9D,IAAId,YAAY;QACd,MAAM+B,mBAAmBT,WAAWU,KAAK,EAAEC;QAC3C,MAAMC,iBAAiBH,kBAAkBI;QACzCb,aAAa;YACX,GAAGA,UAAU;YACbU,OAAO;gBACL,GAAGV,WAAWU,KAAK;gBACnBC,iBAAiB;oBACf,GAAGF,gBAAgB;oBACnBK,OAAOpD,KAAKqD,IAAI,CAACpC,KAAK,WAAW,WAAW;oBAC5CkC,QAAQG,MAAMC,OAAO,CAACL,kBAClBA,eAAeM,GAAG,CAAC,CAACtC,QAAW,CAAA;4BAAC,GAAGA,KAAK;4BAAEuC,sBAAsB;wBAAI,CAAA,KACpE;wBAAC,GAAGP,cAAc;wBAAEO,sBAAsB;oBAAI;gBACpD;YACF;YACAC,cAAc;gBAAC,GAAGpB,WAAWoB,YAAY;gBAAE1C,YAAY;YAAI;QAC7D;IACF;IAEA,sDAAsD;IACtD,IAAIa,kBAAkB;QACpBS,aAAa,MAAMrC,+BACjB;YAAC0D,SAAS;YAASzB;QAAI,GACvBI,YACAT;IAEJ;IAEAnB,MAAM;IACN,MAAMkC,SAAS,MAAMrC,aAAa+B;IAElC5B,MAAM;IACN,MAAMkC,OAAOgB,MAAM;IAEnB,OAAO;QACLC,OAAO;YACL,IAAI7B,SAAS;gBACX,MAAMA,QAAQ6B,KAAK;YACrB;YACA,MAAMjB,OAAOiB,KAAK;QACpB;QACAjB;QACAZ;IACF;AACF"}
@@ -8,7 +8,7 @@ export async function uploadAsset({ assetType, body, contentType, dataset, filen
8
8
  apiVersion: ASSETS_API_VERSION,
9
9
  dataset,
10
10
  projectId,
11
- requestTagPrefix: 'sanity.assets.upload',
11
+ requestTagPrefix: 'sanity.cli.assets.upload',
12
12
  requireUser: true
13
13
  });
14
14
  signal?.throwIfAborted();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/services/assets.ts"],"sourcesContent":["import {type Readable, Transform} from 'node:stream'\n\nimport {getProjectCliClient} from '@sanity/cli-core'\nimport {filter, lastValueFrom, map, Observable, race} from 'rxjs'\n\nexport const ASSETS_API_VERSION = 'v2024-06-24'\n\nexport type AssetType = 'file' | 'image'\n\ninterface UploadAssetOptions {\n assetType: AssetType\n body: Readable\n dataset: string\n filename: string\n fileSize: number\n projectId: string\n\n contentType?: string\n onProgress?: (percent: number) => void\n signal?: AbortSignal\n}\n\nexport async function uploadAsset({\n assetType,\n body,\n contentType,\n dataset,\n filename,\n fileSize,\n onProgress,\n projectId,\n signal,\n}: UploadAssetOptions) {\n signal?.throwIfAborted()\n\n const client = await getProjectCliClient({\n apiVersion: ASSETS_API_VERSION,\n dataset,\n projectId,\n requestTagPrefix: 'sanity.assets.upload',\n requireUser: true,\n })\n signal?.throwIfAborted()\n\n let uploadedBytes = 0\n const uploadStream = new Transform({\n transform(chunk: Buffer, _encoding, callback) {\n uploadedBytes += chunk.length\n onProgress?.((uploadedBytes / fileSize) * 100)\n callback(null, chunk)\n },\n })\n body.on('error', (error) => uploadStream.destroy(error)).pipe(uploadStream)\n\n const response$ = client.observable.assets\n .upload(assetType, uploadStream, {\n ...(contentType ? {contentType} : {}),\n filename,\n tag: 'asset.upload',\n })\n .pipe(\n filter((event) => event.type === 'response'),\n map((event) => event.body.document),\n )\n\n if (!signal) return lastValueFrom(response$)\n\n const abort$ = new Observable<never>((subscriber) => {\n const abortUpload = () => {\n body.destroy()\n uploadStream.destroy()\n subscriber.error(signal.reason instanceof Error ? signal.reason : new Error('SIGINT'))\n }\n\n signal.addEventListener('abort', abortUpload, {once: true})\n return () => signal.removeEventListener('abort', abortUpload)\n })\n\n return lastValueFrom(race(response$, abort$))\n}\n"],"names":["Transform","getProjectCliClient","filter","lastValueFrom","map","Observable","race","ASSETS_API_VERSION","uploadAsset","assetType","body","contentType","dataset","filename","fileSize","onProgress","projectId","signal","throwIfAborted","client","apiVersion","requestTagPrefix","requireUser","uploadedBytes","uploadStream","transform","chunk","_encoding","callback","length","on","error","destroy","pipe","response$","observable","assets","upload","tag","event","type","document","abort$","subscriber","abortUpload","reason","Error","addEventListener","once","removeEventListener"],"mappings":"AAAA,SAAuBA,SAAS,QAAO,cAAa;AAEpD,SAAQC,mBAAmB,QAAO,mBAAkB;AACpD,SAAQC,MAAM,EAAEC,aAAa,EAAEC,GAAG,EAAEC,UAAU,EAAEC,IAAI,QAAO,OAAM;AAEjE,OAAO,MAAMC,qBAAqB,cAAa;AAiB/C,OAAO,eAAeC,YAAY,EAChCC,SAAS,EACTC,IAAI,EACJC,WAAW,EACXC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,UAAU,EACVC,SAAS,EACTC,MAAM,EACa;IACnBA,QAAQC;IAER,MAAMC,SAAS,MAAMlB,oBAAoB;QACvCmB,YAAYb;QACZK;QACAI;QACAK,kBAAkB;QAClBC,aAAa;IACf;IACAL,QAAQC;IAER,IAAIK,gBAAgB;IACpB,MAAMC,eAAe,IAAIxB,UAAU;QACjCyB,WAAUC,KAAa,EAAEC,SAAS,EAAEC,QAAQ;YAC1CL,iBAAiBG,MAAMG,MAAM;YAC7Bd,aAAa,AAACQ,gBAAgBT,WAAY;YAC1Cc,SAAS,MAAMF;QACjB;IACF;IACAhB,KAAKoB,EAAE,CAAC,SAAS,CAACC,QAAUP,aAAaQ,OAAO,CAACD,QAAQE,IAAI,CAACT;IAE9D,MAAMU,YAAYf,OAAOgB,UAAU,CAACC,MAAM,CACvCC,MAAM,CAAC5B,WAAWe,cAAc;QAC/B,GAAIb,cAAc;YAACA;QAAW,IAAI,CAAC,CAAC;QACpCE;QACAyB,KAAK;IACP,GACCL,IAAI,CACH/B,OAAO,CAACqC,QAAUA,MAAMC,IAAI,KAAK,aACjCpC,IAAI,CAACmC,QAAUA,MAAM7B,IAAI,CAAC+B,QAAQ;IAGtC,IAAI,CAACxB,QAAQ,OAAOd,cAAc+B;IAElC,MAAMQ,SAAS,IAAIrC,WAAkB,CAACsC;QACpC,MAAMC,cAAc;YAClBlC,KAAKsB,OAAO;YACZR,aAAaQ,OAAO;YACpBW,WAAWZ,KAAK,CAACd,OAAO4B,MAAM,YAAYC,QAAQ7B,OAAO4B,MAAM,GAAG,IAAIC,MAAM;QAC9E;QAEA7B,OAAO8B,gBAAgB,CAAC,SAASH,aAAa;YAACI,MAAM;QAAI;QACzD,OAAO,IAAM/B,OAAOgC,mBAAmB,CAAC,SAASL;IACnD;IAEA,OAAOzC,cAAcG,KAAK4B,WAAWQ;AACvC"}
1
+ {"version":3,"sources":["../../src/services/assets.ts"],"sourcesContent":["import {type Readable, Transform} from 'node:stream'\n\nimport {getProjectCliClient} from '@sanity/cli-core'\nimport {filter, lastValueFrom, map, Observable, race} from 'rxjs'\n\nexport const ASSETS_API_VERSION = 'v2024-06-24'\n\nexport type AssetType = 'file' | 'image'\n\ninterface UploadAssetOptions {\n assetType: AssetType\n body: Readable\n dataset: string\n filename: string\n fileSize: number\n projectId: string\n\n contentType?: string\n onProgress?: (percent: number) => void\n signal?: AbortSignal\n}\n\nexport async function uploadAsset({\n assetType,\n body,\n contentType,\n dataset,\n filename,\n fileSize,\n onProgress,\n projectId,\n signal,\n}: UploadAssetOptions) {\n signal?.throwIfAborted()\n\n const client = await getProjectCliClient({\n apiVersion: ASSETS_API_VERSION,\n dataset,\n projectId,\n requestTagPrefix: 'sanity.cli.assets.upload',\n requireUser: true,\n })\n signal?.throwIfAborted()\n\n let uploadedBytes = 0\n const uploadStream = new Transform({\n transform(chunk: Buffer, _encoding, callback) {\n uploadedBytes += chunk.length\n onProgress?.((uploadedBytes / fileSize) * 100)\n callback(null, chunk)\n },\n })\n body.on('error', (error) => uploadStream.destroy(error)).pipe(uploadStream)\n\n const response$ = client.observable.assets\n .upload(assetType, uploadStream, {\n ...(contentType ? {contentType} : {}),\n filename,\n tag: 'asset.upload',\n })\n .pipe(\n filter((event) => event.type === 'response'),\n map((event) => event.body.document),\n )\n\n if (!signal) return lastValueFrom(response$)\n\n const abort$ = new Observable<never>((subscriber) => {\n const abortUpload = () => {\n body.destroy()\n uploadStream.destroy()\n subscriber.error(signal.reason instanceof Error ? signal.reason : new Error('SIGINT'))\n }\n\n signal.addEventListener('abort', abortUpload, {once: true})\n return () => signal.removeEventListener('abort', abortUpload)\n })\n\n return lastValueFrom(race(response$, abort$))\n}\n"],"names":["Transform","getProjectCliClient","filter","lastValueFrom","map","Observable","race","ASSETS_API_VERSION","uploadAsset","assetType","body","contentType","dataset","filename","fileSize","onProgress","projectId","signal","throwIfAborted","client","apiVersion","requestTagPrefix","requireUser","uploadedBytes","uploadStream","transform","chunk","_encoding","callback","length","on","error","destroy","pipe","response$","observable","assets","upload","tag","event","type","document","abort$","subscriber","abortUpload","reason","Error","addEventListener","once","removeEventListener"],"mappings":"AAAA,SAAuBA,SAAS,QAAO,cAAa;AAEpD,SAAQC,mBAAmB,QAAO,mBAAkB;AACpD,SAAQC,MAAM,EAAEC,aAAa,EAAEC,GAAG,EAAEC,UAAU,EAAEC,IAAI,QAAO,OAAM;AAEjE,OAAO,MAAMC,qBAAqB,cAAa;AAiB/C,OAAO,eAAeC,YAAY,EAChCC,SAAS,EACTC,IAAI,EACJC,WAAW,EACXC,OAAO,EACPC,QAAQ,EACRC,QAAQ,EACRC,UAAU,EACVC,SAAS,EACTC,MAAM,EACa;IACnBA,QAAQC;IAER,MAAMC,SAAS,MAAMlB,oBAAoB;QACvCmB,YAAYb;QACZK;QACAI;QACAK,kBAAkB;QAClBC,aAAa;IACf;IACAL,QAAQC;IAER,IAAIK,gBAAgB;IACpB,MAAMC,eAAe,IAAIxB,UAAU;QACjCyB,WAAUC,KAAa,EAAEC,SAAS,EAAEC,QAAQ;YAC1CL,iBAAiBG,MAAMG,MAAM;YAC7Bd,aAAa,AAACQ,gBAAgBT,WAAY;YAC1Cc,SAAS,MAAMF;QACjB;IACF;IACAhB,KAAKoB,EAAE,CAAC,SAAS,CAACC,QAAUP,aAAaQ,OAAO,CAACD,QAAQE,IAAI,CAACT;IAE9D,MAAMU,YAAYf,OAAOgB,UAAU,CAACC,MAAM,CACvCC,MAAM,CAAC5B,WAAWe,cAAc;QAC/B,GAAIb,cAAc;YAACA;QAAW,IAAI,CAAC,CAAC;QACpCE;QACAyB,KAAK;IACP,GACCL,IAAI,CACH/B,OAAO,CAACqC,QAAUA,MAAMC,IAAI,KAAK,aACjCpC,IAAI,CAACmC,QAAUA,MAAM7B,IAAI,CAAC+B,QAAQ;IAGtC,IAAI,CAACxB,QAAQ,OAAOd,cAAc+B;IAElC,MAAMQ,SAAS,IAAIrC,WAAkB,CAACsC;QACpC,MAAMC,cAAc;YAClBlC,KAAKsB,OAAO;YACZR,aAAaQ,OAAO;YACpBW,WAAWZ,KAAK,CAACd,OAAO4B,MAAM,YAAYC,QAAQ7B,OAAO4B,MAAM,GAAG,IAAIC,MAAM;QAC9E;QAEA7B,OAAO8B,gBAAgB,CAAC,SAASH,aAAa;YAACI,MAAM;QAAI;QACzD,OAAO,IAAM/B,OAAOgC,mBAAmB,CAAC,SAASL;IACnD;IAEA,OAAOzC,cAAcG,KAAK4B,WAAWQ;AACvC"}