@sanity/cli 8.25.0 → 8.27.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 (127) hide show
  1. package/README.md +3 -2
  2. package/dist/actions/build/shouldAutoUpdate.js +1 -26
  3. package/dist/actions/build/shouldAutoUpdate.js.map +1 -1
  4. package/dist/actions/context/mcpEndpoint.js +165 -0
  5. package/dist/actions/context/mcpEndpoint.js.map +1 -0
  6. package/dist/actions/context/resolveOrganizationId.js +8 -1
  7. package/dist/actions/context/resolveOrganizationId.js.map +1 -1
  8. package/dist/actions/deploy/deployApp.js +10 -3
  9. package/dist/actions/deploy/deployApp.js.map +1 -1
  10. package/dist/actions/deploy/deployStudio.js +11 -4
  11. package/dist/actions/deploy/deployStudio.js.map +1 -1
  12. package/dist/actions/init/initAction.js +3 -3
  13. package/dist/actions/init/initAction.js.map +1 -1
  14. package/dist/actions/init/plan/verifyCoupon.js +0 -1
  15. package/dist/actions/init/plan/verifyCoupon.js.map +1 -1
  16. package/dist/actions/init/scaffoldTemplate.js +1 -1
  17. package/dist/actions/init/scaffoldTemplate.js.map +1 -1
  18. package/dist/commands/api.js +10 -0
  19. package/dist/commands/api.js.map +1 -1
  20. package/dist/commands/backups/download.js +6 -0
  21. package/dist/commands/backups/download.js.map +1 -1
  22. package/dist/commands/context/create.js +8 -22
  23. package/dist/commands/context/create.js.map +1 -1
  24. package/dist/commands/context/delete.js +8 -1
  25. package/dist/commands/context/delete.js.map +1 -1
  26. package/dist/commands/context/issues/list.js +0 -5
  27. package/dist/commands/context/issues/list.js.map +1 -1
  28. package/dist/commands/context/list.js +6 -14
  29. package/dist/commands/context/list.js.map +1 -1
  30. package/dist/commands/context/mcp/create.js +152 -0
  31. package/dist/commands/context/mcp/create.js.map +1 -0
  32. package/dist/commands/context/mcp/delete.js +82 -0
  33. package/dist/commands/context/mcp/delete.js.map +1 -0
  34. package/dist/commands/context/mcp/get.js +42 -0
  35. package/dist/commands/context/mcp/get.js.map +1 -0
  36. package/dist/commands/context/mcp/list.js +87 -0
  37. package/dist/commands/context/mcp/list.js.map +1 -0
  38. package/dist/commands/context/mcp/status.js +98 -0
  39. package/dist/commands/context/mcp/status.js.map +1 -0
  40. package/dist/commands/context/mcp/update.js +225 -0
  41. package/dist/commands/context/mcp/update.js.map +1 -0
  42. package/dist/commands/context/query.js +6 -14
  43. package/dist/commands/context/query.js.map +1 -1
  44. package/dist/commands/context/update.js +12 -1
  45. package/dist/commands/context/update.js.map +1 -1
  46. package/dist/commands/datasets/create.js +6 -0
  47. package/dist/commands/datasets/create.js.map +1 -1
  48. package/dist/commands/datasets/embeddings/enable.js +6 -0
  49. package/dist/commands/datasets/embeddings/enable.js.map +1 -1
  50. package/dist/commands/datasets/import.js +6 -0
  51. package/dist/commands/datasets/import.js.map +1 -1
  52. package/dist/commands/deploy.js +7 -0
  53. package/dist/commands/deploy.js.map +1 -1
  54. package/dist/commands/documents/validate.js +6 -0
  55. package/dist/commands/documents/validate.js.map +1 -1
  56. package/dist/commands/exec.js +4 -2
  57. package/dist/commands/exec.js.map +1 -1
  58. package/dist/commands/init.js +13 -0
  59. package/dist/commands/init.js.map +1 -1
  60. package/dist/commands/manifest/extract.js +6 -0
  61. package/dist/commands/manifest/extract.js.map +1 -1
  62. package/dist/commands/media/create-aspect.js +7 -0
  63. package/dist/commands/media/create-aspect.js.map +1 -1
  64. package/dist/commands/migrations/run.js +6 -0
  65. package/dist/commands/migrations/run.js.map +1 -1
  66. package/dist/commands/organizations/create.js +6 -0
  67. package/dist/commands/organizations/create.js.map +1 -1
  68. package/dist/commands/organizations/update.js +6 -0
  69. package/dist/commands/organizations/update.js.map +1 -1
  70. package/dist/commands/schemas/delete.js +6 -0
  71. package/dist/commands/schemas/delete.js.map +1 -1
  72. package/dist/commands/schemas/deploy.js +6 -0
  73. package/dist/commands/schemas/deploy.js.map +1 -1
  74. package/dist/commands/schemas/extract.js +28 -3
  75. package/dist/commands/schemas/extract.js.map +1 -1
  76. package/dist/commands/schemas/list.js +6 -0
  77. package/dist/commands/schemas/list.js.map +1 -1
  78. package/dist/commands/schemas/validate.js +6 -0
  79. package/dist/commands/schemas/validate.js.map +1 -1
  80. package/dist/commands/tokens/rotate.js +6 -0
  81. package/dist/commands/tokens/rotate.js.map +1 -1
  82. package/dist/commands/typegen/generate.js +25 -1
  83. package/dist/commands/typegen/generate.js.map +1 -1
  84. package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js +6 -0
  85. package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js.map +1 -1
  86. package/dist/generated/apiRoutes.js +22 -0
  87. package/dist/generated/apiRoutes.js.map +1 -1
  88. package/dist/hooks/prerun/setupTelemetry.js +2 -3
  89. package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
  90. package/dist/prompts/promptForText.js +12 -0
  91. package/dist/prompts/promptForText.js.map +1 -0
  92. package/dist/services/context.js +174 -1
  93. package/dist/services/context.js.map +1 -1
  94. package/dist/services/telemetry.js +4 -2
  95. package/dist/services/telemetry.js.map +1 -1
  96. package/dist/telemetry/cli.telemetry.js +1 -1
  97. package/dist/telemetry/cli.telemetry.js.map +1 -1
  98. package/dist/telemetry/init.telemetry.js +1 -1
  99. package/dist/telemetry/init.telemetry.js.map +1 -1
  100. package/dist/telemetry/typegen.telemetry.js +12 -0
  101. package/dist/telemetry/typegen.telemetry.js.map +1 -0
  102. package/dist/util/parseArguments.js +12 -40
  103. package/dist/util/parseArguments.js.map +1 -1
  104. package/dist/util/sharedFlags.js.map +1 -1
  105. package/dist/util/telemetry/cliCommandIdentity.js +222 -0
  106. package/dist/util/telemetry/cliCommandIdentity.js.map +1 -0
  107. package/dist/util/telemetry/cliTelemetryFlags.js +186 -0
  108. package/dist/util/telemetry/cliTelemetryFlags.js.map +1 -0
  109. package/dist/util/telemetry/commandTelemetry.js +56 -11
  110. package/dist/util/telemetry/commandTelemetry.js.map +1 -1
  111. package/dist/util/telemetry/createTelemetryStore.js +13 -5
  112. package/dist/util/telemetry/createTelemetryStore.js.map +1 -1
  113. package/dist/util/telemetry/createTraceId.js +3 -3
  114. package/dist/util/telemetry/createTraceId.js.map +1 -1
  115. package/dist/util/telemetry/flushTelemetryFiles.js +14 -4
  116. package/dist/util/telemetry/flushTelemetryFiles.js.map +1 -1
  117. package/dist/util/telemetry/logger.js +1 -1
  118. package/dist/util/telemetry/logger.js.map +1 -1
  119. package/dist/util/telemetry/readNDJSON.js +1 -1
  120. package/dist/util/telemetry/readNDJSON.js.map +1 -1
  121. package/dist/util/telemetry/sanitizeTelemetryEvent.js +304 -0
  122. package/dist/util/telemetry/sanitizeTelemetryEvent.js.map +1 -0
  123. package/dist/util/telemetry/trace.js +4 -7
  124. package/dist/util/telemetry/trace.js.map +1 -1
  125. package/oclif.config.js +1 -1
  126. package/oclif.manifest.json +2380 -1526
  127. package/package.json +8 -11
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/deploy/deployStudio.ts"],"sourcesContent":["import {basename, dirname, relative} from 'node:path'\nimport {styleText} from 'node:util'\nimport {createGzip, type Gzip} from 'node:zlib'\n\nimport {formatSchemaValidation, SchemaExtractionError} from '@sanity/cli-build/_internal/extract'\nimport {readIconFromPath} from '@sanity/cli-build/_internal/manifest'\nimport {exitCodes} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {\n type BrettAccess,\n type BrettWorkspace,\n createStudio,\n deployWorkbenchApp,\n getApplicationUrl,\n getWorkbench,\n getWorkbenchUrl,\n toWorkbenchPayload,\n} from '@sanity/workbench-cli/deploy'\nimport {type StudioManifest} from 'sanity'\nimport {c as createTar} from 'tar'\n\nimport {createDeployment, type UserApplication} from '../../services/userApplications.js'\nimport {getAppId} from '../../util/appId.js'\nimport {NO_ORGANIZATION_ID, NO_PROJECT_ID} from '../../util/errorMessages.js'\nimport {buildStudio} from '../build/buildStudio.js'\nimport {checkBlueprintManaged} from './blueprintManaged.js'\nimport {createStudioUserApplication} from './createUserApplication.js'\nimport {\n checkAutoUpdates,\n checkBuild,\n checkExternalUrl,\n checkPackageVersion,\n checkStudioTarget,\n type DeployCheckReporter,\n verifyOutputDir,\n} from './deployChecks.js'\nimport {deployDebug} from './deployDebug.js'\nimport {listDeploymentFiles, reportInterfaces} from './deploymentPlan.js'\nimport {type DeployPayload, type DeployResult, runDeploy} from './deployRunner.js'\nimport {deployStudioSchemasAndManifests} from './deployStudioSchemasAndManifests.js'\nimport {findUserApplicationForStudio} from './findUserApplication.js'\nimport {type DeployAppOptions} from './types.js'\n\nconst STUDIO_PACKAGE = 'sanity'\n\nexport function deployStudio(options: DeployAppOptions): Promise<void> {\n return runDeploy(options, {\n listFiles: ({flags, projectRoot, sourceDir}) =>\n flags.external ? Promise.resolve([]) : listDeploymentFiles(sourceDir, projectRoot.directory),\n run: runStudioDeployment,\n type: 'studio',\n })\n}\n\n/** Validates the deploy, extracts and uploads the schema, and ships the build. */\nasync function runStudioDeployment(\n options: DeployAppOptions,\n reporter: DeployCheckReporter,\n): Promise<DeployResult | void> {\n const {cliConfig, flags, output, sourceDir} = options\n const workDir = options.projectRoot.directory\n const isExternal = !!flags.external\n const workbench = getWorkbench(cliConfig)\n const isWorkbenchApp = workbench !== null\n const projectId = cliConfig.api?.projectId\n const organizationId = cliConfig.app?.organizationId\n const appId = getAppId(cliConfig)\n const dryRun = !!flags['dry-run']\n // A legacy external studio only registers its URL; a federated one is built\n // and deployed like a hosted one, minus the upload.\n const isLegacyExternal = isExternal && !isWorkbenchApp\n\n const appTitle = workbench\n ? flags.title?.trim() || cliConfig.app?.title?.trim() || workbench.slug\n : ''\n\n const isAutoUpdating = checkAutoUpdates(reporter, {cliConfig, flags})\n\n const version = await checkPackageVersion(reporter, {\n moduleName: STUDIO_PACKAGE,\n workDir,\n })\n\n reporter.report(\n projectId\n ? {message: `Project: ${projectId}`, status: 'pass'}\n : {\n message: NO_PROJECT_ID,\n solution: 'Add `api.projectId` to sanity.cli.ts',\n status: 'fail',\n },\n )\n\n await checkBlueprintManaged(reporter, {kind: 'studio', projectRootDir: workDir})\n\n // Workbench studios deploy to Brett (which needs the org); plain studios\n // resolve/create on user-applications, unchanged.\n let application: UserApplication | null = null\n let studioCreated = false\n let workbenchApp: {externalUrl?: string} | undefined\n let externalUrl: string | undefined\n if (workbench) {\n reporter.report(\n organizationId\n ? {message: `Organization: ${organizationId}`, status: 'pass'}\n : {\n message: NO_ORGANIZATION_ID,\n solution: 'Add `app.organizationId` to sanity.cli.ts',\n status: 'fail',\n },\n )\n workbenchApp = (\n await checkStudioTarget(reporter, {\n appId,\n isWorkbenchApp: true,\n organizationId,\n slug: workbench.slug,\n title: appTitle,\n })\n )?.application\n if (isExternal) externalUrl = checkExternalUrl(reporter, {appId, url: flags.url})\n } else {\n ;({application, created: studioCreated} = await resolveStudioApplication(options, {\n dryRun,\n reporter,\n }))\n }\n // A redeploy follows how the application was registered, so --external is only needed once.\n const isExternallyHosted = isExternal || !!workbenchApp?.externalUrl\n\n // A first deploy mints the app id and the build inlines it; --no-build would\n // ship an existing bundle carrying a different id, so it can't be a first deploy.\n if (workbench && !appId && !flags.build) {\n reporter.report({\n exitCode: exitCodes.USAGE_ERROR,\n message: 'A first deploy cannot skip the build (--no-build)',\n solution: 'Drop --no-build so the new application id is inlined into the build',\n status: 'fail',\n })\n }\n\n // Read up front so a bad icon path fails before we create or build.\n const appIcon =\n !dryRun && workbench?.icon ? await readIconFromPath(workDir, workbench.icon) : undefined\n\n // Create the studio before the build so the bundle carries its real id. A\n // redeploy already has it from `deployment.appId`; a dry run skips creation.\n let applicationId = appId\n let applicationCreated = false\n let rollbackApp: (() => Promise<void>) | undefined\n if (!dryRun && workbench && organizationId && !applicationId) {\n const created = await createStudio({\n externalUrl,\n name: workbench.name,\n organizationId,\n projectId,\n slug: workbench.slug,\n title: appTitle,\n visibility: workbench.visibility,\n })\n workbenchApp = created.application\n applicationId = created.application.id\n rollbackApp = created.rollback\n applicationCreated = true\n }\n\n // A record created above is stranded at its slug (and blocks retries) if any\n // step before it fully deploys fails, so undo the creation on failure.\n try {\n const built = await checkBuild(reporter, {\n build: () =>\n buildStudio({\n applicationId: workbench ? applicationId : undefined,\n autoUpdatesEnabled: isAutoUpdating,\n calledFromDeploy: true,\n cliConfig,\n flags,\n outDir: sourceDir,\n output,\n workDir,\n }),\n skipReason: studioBuildSkipReason({build: flags.build, isLegacyExternal}),\n successMessage: 'Studio built',\n })\n\n let mfManifest = built?.mfManifest\n // A federated build has already read its manifest; anything else verifies the directory.\n if (mfManifest === undefined && !isLegacyExternal) {\n mfManifest = await verifyOutputDir({isWorkbenchApp, reporter, sourceDir})\n }\n\n const interfaces = workbench ? reportInterfaces(reporter, workbench) : null\n\n const payload: DeployPayload = {\n appId: appId ?? null,\n isAutoUpdating,\n ...(organizationId ? {organizationId} : {}),\n ...(projectId ? {projectId} : {}),\n type: 'studio',\n version,\n ...toWorkbenchPayload(workbench, {interfaces, title: appTitle}),\n }\n\n // Dry run stops here — everything below mutates.\n if (dryRun) return {application: null, payload}\n\n // A real deploy has already exited if anything failed; landing here without a\n // resolved version means the deploy target was never resolved.\n if (!version) return\n\n const studioManifest = await uploadStudioSchema(options, {\n applicationId: workbench ? applicationId : undefined,\n isExternal: isLegacyExternal,\n })\n // The studio was created (or resolved from `deployment.appId`) before the\n // build, so this only ships the deployment; plain studios use user-applications.\n if (workbench && organizationId && applicationId) {\n if (!mfManifest) throw new Error('The federated build produced no manifest.')\n await deployWorkbenchApp({\n access: toAccess(studioManifest),\n app: cliConfig.app,\n applicationId,\n icon: appIcon,\n isApp: false,\n isAutoUpdating,\n isExternal: isExternallyHosted,\n label: 'Deploying studio',\n mfManifest,\n // Once the deployment is live, a metadata-sync failure must not delete\n // the studio.\n onDeployed: () => {\n rollbackApp = undefined\n },\n slug: workbench.slug,\n sourceDir,\n title: appTitle,\n version,\n visibility: workbench.visibility,\n workspaces: toWorkspaces(studioManifest),\n })\n const url = getApplicationUrl({\n id: applicationId,\n organizationId,\n slug: workbench.slug,\n type: 'studio',\n })\n logWorkbenchStudioDeployed({applicationId, cliConfig, output, url})\n if (isExternallyHosted)\n logExternalHost({built: flags.build, organizationId, output, sourceDir})\n return {\n action: applicationCreated ? 'create' : 'update',\n application: workbenchApp ?? null,\n payload,\n url,\n }\n }\n\n if (!application) return\n const location = await shipStudioDeployment({\n application,\n isAutoUpdating,\n isExternal,\n options,\n studioManifest,\n version,\n })\n\n return {\n action: studioCreated ? 'create' : 'update',\n application,\n payload,\n url: location,\n }\n } catch (err) {\n await rollbackApp?.()\n throw err\n }\n}\n\n/**\n * Finds the application a real deploy targets, registering a studio host when\n * none is configured. A dry run resolves and reports the target read-only instead.\n */\nasync function resolveStudioApplication(\n options: DeployAppOptions,\n {dryRun, reporter}: {dryRun: boolean; reporter: DeployCheckReporter},\n): Promise<{application: UserApplication | null; created: boolean}> {\n const {cliConfig, flags, output} = options\n const isExternal = !!flags.external\n const appId = getAppId(cliConfig)\n // Sets the title on a newly registered studio; blank falls back to undefined\n const title = flags.title?.trim() || undefined\n\n if (dryRun) {\n await checkStudioTarget(reporter, {\n appId,\n isExternal,\n projectId: cliConfig.api?.projectId,\n studioHost: cliConfig.studioHost,\n title,\n urlFlag: flags.url,\n })\n return {application: null, created: false}\n }\n\n const projectId = cliConfig.api?.projectId ?? ''\n // `created` is true when a configured-but-unregistered host was just registered.\n const {application, created} = await findUserApplicationForStudio({\n appId,\n isExternal,\n output,\n projectId,\n studioHost: cliConfig.studioHost,\n title,\n unattended: !!flags.yes,\n urlFlag: flags.url,\n })\n\n if (!application) {\n if (isExternal) {\n output.log('Your project has not been registered with an external studio URL.')\n output.log('Please enter the full URL where your studio is hosted.')\n } else {\n output.log('Your project has not been assigned a studio hostname.')\n output.log('To deploy your Sanity Studio to our hosted sanity.studio service,')\n output.log('you will need one. Please enter the subdomain you want to use.')\n }\n\n const registered = await createStudioUserApplication({\n projectId,\n title,\n urlType: isExternal ? 'external' : 'internal',\n })\n deployDebug('Created user application', registered)\n return {application: registered, created: true}\n }\n\n deployDebug('Found user application', application)\n return {application, created}\n}\n\n/** Extracts the studio schema and manifest and uploads them to the schema store. */\nasync function uploadStudioSchema(\n options: DeployAppOptions,\n {applicationId, isExternal}: {applicationId?: string; isExternal: boolean},\n): Promise<StudioManifest | null> {\n const {cliConfig, flags, output, projectRoot, sourceDir} = options\n\n let studioManifest: StudioManifest | null = null\n try {\n studioManifest = await deployStudioSchemasAndManifests(\n {\n applicationId,\n configPath: projectRoot.path,\n isExternal,\n outPath: `${sourceDir}/static`,\n projectId: cliConfig.api?.projectId ?? '',\n schemaRequired: flags['schema-required'],\n verbose: flags.verbose,\n workDir: projectRoot.directory,\n },\n output,\n )\n } catch (error) {\n deployDebug('Error deploying studio schemas and manifests', error)\n if (error instanceof SchemaExtractionError && error.validation?.length) {\n output.error(formatSchemaValidation(error.validation), {exit: exitCodes.RUNTIME_ERROR})\n }\n output.error(`Error deploying studio schemas and manifests: ${error}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (!studioManifest) {\n output.error('Failed to generate studio manifest. Please check your schemas and manifests.', {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n return studioManifest\n}\n\nasync function shipStudioDeployment({\n application,\n isAutoUpdating,\n isExternal,\n options,\n studioManifest,\n version,\n}: {\n application: UserApplication\n isAutoUpdating: boolean\n isExternal: boolean\n options: DeployAppOptions\n studioManifest: StudioManifest | null\n version: string\n}): Promise<string> {\n const {cliConfig, output, sourceDir} = options\n\n let tarball: Gzip | undefined\n if (!isExternal) {\n tarball = createTar({cwd: dirname(sourceDir)}, [basename(sourceDir)]).pipe(createGzip())\n }\n\n const spin = spinner(isExternal ? 'Registering studio' : 'Deploying to sanity.studio').start()\n let location: string\n try {\n ;({location} = await createDeployment({\n applicationId: application.id,\n isApp: false,\n isAutoUpdating,\n manifest: studioManifest,\n projectId: cliConfig.api?.projectId,\n tarball,\n version,\n }))\n } catch (error) {\n spin.fail()\n throw error\n }\n spin.succeed()\n\n const named = application.title ? ` — \"${application.title}\"` : ''\n output.log(\n isExternal\n ? `\\nSuccess! Studio registered${named}`\n : `\\nSuccess! Studio deployed to ${styleText('cyan', location)}${named}`,\n )\n\n if (getAppId(cliConfig)) return location\n\n const example = `Example:\nexport default defineCliConfig({\n //…\n deployment: {\n ${styleText('cyan', `appId: '${application.id}'`)},\n },\n //…\n})`\n output.log(`\\nAdd ${styleText('cyan', `appId: '${application.id}'`)}`)\n output.log(`to the \\`deployment\\` section in sanity.cli.js or sanity.cli.ts`)\n output.log(`to avoid prompting for application id on next deploy.`)\n output.log(`\\n${example}`)\n\n return location\n}\n\n/**\n * One `datasets` access entry per unique workspace dataset, with a `resourceId`\n * of `\"<projectId>.<dataset>\"`. Deduped, since workspaces can share a dataset.\n */\nfunction toAccess(manifest: StudioManifest | null): BrettAccess[] {\n const resourceIds = new Set(\n (manifest?.workspaces ?? []).map((w) => `${w.projectId}.${w.dataset}`),\n )\n return [...resourceIds].map(\n (resourceId) => ({resourceId, resourceType: 'dataset'}) satisfies BrettAccess,\n )\n}\n\nfunction toWorkspaces(manifest: StudioManifest | null): BrettWorkspace[] {\n return (manifest?.workspaces ?? []).map((workspace) => ({\n basePath: workspace.basePath,\n dataset: workspace.dataset,\n icon: workspace.icon,\n name: workspace.name,\n projectId: workspace.projectId,\n schemaDescriptorId: workspace.schemaDescriptorId,\n subtitle: workspace.subtitle,\n title: workspace.title,\n }))\n}\n\n/** Renders the workbench studio's deploy result; the appId hint shows only when none is configured. */\nfunction logWorkbenchStudioDeployed({\n applicationId,\n cliConfig,\n output,\n url,\n}: {\n applicationId: string\n cliConfig: DeployAppOptions['cliConfig']\n output: DeployAppOptions['output']\n url: string\n}): void {\n output.log(`\\nSuccess! Studio deployed to ${styleText('cyan', url)}`)\n if (getAppId(cliConfig)) return\n\n output.log(`\\nAdd ${styleText('cyan', `appId: '${applicationId}'`)}`)\n output.log(`to the \\`deployment\\` section in sanity.cli.js or sanity.cli.ts`)\n output.log(`to avoid prompting for application id on next deploy.`)\n}\n\n/** Tells the customer what their host must do for the Dashboard to load the studio from it. */\nfunction logExternalHost({\n built,\n organizationId,\n output,\n sourceDir,\n}: {\n built: boolean\n organizationId: string\n output: DeployAppOptions['output']\n sourceDir: string\n}): void {\n const dir = `${relative(process.cwd(), sourceDir) || '.'}/`\n output.log(`\nThe Dashboard loads this studio from your host, which must:\n 1. Serve ${dir} unchanged at the root of its URL (/mf-manifest.json, /remoteEntry-*.js, /static/*)\n 2. Send Access-Control-Allow-Origin for ${getWorkbenchUrl(organizationId)}\n 3. Respond without cookies or a sign-in${built ? `\\n\\nThis deploy rebuilt ${dir}: copy it to your host before opening the studio in the Dashboard.` : ''}`)\n}\n\nfunction studioBuildSkipReason({\n build,\n isLegacyExternal,\n}: {\n build: boolean\n isLegacyExternal: boolean\n}) {\n if (isLegacyExternal) return 'Build skipped for externally hosted studios'\n if (!build) return 'Build skipped (--no-build) — validating existing output directory'\n return\n}\n"],"names":["basename","dirname","relative","styleText","createGzip","formatSchemaValidation","SchemaExtractionError","readIconFromPath","exitCodes","spinner","createStudio","deployWorkbenchApp","getApplicationUrl","getWorkbench","getWorkbenchUrl","toWorkbenchPayload","c","createTar","createDeployment","getAppId","NO_ORGANIZATION_ID","NO_PROJECT_ID","buildStudio","checkBlueprintManaged","createStudioUserApplication","checkAutoUpdates","checkBuild","checkExternalUrl","checkPackageVersion","checkStudioTarget","verifyOutputDir","deployDebug","listDeploymentFiles","reportInterfaces","runDeploy","deployStudioSchemasAndManifests","findUserApplicationForStudio","STUDIO_PACKAGE","deployStudio","options","listFiles","flags","projectRoot","sourceDir","external","Promise","resolve","directory","run","runStudioDeployment","type","reporter","cliConfig","output","workDir","isExternal","workbench","isWorkbenchApp","projectId","api","organizationId","app","appId","dryRun","isLegacyExternal","appTitle","title","trim","slug","isAutoUpdating","version","moduleName","report","message","status","solution","kind","projectRootDir","application","studioCreated","workbenchApp","externalUrl","url","created","resolveStudioApplication","isExternallyHosted","build","exitCode","USAGE_ERROR","appIcon","icon","undefined","applicationId","applicationCreated","rollbackApp","name","visibility","id","rollback","built","autoUpdatesEnabled","calledFromDeploy","outDir","skipReason","studioBuildSkipReason","successMessage","mfManifest","interfaces","payload","studioManifest","uploadStudioSchema","Error","access","toAccess","isApp","label","onDeployed","workspaces","toWorkspaces","logWorkbenchStudioDeployed","logExternalHost","action","location","shipStudioDeployment","err","studioHost","urlFlag","unattended","yes","log","registered","urlType","configPath","path","outPath","schemaRequired","verbose","error","validation","length","exit","RUNTIME_ERROR","tarball","cwd","pipe","spin","start","manifest","fail","succeed","named","example","resourceIds","Set","map","w","dataset","resourceId","resourceType","workspace","basePath","schemaDescriptorId","subtitle","dir","process"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/deploy/deployStudio.ts"],"sourcesContent":["import {basename, dirname, relative} from 'node:path'\nimport {styleText} from 'node:util'\nimport {createGzip, type Gzip} from 'node:zlib'\n\nimport {formatSchemaValidation, SchemaExtractionError} from '@sanity/cli-build/_internal/extract'\nimport {readIconFromPath} from '@sanity/cli-build/_internal/manifest'\nimport {exitCodes} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {\n type BrettAccess,\n type BrettWorkspace,\n createStudio,\n deployWorkbenchApp,\n getApplicationUrl,\n getWorkbench,\n getWorkbenchUrl,\n selectWorkbenchAppId,\n toWorkbenchPayload,\n} from '@sanity/workbench-cli/deploy'\nimport {type StudioManifest} from 'sanity'\nimport {c as createTar} from 'tar'\n\nimport {createDeployment, type UserApplication} from '../../services/userApplications.js'\nimport {getAppId} from '../../util/appId.js'\nimport {NO_ORGANIZATION_ID, NO_PROJECT_ID} from '../../util/errorMessages.js'\nimport {buildStudio} from '../build/buildStudio.js'\nimport {checkBlueprintManaged} from './blueprintManaged.js'\nimport {createStudioUserApplication} from './createUserApplication.js'\nimport {\n checkAutoUpdates,\n checkBuild,\n checkExternalUrl,\n checkPackageVersion,\n checkStudioTarget,\n type DeployCheckReporter,\n verifyOutputDir,\n} from './deployChecks.js'\nimport {deployDebug} from './deployDebug.js'\nimport {listDeploymentFiles, reportInterfaces} from './deploymentPlan.js'\nimport {type DeployPayload, type DeployResult, runDeploy} from './deployRunner.js'\nimport {deployStudioSchemasAndManifests} from './deployStudioSchemasAndManifests.js'\nimport {findUserApplicationForStudio} from './findUserApplication.js'\nimport {type DeployAppOptions} from './types.js'\n\nconst STUDIO_PACKAGE = 'sanity'\n\nexport function deployStudio(options: DeployAppOptions): Promise<void> {\n return runDeploy(options, {\n listFiles: ({flags, projectRoot, sourceDir}) =>\n flags.external ? Promise.resolve([]) : listDeploymentFiles(sourceDir, projectRoot.directory),\n run: runStudioDeployment,\n type: 'studio',\n })\n}\n\n/** Validates the deploy, extracts and uploads the schema, and ships the build. */\nasync function runStudioDeployment(\n options: DeployAppOptions,\n reporter: DeployCheckReporter,\n): Promise<DeployResult | void> {\n const {cliConfig, flags, output, sourceDir} = options\n const workDir = options.projectRoot.directory\n const isExternal = !!flags.external\n const workbench = getWorkbench(cliConfig)\n const isWorkbenchApp = workbench !== null\n const projectId = cliConfig.api?.projectId\n const organizationId = cliConfig.app?.organizationId\n const appId = getAppId(cliConfig)\n const dryRun = !!flags['dry-run']\n // A legacy external studio only registers its URL; a federated one is built\n // and deployed like a hosted one, minus the upload.\n const isLegacyExternal = isExternal && !isWorkbenchApp\n\n const appTitle = workbench\n ? flags.title?.trim() || cliConfig.app?.title?.trim() || workbench.slug\n : ''\n\n const isAutoUpdating = checkAutoUpdates(reporter, {cliConfig, flags})\n\n const version = await checkPackageVersion(reporter, {\n moduleName: STUDIO_PACKAGE,\n workDir,\n })\n\n reporter.report(\n projectId\n ? {message: `Project: ${projectId}`, status: 'pass'}\n : {\n message: NO_PROJECT_ID,\n solution: 'Add `api.projectId` to sanity.cli.ts',\n status: 'fail',\n },\n )\n\n await checkBlueprintManaged(reporter, {kind: 'studio', projectRootDir: workDir})\n\n // Workbench studios deploy to Brett (which needs the org); plain studios\n // resolve/create on user-applications, unchanged.\n let application: UserApplication | null = null\n let studioCreated = false\n let workbenchApp: {externalUrl?: string} | undefined\n let externalUrl: string | undefined\n let targetAppId = appId\n if (workbench) {\n reporter.report(\n organizationId\n ? {message: `Organization: ${organizationId}`, status: 'pass'}\n : {\n message: NO_ORGANIZATION_ID,\n solution: 'Add `app.organizationId` to sanity.cli.ts',\n status: 'fail',\n },\n )\n targetAppId = await selectWorkbenchAppId({appId, flags, organizationId, type: 'studio'})\n workbenchApp = (\n await checkStudioTarget(reporter, {\n appId: targetAppId,\n isWorkbenchApp: true,\n organizationId,\n slug: workbench.slug,\n title: appTitle,\n })\n )?.application\n if (isExternal) externalUrl = checkExternalUrl(reporter, {appId: targetAppId, url: flags.url})\n } else {\n ;({application, created: studioCreated} = await resolveStudioApplication(options, {\n dryRun,\n reporter,\n }))\n }\n // A redeploy follows how the application was registered, so --external is only needed once.\n const isExternallyHosted = isExternal || !!workbenchApp?.externalUrl\n\n // A first deploy mints the app id and the build inlines it; --no-build would\n // ship an existing bundle carrying a different id, so it can't be a first deploy.\n if (workbench && !appId && !flags.build) {\n reporter.report({\n exitCode: exitCodes.USAGE_ERROR,\n message: 'A first deploy cannot skip the build (--no-build)',\n solution: 'Drop --no-build so the new application id is inlined into the build',\n status: 'fail',\n })\n }\n\n // Read up front so a bad icon path fails before we create or build.\n const appIcon =\n !dryRun && workbench?.icon ? await readIconFromPath(workDir, workbench.icon) : undefined\n\n // Create the studio before the build so the bundle carries its real id. A\n // redeploy already has it from `deployment.appId`; a dry run skips creation.\n let applicationId = targetAppId\n let applicationCreated = false\n let rollbackApp: (() => Promise<void>) | undefined\n if (!dryRun && workbench && organizationId && !applicationId) {\n const created = await createStudio({\n externalUrl,\n name: workbench.name,\n organizationId,\n projectId,\n slug: workbench.slug,\n title: appTitle,\n visibility: workbench.visibility,\n })\n workbenchApp = created.application\n applicationId = created.application.id\n rollbackApp = created.rollback\n applicationCreated = true\n }\n\n // A record created above is stranded at its slug (and blocks retries) if any\n // step before it fully deploys fails, so undo the creation on failure.\n try {\n const built = await checkBuild(reporter, {\n build: () =>\n buildStudio({\n applicationId: workbench ? applicationId : undefined,\n autoUpdatesEnabled: isAutoUpdating,\n calledFromDeploy: true,\n cliConfig,\n flags,\n outDir: sourceDir,\n output,\n workDir,\n }),\n skipReason: studioBuildSkipReason({build: flags.build, isLegacyExternal}),\n successMessage: 'Studio built',\n })\n\n let mfManifest = built?.mfManifest\n // A federated build has already read its manifest; anything else verifies the directory.\n if (mfManifest === undefined && !isLegacyExternal) {\n mfManifest = await verifyOutputDir({isWorkbenchApp, reporter, sourceDir})\n }\n\n const interfaces = workbench ? reportInterfaces(reporter, workbench) : null\n\n const payload: DeployPayload = {\n appId: appId ?? null,\n isAutoUpdating,\n ...(organizationId ? {organizationId} : {}),\n ...(projectId ? {projectId} : {}),\n type: 'studio',\n version,\n ...toWorkbenchPayload(workbench, {interfaces, title: appTitle}),\n }\n\n // Dry run stops here — everything below mutates.\n if (dryRun) return {application: null, payload}\n\n // A real deploy has already exited if anything failed; landing here without a\n // resolved version means the deploy target was never resolved.\n if (!version) return\n\n const studioManifest = await uploadStudioSchema(options, {\n applicationId: workbench ? applicationId : undefined,\n isExternal: isLegacyExternal,\n })\n // The studio was created (or resolved from `deployment.appId`) before the\n // build, so this only ships the deployment; plain studios use user-applications.\n if (workbench && organizationId && applicationId) {\n if (!mfManifest) throw new Error('The federated build produced no manifest.')\n await deployWorkbenchApp({\n access: toAccess(studioManifest),\n app: cliConfig.app,\n applicationId,\n icon: appIcon,\n isApp: false,\n isAutoUpdating,\n isExternal: isExternallyHosted,\n label: 'Deploying studio',\n mfManifest,\n // Once the deployment is live, a metadata-sync failure must not delete\n // the studio.\n onDeployed: () => {\n rollbackApp = undefined\n },\n slug: workbench.slug,\n sourceDir,\n title: appTitle,\n version,\n visibility: workbench.visibility,\n workspaces: toWorkspaces(studioManifest),\n })\n const url = getApplicationUrl({\n id: applicationId,\n organizationId,\n slug: workbench.slug,\n type: 'studio',\n })\n logWorkbenchStudioDeployed({applicationId, cliConfig, output, url})\n if (isExternallyHosted)\n logExternalHost({built: flags.build, organizationId, output, sourceDir})\n return {\n action: applicationCreated ? 'create' : 'update',\n application: workbenchApp ?? null,\n payload,\n url,\n }\n }\n\n if (!application) return\n const location = await shipStudioDeployment({\n application,\n isAutoUpdating,\n isExternal,\n options,\n studioManifest,\n version,\n })\n\n return {\n action: studioCreated ? 'create' : 'update',\n application,\n payload,\n url: location,\n }\n } catch (err) {\n await rollbackApp?.()\n throw err\n }\n}\n\n/**\n * Finds the application a real deploy targets, registering a studio host when\n * none is configured. A dry run resolves and reports the target read-only instead.\n */\nasync function resolveStudioApplication(\n options: DeployAppOptions,\n {dryRun, reporter}: {dryRun: boolean; reporter: DeployCheckReporter},\n): Promise<{application: UserApplication | null; created: boolean}> {\n const {cliConfig, flags, output} = options\n const isExternal = !!flags.external\n const appId = getAppId(cliConfig)\n // Sets the title on a newly registered studio; blank falls back to undefined\n const title = flags.title?.trim() || undefined\n\n if (dryRun) {\n await checkStudioTarget(reporter, {\n appId,\n isExternal,\n projectId: cliConfig.api?.projectId,\n studioHost: cliConfig.studioHost,\n title,\n urlFlag: flags.url,\n })\n return {application: null, created: false}\n }\n\n const projectId = cliConfig.api?.projectId ?? ''\n // `created` is true when a configured-but-unregistered host was just registered.\n const {application, created} = await findUserApplicationForStudio({\n appId,\n isExternal,\n output,\n projectId,\n studioHost: cliConfig.studioHost,\n title,\n unattended: !!flags.yes,\n urlFlag: flags.url,\n })\n\n if (!application) {\n if (isExternal) {\n output.log('Your project has not been registered with an external studio URL.')\n output.log('Please enter the full URL where your studio is hosted.')\n } else {\n output.log('Your project has not been assigned a studio hostname.')\n output.log('To deploy your Sanity Studio to our hosted sanity.studio service,')\n output.log('you will need one. Please enter the subdomain you want to use.')\n }\n\n const registered = await createStudioUserApplication({\n projectId,\n title,\n urlType: isExternal ? 'external' : 'internal',\n })\n deployDebug('Created user application', registered)\n return {application: registered, created: true}\n }\n\n deployDebug('Found user application', application)\n return {application, created}\n}\n\n/** Extracts the studio schema and manifest and uploads them to the schema store. */\nasync function uploadStudioSchema(\n options: DeployAppOptions,\n {applicationId, isExternal}: {applicationId?: string; isExternal: boolean},\n): Promise<StudioManifest | null> {\n const {cliConfig, flags, output, projectRoot, sourceDir} = options\n\n let studioManifest: StudioManifest | null = null\n try {\n studioManifest = await deployStudioSchemasAndManifests(\n {\n applicationId,\n configPath: projectRoot.path,\n isExternal,\n outPath: `${sourceDir}/static`,\n projectId: cliConfig.api?.projectId ?? '',\n schemaRequired: flags['schema-required'],\n verbose: flags.verbose,\n workDir: projectRoot.directory,\n },\n output,\n )\n } catch (error) {\n deployDebug('Error deploying studio schemas and manifests', error)\n if (error instanceof SchemaExtractionError && error.validation?.length) {\n output.error(formatSchemaValidation(error.validation), {exit: exitCodes.RUNTIME_ERROR})\n }\n output.error(`Error deploying studio schemas and manifests: ${error}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (!studioManifest) {\n output.error('Failed to generate studio manifest. Please check your schemas and manifests.', {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n return studioManifest\n}\n\nasync function shipStudioDeployment({\n application,\n isAutoUpdating,\n isExternal,\n options,\n studioManifest,\n version,\n}: {\n application: UserApplication\n isAutoUpdating: boolean\n isExternal: boolean\n options: DeployAppOptions\n studioManifest: StudioManifest | null\n version: string\n}): Promise<string> {\n const {cliConfig, output, sourceDir} = options\n\n let tarball: Gzip | undefined\n if (!isExternal) {\n tarball = createTar({cwd: dirname(sourceDir)}, [basename(sourceDir)]).pipe(createGzip())\n }\n\n const spin = spinner(isExternal ? 'Registering studio' : 'Deploying to sanity.studio').start()\n let location: string\n try {\n ;({location} = await createDeployment({\n applicationId: application.id,\n isApp: false,\n isAutoUpdating,\n manifest: studioManifest,\n projectId: cliConfig.api?.projectId,\n tarball,\n version,\n }))\n } catch (error) {\n spin.fail()\n throw error\n }\n spin.succeed()\n\n const named = application.title ? ` — \"${application.title}\"` : ''\n output.log(\n isExternal\n ? `\\nSuccess! Studio registered${named}`\n : `\\nSuccess! Studio deployed to ${styleText('cyan', location)}${named}`,\n )\n\n if (getAppId(cliConfig)) return location\n\n const example = `Example:\nexport default defineCliConfig({\n //…\n deployment: {\n ${styleText('cyan', `appId: '${application.id}'`)},\n },\n //…\n})`\n output.log(`\\nAdd ${styleText('cyan', `appId: '${application.id}'`)}`)\n output.log(`to the \\`deployment\\` section in sanity.cli.js or sanity.cli.ts`)\n output.log(`to avoid prompting for application id on next deploy.`)\n output.log(`\\n${example}`)\n\n return location\n}\n\n/**\n * One `datasets` access entry per unique workspace dataset, with a `resourceId`\n * of `\"<projectId>.<dataset>\"`. Deduped, since workspaces can share a dataset.\n */\nfunction toAccess(manifest: StudioManifest | null): BrettAccess[] {\n const resourceIds = new Set(\n (manifest?.workspaces ?? []).map((w) => `${w.projectId}.${w.dataset}`),\n )\n return [...resourceIds].map(\n (resourceId) => ({resourceId, resourceType: 'dataset'}) satisfies BrettAccess,\n )\n}\n\nfunction toWorkspaces(manifest: StudioManifest | null): BrettWorkspace[] {\n return (manifest?.workspaces ?? []).map((workspace) => ({\n basePath: workspace.basePath,\n dataset: workspace.dataset,\n icon: workspace.icon,\n name: workspace.name,\n projectId: workspace.projectId,\n schemaDescriptorId: workspace.schemaDescriptorId,\n subtitle: workspace.subtitle,\n title: workspace.title,\n }))\n}\n\n/** Renders the workbench studio's deploy result; the appId hint shows only when none is configured. */\nfunction logWorkbenchStudioDeployed({\n applicationId,\n cliConfig,\n output,\n url,\n}: {\n applicationId: string\n cliConfig: DeployAppOptions['cliConfig']\n output: DeployAppOptions['output']\n url: string\n}): void {\n output.log(`\\nSuccess! Studio deployed to ${styleText('cyan', url)}`)\n if (getAppId(cliConfig)) return\n\n output.log(`\\nAdd ${styleText('cyan', `appId: '${applicationId}'`)}`)\n output.log(`to the \\`deployment\\` section in sanity.cli.js or sanity.cli.ts`)\n output.log(`to avoid prompting for application id on next deploy.`)\n}\n\n/** Tells the customer what their host must do for the Dashboard to load the studio from it. */\nfunction logExternalHost({\n built,\n organizationId,\n output,\n sourceDir,\n}: {\n built: boolean\n organizationId: string\n output: DeployAppOptions['output']\n sourceDir: string\n}): void {\n const dir = `${relative(process.cwd(), sourceDir) || '.'}/`\n output.log(`\nThe Dashboard loads this studio from your host, which must:\n 1. Serve ${dir} unchanged at the root of its URL (/mf-manifest.json, /remoteEntry-*.js, /static/*)\n 2. Send Access-Control-Allow-Origin for ${getWorkbenchUrl(organizationId)}\n 3. Respond without cookies or a sign-in${built ? `\\n\\nThis deploy rebuilt ${dir}: copy it to your host before opening the studio in the Dashboard.` : ''}`)\n}\n\nfunction studioBuildSkipReason({\n build,\n isLegacyExternal,\n}: {\n build: boolean\n isLegacyExternal: boolean\n}) {\n if (isLegacyExternal) return 'Build skipped for externally hosted studios'\n if (!build) return 'Build skipped (--no-build) — validating existing output directory'\n return\n}\n"],"names":["basename","dirname","relative","styleText","createGzip","formatSchemaValidation","SchemaExtractionError","readIconFromPath","exitCodes","spinner","createStudio","deployWorkbenchApp","getApplicationUrl","getWorkbench","getWorkbenchUrl","selectWorkbenchAppId","toWorkbenchPayload","c","createTar","createDeployment","getAppId","NO_ORGANIZATION_ID","NO_PROJECT_ID","buildStudio","checkBlueprintManaged","createStudioUserApplication","checkAutoUpdates","checkBuild","checkExternalUrl","checkPackageVersion","checkStudioTarget","verifyOutputDir","deployDebug","listDeploymentFiles","reportInterfaces","runDeploy","deployStudioSchemasAndManifests","findUserApplicationForStudio","STUDIO_PACKAGE","deployStudio","options","listFiles","flags","projectRoot","sourceDir","external","Promise","resolve","directory","run","runStudioDeployment","type","reporter","cliConfig","output","workDir","isExternal","workbench","isWorkbenchApp","projectId","api","organizationId","app","appId","dryRun","isLegacyExternal","appTitle","title","trim","slug","isAutoUpdating","version","moduleName","report","message","status","solution","kind","projectRootDir","application","studioCreated","workbenchApp","externalUrl","targetAppId","url","created","resolveStudioApplication","isExternallyHosted","build","exitCode","USAGE_ERROR","appIcon","icon","undefined","applicationId","applicationCreated","rollbackApp","name","visibility","id","rollback","built","autoUpdatesEnabled","calledFromDeploy","outDir","skipReason","studioBuildSkipReason","successMessage","mfManifest","interfaces","payload","studioManifest","uploadStudioSchema","Error","access","toAccess","isApp","label","onDeployed","workspaces","toWorkspaces","logWorkbenchStudioDeployed","logExternalHost","action","location","shipStudioDeployment","err","studioHost","urlFlag","unattended","yes","log","registered","urlType","configPath","path","outPath","schemaRequired","verbose","error","validation","length","exit","RUNTIME_ERROR","tarball","cwd","pipe","spin","start","manifest","fail","succeed","named","example","resourceIds","Set","map","w","dataset","resourceId","resourceType","workspace","basePath","schemaDescriptorId","subtitle","dir","process"],"mappings":"AAAA,SAAQA,QAAQ,EAAEC,OAAO,EAAEC,QAAQ,QAAO,YAAW;AACrD,SAAQC,SAAS,QAAO,YAAW;AACnC,SAAQC,UAAU,QAAkB,YAAW;AAE/C,SAAQC,sBAAsB,EAAEC,qBAAqB,QAAO,sCAAqC;AACjG,SAAQC,gBAAgB,QAAO,uCAAsC;AACrE,SAAQC,SAAS,QAAO,mBAAkB;AAC1C,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,SAGEC,YAAY,EACZC,kBAAkB,EAClBC,iBAAiB,EACjBC,YAAY,EACZC,eAAe,EACfC,oBAAoB,EACpBC,kBAAkB,QACb,+BAA8B;AAErC,SAAQC,KAAKC,SAAS,QAAO,MAAK;AAElC,SAAQC,gBAAgB,QAA6B,qCAAoC;AACzF,SAAQC,QAAQ,QAAO,sBAAqB;AAC5C,SAAQC,kBAAkB,EAAEC,aAAa,QAAO,8BAA6B;AAC7E,SAAQC,WAAW,QAAO,0BAAyB;AACnD,SAAQC,qBAAqB,QAAO,wBAAuB;AAC3D,SAAQC,2BAA2B,QAAO,6BAA4B;AACtE,SACEC,gBAAgB,EAChBC,UAAU,EACVC,gBAAgB,EAChBC,mBAAmB,EACnBC,iBAAiB,EAEjBC,eAAe,QACV,oBAAmB;AAC1B,SAAQC,WAAW,QAAO,mBAAkB;AAC5C,SAAQC,mBAAmB,EAAEC,gBAAgB,QAAO,sBAAqB;AACzE,SAA+CC,SAAS,QAAO,oBAAmB;AAClF,SAAQC,+BAA+B,QAAO,uCAAsC;AACpF,SAAQC,4BAA4B,QAAO,2BAA0B;AAGrE,MAAMC,iBAAiB;AAEvB,OAAO,SAASC,aAAaC,OAAyB;IACpD,OAAOL,UAAUK,SAAS;QACxBC,WAAW,CAAC,EAACC,KAAK,EAAEC,WAAW,EAAEC,SAAS,EAAC,GACzCF,MAAMG,QAAQ,GAAGC,QAAQC,OAAO,CAAC,EAAE,IAAId,oBAAoBW,WAAWD,YAAYK,SAAS;QAC7FC,KAAKC;QACLC,MAAM;IACR;AACF;AAEA,gFAAgF,GAChF,eAAeD,oBACbV,OAAyB,EACzBY,QAA6B;IAE7B,MAAM,EAACC,SAAS,EAAEX,KAAK,EAAEY,MAAM,EAAEV,SAAS,EAAC,GAAGJ;IAC9C,MAAMe,UAAUf,QAAQG,WAAW,CAACK,SAAS;IAC7C,MAAMQ,aAAa,CAAC,CAACd,MAAMG,QAAQ;IACnC,MAAMY,YAAY5C,aAAawC;IAC/B,MAAMK,iBAAiBD,cAAc;IACrC,MAAME,YAAYN,UAAUO,GAAG,EAAED;IACjC,MAAME,iBAAiBR,UAAUS,GAAG,EAAED;IACtC,MAAME,QAAQ3C,SAASiC;IACvB,MAAMW,SAAS,CAAC,CAACtB,KAAK,CAAC,UAAU;IACjC,4EAA4E;IAC5E,oDAAoD;IACpD,MAAMuB,mBAAmBT,cAAc,CAACE;IAExC,MAAMQ,WAAWT,YACbf,MAAMyB,KAAK,EAAEC,UAAUf,UAAUS,GAAG,EAAEK,OAAOC,UAAUX,UAAUY,IAAI,GACrE;IAEJ,MAAMC,iBAAiB5C,iBAAiB0B,UAAU;QAACC;QAAWX;IAAK;IAEnE,MAAM6B,UAAU,MAAM1C,oBAAoBuB,UAAU;QAClDoB,YAAYlC;QACZiB;IACF;IAEAH,SAASqB,MAAM,CACbd,YACI;QAACe,SAAS,CAAC,SAAS,EAAEf,WAAW;QAAEgB,QAAQ;IAAM,IACjD;QACED,SAASpD;QACTsD,UAAU;QACVD,QAAQ;IACV;IAGN,MAAMnD,sBAAsB4B,UAAU;QAACyB,MAAM;QAAUC,gBAAgBvB;IAAO;IAE9E,yEAAyE;IACzE,kDAAkD;IAClD,IAAIwB,cAAsC;IAC1C,IAAIC,gBAAgB;IACpB,IAAIC;IACJ,IAAIC;IACJ,IAAIC,cAAcpB;IAClB,IAAIN,WAAW;QACbL,SAASqB,MAAM,CACbZ,iBACI;YAACa,SAAS,CAAC,cAAc,EAAEb,gBAAgB;YAAEc,QAAQ;QAAM,IAC3D;YACED,SAASrD;YACTuD,UAAU;YACVD,QAAQ;QACV;QAENQ,cAAc,MAAMpE,qBAAqB;YAACgD;YAAOrB;YAAOmB;YAAgBV,MAAM;QAAQ;QACtF8B,eACE,CAAA,MAAMnD,kBAAkBsB,UAAU;YAChCW,OAAOoB;YACPzB,gBAAgB;YAChBG;YACAQ,MAAMZ,UAAUY,IAAI;YACpBF,OAAOD;QACT,EAAC,GACAa;QACH,IAAIvB,YAAY0B,cAActD,iBAAiBwB,UAAU;YAACW,OAAOoB;YAAaC,KAAK1C,MAAM0C,GAAG;QAAA;IAC9F,OAAO;;QACH,CAAA,EAACL,WAAW,EAAEM,SAASL,aAAa,EAAC,GAAG,MAAMM,yBAAyB9C,SAAS;YAChFwB;YACAZ;QACF,EAAC;IACH;IACA,4FAA4F;IAC5F,MAAMmC,qBAAqB/B,cAAc,CAAC,CAACyB,cAAcC;IAEzD,6EAA6E;IAC7E,kFAAkF;IAClF,IAAIzB,aAAa,CAACM,SAAS,CAACrB,MAAM8C,KAAK,EAAE;QACvCpC,SAASqB,MAAM,CAAC;YACdgB,UAAUjF,UAAUkF,WAAW;YAC/BhB,SAAS;YACTE,UAAU;YACVD,QAAQ;QACV;IACF;IAEA,oEAAoE;IACpE,MAAMgB,UACJ,CAAC3B,UAAUP,WAAWmC,OAAO,MAAMrF,iBAAiBgD,SAASE,UAAUmC,IAAI,IAAIC;IAEjF,0EAA0E;IAC1E,6EAA6E;IAC7E,IAAIC,gBAAgBX;IACpB,IAAIY,qBAAqB;IACzB,IAAIC;IACJ,IAAI,CAAChC,UAAUP,aAAaI,kBAAkB,CAACiC,eAAe;QAC5D,MAAMT,UAAU,MAAM3E,aAAa;YACjCwE;YACAe,MAAMxC,UAAUwC,IAAI;YACpBpC;YACAF;YACAU,MAAMZ,UAAUY,IAAI;YACpBF,OAAOD;YACPgC,YAAYzC,UAAUyC,UAAU;QAClC;QACAjB,eAAeI,QAAQN,WAAW;QAClCe,gBAAgBT,QAAQN,WAAW,CAACoB,EAAE;QACtCH,cAAcX,QAAQe,QAAQ;QAC9BL,qBAAqB;IACvB;IAEA,6EAA6E;IAC7E,uEAAuE;IACvE,IAAI;QACF,MAAMM,QAAQ,MAAM1E,WAAWyB,UAAU;YACvCoC,OAAO,IACLjE,YAAY;oBACVuE,eAAerC,YAAYqC,gBAAgBD;oBAC3CS,oBAAoBhC;oBACpBiC,kBAAkB;oBAClBlD;oBACAX;oBACA8D,QAAQ5D;oBACRU;oBACAC;gBACF;YACFkD,YAAYC,sBAAsB;gBAAClB,OAAO9C,MAAM8C,KAAK;gBAAEvB;YAAgB;YACvE0C,gBAAgB;QAClB;QAEA,IAAIC,aAAaP,OAAOO;QACxB,yFAAyF;QACzF,IAAIA,eAAef,aAAa,CAAC5B,kBAAkB;YACjD2C,aAAa,MAAM7E,gBAAgB;gBAAC2B;gBAAgBN;gBAAUR;YAAS;QACzE;QAEA,MAAMiE,aAAapD,YAAYvB,iBAAiBkB,UAAUK,aAAa;QAEvE,MAAMqD,UAAyB;YAC7B/C,OAAOA,SAAS;YAChBO;YACA,GAAIT,iBAAiB;gBAACA;YAAc,IAAI,CAAC,CAAC;YAC1C,GAAIF,YAAY;gBAACA;YAAS,IAAI,CAAC,CAAC;YAChCR,MAAM;YACNoB;YACA,GAAGvD,mBAAmByC,WAAW;gBAACoD;gBAAY1C,OAAOD;YAAQ,EAAE;QACjE;QAEA,iDAAiD;QACjD,IAAIF,QAAQ,OAAO;YAACe,aAAa;YAAM+B;QAAO;QAE9C,8EAA8E;QAC9E,+DAA+D;QAC/D,IAAI,CAACvC,SAAS;QAEd,MAAMwC,iBAAiB,MAAMC,mBAAmBxE,SAAS;YACvDsD,eAAerC,YAAYqC,gBAAgBD;YAC3CrC,YAAYS;QACd;QACA,0EAA0E;QAC1E,iFAAiF;QACjF,IAAIR,aAAaI,kBAAkBiC,eAAe;YAChD,IAAI,CAACc,YAAY,MAAM,IAAIK,MAAM;YACjC,MAAMtG,mBAAmB;gBACvBuG,QAAQC,SAASJ;gBACjBjD,KAAKT,UAAUS,GAAG;gBAClBgC;gBACAF,MAAMD;gBACNyB,OAAO;gBACP9C;gBACAd,YAAY+B;gBACZ8B,OAAO;gBACPT;gBACA,uEAAuE;gBACvE,cAAc;gBACdU,YAAY;oBACVtB,cAAcH;gBAChB;gBACAxB,MAAMZ,UAAUY,IAAI;gBACpBzB;gBACAuB,OAAOD;gBACPK;gBACA2B,YAAYzC,UAAUyC,UAAU;gBAChCqB,YAAYC,aAAaT;YAC3B;YACA,MAAM3B,MAAMxE,kBAAkB;gBAC5BuF,IAAIL;gBACJjC;gBACAQ,MAAMZ,UAAUY,IAAI;gBACpBlB,MAAM;YACR;YACAsE,2BAA2B;gBAAC3B;gBAAezC;gBAAWC;gBAAQ8B;YAAG;YACjE,IAAIG,oBACFmC,gBAAgB;gBAACrB,OAAO3D,MAAM8C,KAAK;gBAAE3B;gBAAgBP;gBAAQV;YAAS;YACxE,OAAO;gBACL+E,QAAQ5B,qBAAqB,WAAW;gBACxChB,aAAaE,gBAAgB;gBAC7B6B;gBACA1B;YACF;QACF;QAEA,IAAI,CAACL,aAAa;QAClB,MAAM6C,WAAW,MAAMC,qBAAqB;YAC1C9C;YACAT;YACAd;YACAhB;YACAuE;YACAxC;QACF;QAEA,OAAO;YACLoD,QAAQ3C,gBAAgB,WAAW;YACnCD;YACA+B;YACA1B,KAAKwC;QACP;IACF,EAAE,OAAOE,KAAK;QACZ,MAAM9B;QACN,MAAM8B;IACR;AACF;AAEA;;;CAGC,GACD,eAAexC,yBACb9C,OAAyB,EACzB,EAACwB,MAAM,EAAEZ,QAAQ,EAAmD;IAEpE,MAAM,EAACC,SAAS,EAAEX,KAAK,EAAEY,MAAM,EAAC,GAAGd;IACnC,MAAMgB,aAAa,CAAC,CAACd,MAAMG,QAAQ;IACnC,MAAMkB,QAAQ3C,SAASiC;IACvB,6EAA6E;IAC7E,MAAMc,QAAQzB,MAAMyB,KAAK,EAAEC,UAAUyB;IAErC,IAAI7B,QAAQ;QACV,MAAMlC,kBAAkBsB,UAAU;YAChCW;YACAP;YACAG,WAAWN,UAAUO,GAAG,EAAED;YAC1BoE,YAAY1E,UAAU0E,UAAU;YAChC5D;YACA6D,SAAStF,MAAM0C,GAAG;QACpB;QACA,OAAO;YAACL,aAAa;YAAMM,SAAS;QAAK;IAC3C;IAEA,MAAM1B,YAAYN,UAAUO,GAAG,EAAED,aAAa;IAC9C,iFAAiF;IACjF,MAAM,EAACoB,WAAW,EAAEM,OAAO,EAAC,GAAG,MAAMhD,6BAA6B;QAChE0B;QACAP;QACAF;QACAK;QACAoE,YAAY1E,UAAU0E,UAAU;QAChC5D;QACA8D,YAAY,CAAC,CAACvF,MAAMwF,GAAG;QACvBF,SAAStF,MAAM0C,GAAG;IACpB;IAEA,IAAI,CAACL,aAAa;QAChB,IAAIvB,YAAY;YACdF,OAAO6E,GAAG,CAAC;YACX7E,OAAO6E,GAAG,CAAC;QACb,OAAO;YACL7E,OAAO6E,GAAG,CAAC;YACX7E,OAAO6E,GAAG,CAAC;YACX7E,OAAO6E,GAAG,CAAC;QACb;QAEA,MAAMC,aAAa,MAAM3G,4BAA4B;YACnDkC;YACAQ;YACAkE,SAAS7E,aAAa,aAAa;QACrC;QACAxB,YAAY,4BAA4BoG;QACxC,OAAO;YAACrD,aAAaqD;YAAY/C,SAAS;QAAI;IAChD;IAEArD,YAAY,0BAA0B+C;IACtC,OAAO;QAACA;QAAaM;IAAO;AAC9B;AAEA,kFAAkF,GAClF,eAAe2B,mBACbxE,OAAyB,EACzB,EAACsD,aAAa,EAAEtC,UAAU,EAAgD;IAE1E,MAAM,EAACH,SAAS,EAAEX,KAAK,EAAEY,MAAM,EAAEX,WAAW,EAAEC,SAAS,EAAC,GAAGJ;IAE3D,IAAIuE,iBAAwC;IAC5C,IAAI;QACFA,iBAAiB,MAAM3E,gCACrB;YACE0D;YACAwC,YAAY3F,YAAY4F,IAAI;YAC5B/E;YACAgF,SAAS,GAAG5F,UAAU,OAAO,CAAC;YAC9Be,WAAWN,UAAUO,GAAG,EAAED,aAAa;YACvC8E,gBAAgB/F,KAAK,CAAC,kBAAkB;YACxCgG,SAAShG,MAAMgG,OAAO;YACtBnF,SAASZ,YAAYK,SAAS;QAChC,GACAM;IAEJ,EAAE,OAAOqF,OAAO;QACd3G,YAAY,gDAAgD2G;QAC5D,IAAIA,iBAAiBrI,yBAAyBqI,MAAMC,UAAU,EAAEC,QAAQ;YACtEvF,OAAOqF,KAAK,CAACtI,uBAAuBsI,MAAMC,UAAU,GAAG;gBAACE,MAAMtI,UAAUuI,aAAa;YAAA;QACvF;QACAzF,OAAOqF,KAAK,CAAC,CAAC,8CAA8C,EAAEA,OAAO,EAAE;YACrEG,MAAMtI,UAAUuI,aAAa;QAC/B;IACF;IAEA,IAAI,CAAChC,gBAAgB;QACnBzD,OAAOqF,KAAK,CAAC,gFAAgF;YAC3FG,MAAMtI,UAAUuI,aAAa;QAC/B;IACF;IAEA,OAAOhC;AACT;AAEA,eAAec,qBAAqB,EAClC9C,WAAW,EACXT,cAAc,EACdd,UAAU,EACVhB,OAAO,EACPuE,cAAc,EACdxC,OAAO,EAQR;IACC,MAAM,EAAClB,SAAS,EAAEC,MAAM,EAAEV,SAAS,EAAC,GAAGJ;IAEvC,IAAIwG;IACJ,IAAI,CAACxF,YAAY;QACfwF,UAAU9H,UAAU;YAAC+H,KAAKhJ,QAAQ2C;QAAU,GAAG;YAAC5C,SAAS4C;SAAW,EAAEsG,IAAI,CAAC9I;IAC7E;IAEA,MAAM+I,OAAO1I,QAAQ+C,aAAa,uBAAuB,8BAA8B4F,KAAK;IAC5F,IAAIxB;IACJ,IAAI;;QACA,CAAA,EAACA,QAAQ,EAAC,GAAG,MAAMzG,iBAAiB;YACpC2E,eAAef,YAAYoB,EAAE;YAC7BiB,OAAO;YACP9C;YACA+E,UAAUtC;YACVpD,WAAWN,UAAUO,GAAG,EAAED;YAC1BqF;YACAzE;QACF,EAAC;IACH,EAAE,OAAOoE,OAAO;QACdQ,KAAKG,IAAI;QACT,MAAMX;IACR;IACAQ,KAAKI,OAAO;IAEZ,MAAMC,QAAQzE,YAAYZ,KAAK,GAAG,CAAC,IAAI,EAAEY,YAAYZ,KAAK,CAAC,CAAC,CAAC,GAAG;IAChEb,OAAO6E,GAAG,CACR3E,aACI,CAAC,4BAA4B,EAAEgG,OAAO,GACtC,CAAC,8BAA8B,EAAErJ,UAAU,QAAQyH,YAAY4B,OAAO;IAG5E,IAAIpI,SAASiC,YAAY,OAAOuE;IAEhC,MAAM6B,UAAU,CAAC;;;;IAIf,EAAEtJ,UAAU,QAAQ,CAAC,QAAQ,EAAE4E,YAAYoB,EAAE,CAAC,CAAC,CAAC,EAAE;;;EAGpD,CAAC;IACD7C,OAAO6E,GAAG,CAAC,CAAC,MAAM,EAAEhI,UAAU,QAAQ,CAAC,QAAQ,EAAE4E,YAAYoB,EAAE,CAAC,CAAC,CAAC,GAAG;IACrE7C,OAAO6E,GAAG,CAAC,CAAC,+DAA+D,CAAC;IAC5E7E,OAAO6E,GAAG,CAAC,CAAC,qDAAqD,CAAC;IAClE7E,OAAO6E,GAAG,CAAC,CAAC,EAAE,EAAEsB,SAAS;IAEzB,OAAO7B;AACT;AAEA;;;CAGC,GACD,SAAST,SAASkC,QAA+B;IAC/C,MAAMK,cAAc,IAAIC,IACtB,AAACN,CAAAA,UAAU9B,cAAc,EAAE,AAAD,EAAGqC,GAAG,CAAC,CAACC,IAAM,GAAGA,EAAElG,SAAS,CAAC,CAAC,EAAEkG,EAAEC,OAAO,EAAE;IAEvE,OAAO;WAAIJ;KAAY,CAACE,GAAG,CACzB,CAACG,aAAgB,CAAA;YAACA;YAAYC,cAAc;QAAS,CAAA;AAEzD;AAEA,SAASxC,aAAa6B,QAA+B;IACnD,OAAO,AAACA,CAAAA,UAAU9B,cAAc,EAAE,AAAD,EAAGqC,GAAG,CAAC,CAACK,YAAe,CAAA;YACtDC,UAAUD,UAAUC,QAAQ;YAC5BJ,SAASG,UAAUH,OAAO;YAC1BlE,MAAMqE,UAAUrE,IAAI;YACpBK,MAAMgE,UAAUhE,IAAI;YACpBtC,WAAWsG,UAAUtG,SAAS;YAC9BwG,oBAAoBF,UAAUE,kBAAkB;YAChDC,UAAUH,UAAUG,QAAQ;YAC5BjG,OAAO8F,UAAU9F,KAAK;QACxB,CAAA;AACF;AAEA,qGAAqG,GACrG,SAASsD,2BAA2B,EAClC3B,aAAa,EACbzC,SAAS,EACTC,MAAM,EACN8B,GAAG,EAMJ;IACC9B,OAAO6E,GAAG,CAAC,CAAC,8BAA8B,EAAEhI,UAAU,QAAQiF,MAAM;IACpE,IAAIhE,SAASiC,YAAY;IAEzBC,OAAO6E,GAAG,CAAC,CAAC,MAAM,EAAEhI,UAAU,QAAQ,CAAC,QAAQ,EAAE2F,cAAc,CAAC,CAAC,GAAG;IACpExC,OAAO6E,GAAG,CAAC,CAAC,+DAA+D,CAAC;IAC5E7E,OAAO6E,GAAG,CAAC,CAAC,qDAAqD,CAAC;AACpE;AAEA,6FAA6F,GAC7F,SAAST,gBAAgB,EACvBrB,KAAK,EACLxC,cAAc,EACdP,MAAM,EACNV,SAAS,EAMV;IACC,MAAMyH,MAAM,GAAGnK,SAASoK,QAAQrB,GAAG,IAAIrG,cAAc,IAAI,CAAC,CAAC;IAC3DU,OAAO6E,GAAG,CAAC,CAAC;;WAEH,EAAEkC,IAAI;0CACyB,EAAEvJ,gBAAgB+C,gBAAgB;yCACnC,EAAEwC,QAAQ,CAAC,wBAAwB,EAAEgE,IAAI,kEAAkE,CAAC,GAAG,IAAI;AAC5J;AAEA,SAAS3D,sBAAsB,EAC7BlB,KAAK,EACLvB,gBAAgB,EAIjB;IACC,IAAIA,kBAAkB,OAAO;IAC7B,IAAI,CAACuB,OAAO,OAAO;IACnB;AACF"}
@@ -90,10 +90,10 @@ export async function initAction(options, context) {
90
90
  trace.log({
91
91
  flags: {
92
92
  bare: options.bare,
93
- coupon: options.coupon,
93
+ coupon: Boolean(options.coupon),
94
94
  defaultConfig,
95
- env: options.env,
96
- git: typeof options.git === 'string' ? options.git : undefined,
95
+ env: Boolean(options.env),
96
+ git: typeof options.git === 'string',
97
97
  plan: options.projectPlan,
98
98
  reconfigure: options.reconfigure,
99
99
  unattended: options.unattended
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/init/initAction.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n exitCodes,\n type SanityOrgUser,\n subdebug,\n type TelemetryUserProperties,\n} from '@sanity/cli-core'\nimport {logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {type TelemetryTrace} from '@sanity/telemetry'\nimport {type Framework, frameworks} from '@vercel/frameworks'\nimport deburr from 'lodash-es/deburr.js'\n\nimport {promptForConfigFiles} from '../../prompts/init/nextjs.js'\nimport {getCliUser} from '../../services/user.js'\nimport {CLIInitStepCompleted, type InitStepResult} from '../../telemetry/init.telemetry.js'\nimport {detectFrameworkRecord} from '../../util/detectFramework.js'\nimport {formatCliErrorMessages} from '../../util/formatCliErrorMessages.js'\nimport {getProjectDefaults} from '../../util/getProjectDefaults.js'\nimport {validateSession} from '../auth/ensureAuthenticated.js'\nimport {getProviderName, getUserDisplayName} from '../auth/getProviderName.js'\nimport {login} from '../auth/login/login.js'\nimport {LOGIN_REQUIRED_MESSAGE} from '../auth/login/loginInstructions.js'\nimport {detectAvailableEditors} from '../mcp/detectAvailableEditors.js'\nimport {setupMCP} from '../mcp/setupMCP.js'\nimport {setupSkills} from '../skills/setupSkills.js'\nimport {checkNextJsReactCompatibility} from './checkNextJsReactCompatibility.js'\nimport {determineAppTemplate} from './determineAppTemplate.js'\nimport {determineMediaLibraryTemplate} from './determineMediaLibraryTemplate.js'\nimport {createOrAppendEnvVars} from './env/createOrAppendEnvVars.js'\nimport {initApp} from './initApp.js'\nimport {InitError} from './initError.js'\nimport {flagOrDefault, shouldPrompt, writeStagingEnvIfNeeded} from './initHelpers.js'\nimport {initNextJs} from './initNextJs.js'\nimport {initStudio} from './initStudio.js'\nimport {getPlan} from './plan/getPlan.js'\nimport {createProjectFromName} from './project/createProjectFromName.js'\nimport {getProjectDetails} from './project/getProjectDetails.js'\nimport {getProjectOutputPath} from './project/getProjectOutputPath.js'\nimport {checkIsRemoteTemplate, getGitHubRepoInfo, type RepoInfo} from './remoteTemplate.js'\nimport {type InitContext, type InitOptions} from './types.js'\n\nconst debug = subdebug('init')\n\nexport async function initAction(options: InitOptions, context: InitContext): Promise<void> {\n const {output, workDir} = context\n\n if (options.argType) {\n throw new InitError(\n options.argType === 'plugin'\n ? 'Initializing plugins through the CLI is no longer supported'\n : `Unknown init type \"${options.argType}\"`,\n 1,\n )\n }\n\n const trace = context.telemetry.trace(CLIInitStepCompleted)\n\n if (options.reconfigure) {\n throw new InitError('--reconfigure is deprecated - manual configuration is now required', 1)\n }\n\n // Media Library config templates ride the app init flow end to end:\n // organization-only project details, app unattended-flag rules, `initApp`.\n // Template-shape differences are handled downstream (bootstrapLocalTemplate\n // and initApp check `determineMediaLibraryTemplate` themselves).\n const isMediaLibraryTemplate = options.template\n ? determineMediaLibraryTemplate(options.template)\n : false\n\n // That template ignores project flags outright (getProjectDetails warns), so\n // the pair is not the move-a-project contradiction this guard is about.\n if (options.project && options.organization && !isMediaLibraryTemplate) {\n throw new InitError(\n 'You have specified both a project and an organization. To move a project to an organization please visit https://www.sanity.io/manage',\n 1,\n )\n }\n\n const defaultConfig = options.datasetDefault\n let showDefaultConfigPrompt = !defaultConfig\n if (options.dataset || options.visibility || options.datasetDefault || options.unattended) {\n showDefaultConfigPrompt = false\n }\n\n const detectedFramework = await detectFrameworkRecord({\n frameworkList: frameworks as readonly Framework[],\n rootPath: workDir,\n })\n const isNextJs = detectedFramework?.slug === 'nextjs'\n\n let remoteTemplateInfo: RepoInfo | undefined\n if (options.template && checkIsRemoteTemplate(options.template)) {\n remoteTemplateInfo = await getGitHubRepoInfo(options.template, options.templateToken)\n }\n\n // Warned before any setup so the user can cancel. Remote templates ship their\n // own `sanity.cli.*`, so there is nothing to swap.\n if (options.dashboard && remoteTemplateInfo) {\n output.warn('--dashboard is ignored for remote templates')\n }\n\n if (detectedFramework && detectedFramework.slug !== 'sanity' && remoteTemplateInfo) {\n throw new InitError(\n `A remote template cannot be used with a detected framework. Detected: ${detectedFramework.name}`,\n 1,\n )\n }\n\n const isAppTemplate = options.template\n ? determineAppTemplate(options.template) || isMediaLibraryTemplate\n : false\n\n // A config app persists to the org's installation, not to a dashboard\n // workbench, so `createMediaLibraryCliConfig` has no slot for --dashboard.\n // Warned rather than silently dropped (same courtesy as remote templates).\n if (options.dashboard && isMediaLibraryTemplate) {\n output.warn('--dashboard is ignored for the media-library-config template')\n }\n\n if (options.unattended) {\n checkFlagsInUnattendedMode(options, {isAppTemplate, isMediaLibraryTemplate, isNextJs})\n }\n\n trace.start()\n trace.log({\n flags: {\n bare: options.bare,\n coupon: options.coupon,\n defaultConfig,\n env: options.env,\n git: typeof options.git === 'string' ? options.git : undefined,\n plan: options.projectPlan,\n reconfigure: options.reconfigure,\n unattended: options.unattended,\n },\n step: 'start',\n })\n\n const planId = await getPlan(options, output, trace)\n\n let envFilenameDefault = '.env'\n if (detectedFramework && detectedFramework.slug === 'nextjs') {\n envFilenameDefault = '.env.local'\n }\n const envFilename = typeof options.env === 'string' ? options.env : envFilenameDefault\n\n const {user} = await ensureAuthenticated(options, output, trace)\n if (!isAppTemplate) {\n output.log(`${logSymbols.success} Fetching existing projects`)\n output.log('')\n }\n\n let newProject: string | undefined\n // A media-library config records only the organization; creating a project\n // from --project-name here would be a throwaway side effect.\n if (options.projectName && isMediaLibraryTemplate) {\n output.warn(\n '--project-name is ignored for the media-library-config template — it only records the organization.',\n )\n }\n if (options.projectName && !isMediaLibraryTemplate) {\n newProject = await createProjectFromName({\n coupon: options.coupon,\n createProjectName: options.projectName,\n dataset: options.dataset,\n organization: options.organization,\n planId,\n user,\n visibility: options.visibility,\n })\n }\n\n const {datasetName, displayName, isFirstProject, organizationId, projectId} =\n await getProjectDetails({\n coupon: options.coupon,\n dataset: options.dataset,\n datasetDefault: options.datasetDefault,\n isAppTemplate,\n isMediaLibraryTemplate,\n newProject,\n organization: options.organization,\n output,\n planId,\n project: options.project,\n showDefaultConfigPrompt,\n trace,\n unattended: options.unattended,\n user,\n visibility: options.visibility,\n })\n\n if (options.bare) {\n output.log(`${logSymbols.success} Below are your project details`)\n output.log('')\n output.log(`Project ID: ${styleText('cyan', projectId)}`)\n output.log(`Dataset: ${styleText('cyan', datasetName)}`)\n output.log(\n `\\nYou can find your project on Sanity Manage — https://www.sanity.io/manage/project/${projectId}\\n`,\n )\n trace.complete()\n return\n }\n\n // Detect editors once, then share the result with MCP and skills setup so\n // we don't pay the detection cost (filesystem probes + CLI execa calls) twice.\n const detectedEditors =\n options.mcpMode === 'skip' && options.skillsMode === 'skip'\n ? []\n : await detectAvailableEditors()\n\n const mcpResult = await setupMCP({\n editors: detectedEditors,\n mode: options.mcpMode,\n output,\n skillsMode: options.skillsMode,\n })\n\n trace.log({\n configuredEditors: mcpResult.configuredEditors,\n detectedEditors: mcpResult.detectedEditors,\n skipped: mcpResult.skipped,\n step: 'mcpSetup',\n })\n if (mcpResult.error) {\n trace.error(mcpResult.error)\n }\n const mcpConfigured = mcpResult.configuredEditors\n\n async function installSkills(): Promise<void> {\n if (mcpResult.skillsToInstall.length === 0) return\n try {\n const skillsResult = await setupSkills({\n agents: mcpResult.skillsToInstall,\n output,\n })\n trace.log({\n installedAgents: skillsResult.installedAgents,\n skipped: skillsResult.skipped,\n step: 'skillsSetup',\n })\n if (skillsResult.error) {\n trace.error(skillsResult.error)\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n debug('Unexpected error from setupSkills %O', err)\n output.warn(`Could not install Sanity agent skills: ${err.message}`)\n trace.error(err)\n }\n }\n\n // Install skills right after the MCP/skills prompt so the progress + result\n // surface in sequence, rather than trailing the studio \"Success!\" output.\n await installSkills()\n\n const {alreadyConfiguredEditors} = mcpResult\n if (alreadyConfiguredEditors.length > 0) {\n const label =\n alreadyConfiguredEditors.length === 1\n ? `${alreadyConfiguredEditors[0]} already configured for Sanity MCP`\n : `${alreadyConfiguredEditors.length} editors already configured for Sanity MCP`\n spinner(label).start().succeed()\n }\n\n let initNext = flagOrDefault(options.nextjsAddConfigFiles, false)\n if (isNextJs && shouldPrompt(options.unattended, options.nextjsAddConfigFiles)) {\n initNext = await promptForConfigFiles()\n }\n\n trace.log({\n detectedFramework: detectedFramework?.name,\n selectedOption: initNext ? 'yes' : 'no',\n step: 'useDetectedFramework',\n })\n\n // The media-library config template skips project selection, so\n // `displayName` is empty and the slug would be too — which would default the\n // output-path prompt to the (usually non-empty) cwd, a default\n // `validateEmptyPath` then refuses. Fall back to the template's own name.\n const sluggedName =\n deburr(displayName.toLowerCase())\n .replaceAll(/\\s+/g, '-')\n .replaceAll(/[^a-z0-9-]/g, '') || (isMediaLibraryTemplate ? 'media-library-config' : '')\n\n const initFramework = initNext\n\n const defaults = await getProjectDefaults({isPlugin: false, workDir})\n\n const outputPath = await getProjectOutputPath({\n initFramework,\n outputPath: options.outputPath,\n sluggedName,\n unattended: options.unattended,\n useEnv: Boolean(options.env),\n workDir,\n })\n\n if (isNextJs) {\n await checkNextJsReactCompatibility({\n detectedFramework,\n output,\n outputPath,\n })\n }\n\n if (initNext) {\n if (options.dashboard) {\n output.warn('--dashboard is ignored for Next.js projects')\n }\n await initNextJs({\n datasetName,\n detectedFramework,\n envFilename,\n mcpConfigured,\n options,\n output,\n projectId,\n trace,\n workDir,\n })\n trace.complete()\n return\n }\n\n if (options.env) {\n await createOrAppendEnvVars({\n envVars: {\n DATASET: datasetName,\n PROJECT_ID: projectId,\n },\n filename: envFilename,\n framework: detectedFramework,\n log: false,\n output,\n outputPath,\n })\n await writeStagingEnvIfNeeded(output, outputPath)\n trace.complete()\n return\n }\n\n // The Dashboard is opt-in (no prompt): `--dashboard` swaps the scaffolded\n // `sanity.cli.*` over to `defineApplication` — the branded app is the sole\n // Dashboard opt-in.\n const workbench = flagOrDefault(options.dashboard, false)\n\n const sharedParams = {\n defaults,\n mcpConfigured,\n options,\n organizationId,\n output,\n outputPath,\n remoteTemplateInfo,\n sluggedName,\n trace,\n workbench,\n workDir,\n }\n\n await (isAppTemplate\n ? initApp({...sharedParams, datasetName, projectId})\n : initStudio({\n ...sharedParams,\n datasetName,\n displayName,\n isFirstProject,\n projectId,\n }))\n\n trace.complete()\n}\n\nfunction checkFlagsInUnattendedMode(\n options: InitOptions,\n {\n isAppTemplate,\n isMediaLibraryTemplate,\n isNextJs,\n }: {isAppTemplate: boolean; isMediaLibraryTemplate: boolean; isNextJs: boolean},\n): void {\n debug('Unattended mode, validating required options')\n\n const errors: string[] = []\n\n if (isAppTemplate) {\n if (!options.outputPath) {\n errors.push(\n 'Output path is required in unattended mode. Pass it with `--output-path <path>`.',\n )\n }\n\n // The media-library config is organization-only, so project flags can't\n // stand in for --organization the way they can for other app templates.\n if (isMediaLibraryTemplate && !options.organization) {\n errors.push(\n 'Organization is required for the media-library-config template in unattended mode. ' +\n 'Pass it with `--organization <id>`.',\n )\n } else if (options.projectName && !options.organization) {\n errors.push(\n 'Organization is required when creating a project in unattended mode. Pass it with `--organization <id>`.',\n )\n } else if (!options.project && !options.organization) {\n errors.push(\n 'Project or organization is required for app templates in unattended mode. ' +\n 'Pass `--project <id>` or `--organization <id>`. To create a project, pass ' +\n '`--project-name <name>` with `--organization <id>`.',\n )\n }\n } else {\n if (!isNextJs && !options.bare && !options.outputPath) {\n errors.push(\n 'Output path is required in unattended mode. Pass it with `--output-path <path>`.',\n )\n }\n\n if (!options.project && !options.projectName) {\n errors.push(\n 'Project is required in unattended mode. Pass it with `--project <id>` or `--project-name <name>`.',\n )\n }\n\n if (!options.project && !options.organization) {\n errors.push(\n 'Organization is required when creating a project in unattended mode. Pass it with `--organization <id>`.',\n )\n }\n }\n\n if (errors.length > 0) {\n throw new InitError(formatCliErrorMessages(errors), exitCodes.USAGE_ERROR)\n }\n}\n\nasync function ensureAuthenticated(\n options: InitOptions,\n output: InitContext['output'],\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>,\n): Promise<{user: SanityOrgUser}> {\n const user = await validateSession()\n\n if (user) {\n trace.log({alreadyLoggedIn: true, step: 'login'})\n output.log(\n `${logSymbols.success} You are logged in as ${getUserDisplayName(user)} using ${getProviderName(user.provider)}`,\n )\n return {user}\n }\n\n if (options.unattended) {\n throw new InitError(LOGIN_REQUIRED_MESSAGE, exitCodes.RUNTIME_ERROR)\n }\n\n trace.log({step: 'login'})\n output.warn(LOGIN_REQUIRED_MESSAGE)\n\n try {\n await login({\n output,\n telemetry: trace.newContext('login'),\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new InitError(`Login failed: ${message}`, 1)\n }\n\n const loggedInUser = await getCliUser()\n\n output.log(\n `${logSymbols.success} You are logged in as ${getUserDisplayName(loggedInUser)} using ${getProviderName(loggedInUser.provider)}`,\n )\n return {user: loggedInUser}\n}\n"],"names":["styleText","exitCodes","subdebug","logSymbols","spinner","frameworks","deburr","promptForConfigFiles","getCliUser","CLIInitStepCompleted","detectFrameworkRecord","formatCliErrorMessages","getProjectDefaults","validateSession","getProviderName","getUserDisplayName","login","LOGIN_REQUIRED_MESSAGE","detectAvailableEditors","setupMCP","setupSkills","checkNextJsReactCompatibility","determineAppTemplate","determineMediaLibraryTemplate","createOrAppendEnvVars","initApp","InitError","flagOrDefault","shouldPrompt","writeStagingEnvIfNeeded","initNextJs","initStudio","getPlan","createProjectFromName","getProjectDetails","getProjectOutputPath","checkIsRemoteTemplate","getGitHubRepoInfo","debug","initAction","options","context","output","workDir","argType","trace","telemetry","reconfigure","isMediaLibraryTemplate","template","project","organization","defaultConfig","datasetDefault","showDefaultConfigPrompt","dataset","visibility","unattended","detectedFramework","frameworkList","rootPath","isNextJs","slug","remoteTemplateInfo","templateToken","dashboard","warn","name","isAppTemplate","checkFlagsInUnattendedMode","start","log","flags","bare","coupon","env","git","undefined","plan","projectPlan","step","planId","envFilenameDefault","envFilename","user","ensureAuthenticated","success","newProject","projectName","createProjectName","datasetName","displayName","isFirstProject","organizationId","projectId","complete","detectedEditors","mcpMode","skillsMode","mcpResult","editors","mode","configuredEditors","skipped","error","mcpConfigured","installSkills","skillsToInstall","length","skillsResult","agents","installedAgents","err","Error","String","message","alreadyConfiguredEditors","label","succeed","initNext","nextjsAddConfigFiles","selectedOption","sluggedName","toLowerCase","replaceAll","initFramework","defaults","isPlugin","outputPath","useEnv","Boolean","envVars","DATASET","PROJECT_ID","filename","framework","workbench","sharedParams","errors","push","USAGE_ERROR","alreadyLoggedIn","provider","RUNTIME_ERROR","newContext","loggedInUser"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/init/initAction.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n exitCodes,\n type SanityOrgUser,\n subdebug,\n type TelemetryUserProperties,\n} from '@sanity/cli-core'\nimport {logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {type TelemetryTrace} from '@sanity/telemetry'\nimport {type Framework, frameworks} from '@vercel/frameworks'\nimport deburr from 'lodash-es/deburr.js'\n\nimport {promptForConfigFiles} from '../../prompts/init/nextjs.js'\nimport {getCliUser} from '../../services/user.js'\nimport {CLIInitStepCompleted, type InitStepResult} from '../../telemetry/init.telemetry.js'\nimport {detectFrameworkRecord} from '../../util/detectFramework.js'\nimport {formatCliErrorMessages} from '../../util/formatCliErrorMessages.js'\nimport {getProjectDefaults} from '../../util/getProjectDefaults.js'\nimport {validateSession} from '../auth/ensureAuthenticated.js'\nimport {getProviderName, getUserDisplayName} from '../auth/getProviderName.js'\nimport {login} from '../auth/login/login.js'\nimport {LOGIN_REQUIRED_MESSAGE} from '../auth/login/loginInstructions.js'\nimport {detectAvailableEditors} from '../mcp/detectAvailableEditors.js'\nimport {setupMCP} from '../mcp/setupMCP.js'\nimport {setupSkills} from '../skills/setupSkills.js'\nimport {checkNextJsReactCompatibility} from './checkNextJsReactCompatibility.js'\nimport {determineAppTemplate} from './determineAppTemplate.js'\nimport {determineMediaLibraryTemplate} from './determineMediaLibraryTemplate.js'\nimport {createOrAppendEnvVars} from './env/createOrAppendEnvVars.js'\nimport {initApp} from './initApp.js'\nimport {InitError} from './initError.js'\nimport {flagOrDefault, shouldPrompt, writeStagingEnvIfNeeded} from './initHelpers.js'\nimport {initNextJs} from './initNextJs.js'\nimport {initStudio} from './initStudio.js'\nimport {getPlan} from './plan/getPlan.js'\nimport {createProjectFromName} from './project/createProjectFromName.js'\nimport {getProjectDetails} from './project/getProjectDetails.js'\nimport {getProjectOutputPath} from './project/getProjectOutputPath.js'\nimport {checkIsRemoteTemplate, getGitHubRepoInfo, type RepoInfo} from './remoteTemplate.js'\nimport {type InitContext, type InitOptions} from './types.js'\n\nconst debug = subdebug('init')\n\nexport async function initAction(options: InitOptions, context: InitContext): Promise<void> {\n const {output, workDir} = context\n\n if (options.argType) {\n throw new InitError(\n options.argType === 'plugin'\n ? 'Initializing plugins through the CLI is no longer supported'\n : `Unknown init type \"${options.argType}\"`,\n 1,\n )\n }\n\n const trace = context.telemetry.trace(CLIInitStepCompleted)\n\n if (options.reconfigure) {\n throw new InitError('--reconfigure is deprecated - manual configuration is now required', 1)\n }\n\n // Media Library config templates ride the app init flow end to end:\n // organization-only project details, app unattended-flag rules, `initApp`.\n // Template-shape differences are handled downstream (bootstrapLocalTemplate\n // and initApp check `determineMediaLibraryTemplate` themselves).\n const isMediaLibraryTemplate = options.template\n ? determineMediaLibraryTemplate(options.template)\n : false\n\n // That template ignores project flags outright (getProjectDetails warns), so\n // the pair is not the move-a-project contradiction this guard is about.\n if (options.project && options.organization && !isMediaLibraryTemplate) {\n throw new InitError(\n 'You have specified both a project and an organization. To move a project to an organization please visit https://www.sanity.io/manage',\n 1,\n )\n }\n\n const defaultConfig = options.datasetDefault\n let showDefaultConfigPrompt = !defaultConfig\n if (options.dataset || options.visibility || options.datasetDefault || options.unattended) {\n showDefaultConfigPrompt = false\n }\n\n const detectedFramework = await detectFrameworkRecord({\n frameworkList: frameworks as readonly Framework[],\n rootPath: workDir,\n })\n const isNextJs = detectedFramework?.slug === 'nextjs'\n\n let remoteTemplateInfo: RepoInfo | undefined\n if (options.template && checkIsRemoteTemplate(options.template)) {\n remoteTemplateInfo = await getGitHubRepoInfo(options.template, options.templateToken)\n }\n\n // Warned before any setup so the user can cancel. Remote templates ship their\n // own `sanity.cli.*`, so there is nothing to swap.\n if (options.dashboard && remoteTemplateInfo) {\n output.warn('--dashboard is ignored for remote templates')\n }\n\n if (detectedFramework && detectedFramework.slug !== 'sanity' && remoteTemplateInfo) {\n throw new InitError(\n `A remote template cannot be used with a detected framework. Detected: ${detectedFramework.name}`,\n 1,\n )\n }\n\n const isAppTemplate = options.template\n ? determineAppTemplate(options.template) || isMediaLibraryTemplate\n : false\n\n // A config app persists to the org's installation, not to a dashboard\n // workbench, so `createMediaLibraryCliConfig` has no slot for --dashboard.\n // Warned rather than silently dropped (same courtesy as remote templates).\n if (options.dashboard && isMediaLibraryTemplate) {\n output.warn('--dashboard is ignored for the media-library-config template')\n }\n\n if (options.unattended) {\n checkFlagsInUnattendedMode(options, {isAppTemplate, isMediaLibraryTemplate, isNextJs})\n }\n\n trace.start()\n trace.log({\n flags: {\n bare: options.bare,\n coupon: Boolean(options.coupon),\n defaultConfig,\n env: Boolean(options.env),\n git: typeof options.git === 'string',\n plan: options.projectPlan,\n reconfigure: options.reconfigure,\n unattended: options.unattended,\n },\n step: 'start',\n })\n\n const planId = await getPlan(options, output, trace)\n\n let envFilenameDefault = '.env'\n if (detectedFramework && detectedFramework.slug === 'nextjs') {\n envFilenameDefault = '.env.local'\n }\n const envFilename = typeof options.env === 'string' ? options.env : envFilenameDefault\n\n const {user} = await ensureAuthenticated(options, output, trace)\n if (!isAppTemplate) {\n output.log(`${logSymbols.success} Fetching existing projects`)\n output.log('')\n }\n\n let newProject: string | undefined\n // A media-library config records only the organization; creating a project\n // from --project-name here would be a throwaway side effect.\n if (options.projectName && isMediaLibraryTemplate) {\n output.warn(\n '--project-name is ignored for the media-library-config template — it only records the organization.',\n )\n }\n if (options.projectName && !isMediaLibraryTemplate) {\n newProject = await createProjectFromName({\n coupon: options.coupon,\n createProjectName: options.projectName,\n dataset: options.dataset,\n organization: options.organization,\n planId,\n user,\n visibility: options.visibility,\n })\n }\n\n const {datasetName, displayName, isFirstProject, organizationId, projectId} =\n await getProjectDetails({\n coupon: options.coupon,\n dataset: options.dataset,\n datasetDefault: options.datasetDefault,\n isAppTemplate,\n isMediaLibraryTemplate,\n newProject,\n organization: options.organization,\n output,\n planId,\n project: options.project,\n showDefaultConfigPrompt,\n trace,\n unattended: options.unattended,\n user,\n visibility: options.visibility,\n })\n\n if (options.bare) {\n output.log(`${logSymbols.success} Below are your project details`)\n output.log('')\n output.log(`Project ID: ${styleText('cyan', projectId)}`)\n output.log(`Dataset: ${styleText('cyan', datasetName)}`)\n output.log(\n `\\nYou can find your project on Sanity Manage — https://www.sanity.io/manage/project/${projectId}\\n`,\n )\n trace.complete()\n return\n }\n\n // Detect editors once, then share the result with MCP and skills setup so\n // we don't pay the detection cost (filesystem probes + CLI execa calls) twice.\n const detectedEditors =\n options.mcpMode === 'skip' && options.skillsMode === 'skip'\n ? []\n : await detectAvailableEditors()\n\n const mcpResult = await setupMCP({\n editors: detectedEditors,\n mode: options.mcpMode,\n output,\n skillsMode: options.skillsMode,\n })\n\n trace.log({\n configuredEditors: mcpResult.configuredEditors,\n detectedEditors: mcpResult.detectedEditors,\n skipped: mcpResult.skipped,\n step: 'mcpSetup',\n })\n if (mcpResult.error) {\n trace.error(mcpResult.error)\n }\n const mcpConfigured = mcpResult.configuredEditors\n\n async function installSkills(): Promise<void> {\n if (mcpResult.skillsToInstall.length === 0) return\n try {\n const skillsResult = await setupSkills({\n agents: mcpResult.skillsToInstall,\n output,\n })\n trace.log({\n installedAgents: skillsResult.installedAgents,\n skipped: skillsResult.skipped,\n step: 'skillsSetup',\n })\n if (skillsResult.error) {\n trace.error(skillsResult.error)\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n debug('Unexpected error from setupSkills %O', err)\n output.warn(`Could not install Sanity agent skills: ${err.message}`)\n trace.error(err)\n }\n }\n\n // Install skills right after the MCP/skills prompt so the progress + result\n // surface in sequence, rather than trailing the studio \"Success!\" output.\n await installSkills()\n\n const {alreadyConfiguredEditors} = mcpResult\n if (alreadyConfiguredEditors.length > 0) {\n const label =\n alreadyConfiguredEditors.length === 1\n ? `${alreadyConfiguredEditors[0]} already configured for Sanity MCP`\n : `${alreadyConfiguredEditors.length} editors already configured for Sanity MCP`\n spinner(label).start().succeed()\n }\n\n let initNext = flagOrDefault(options.nextjsAddConfigFiles, false)\n if (isNextJs && shouldPrompt(options.unattended, options.nextjsAddConfigFiles)) {\n initNext = await promptForConfigFiles()\n }\n\n trace.log({\n detectedFramework: detectedFramework?.name,\n selectedOption: initNext ? 'yes' : 'no',\n step: 'useDetectedFramework',\n })\n\n // The media-library config template skips project selection, so\n // `displayName` is empty and the slug would be too — which would default the\n // output-path prompt to the (usually non-empty) cwd, a default\n // `validateEmptyPath` then refuses. Fall back to the template's own name.\n const sluggedName =\n deburr(displayName.toLowerCase())\n .replaceAll(/\\s+/g, '-')\n .replaceAll(/[^a-z0-9-]/g, '') || (isMediaLibraryTemplate ? 'media-library-config' : '')\n\n const initFramework = initNext\n\n const defaults = await getProjectDefaults({isPlugin: false, workDir})\n\n const outputPath = await getProjectOutputPath({\n initFramework,\n outputPath: options.outputPath,\n sluggedName,\n unattended: options.unattended,\n useEnv: Boolean(options.env),\n workDir,\n })\n\n if (isNextJs) {\n await checkNextJsReactCompatibility({\n detectedFramework,\n output,\n outputPath,\n })\n }\n\n if (initNext) {\n if (options.dashboard) {\n output.warn('--dashboard is ignored for Next.js projects')\n }\n await initNextJs({\n datasetName,\n detectedFramework,\n envFilename,\n mcpConfigured,\n options,\n output,\n projectId,\n trace,\n workDir,\n })\n trace.complete()\n return\n }\n\n if (options.env) {\n await createOrAppendEnvVars({\n envVars: {\n DATASET: datasetName,\n PROJECT_ID: projectId,\n },\n filename: envFilename,\n framework: detectedFramework,\n log: false,\n output,\n outputPath,\n })\n await writeStagingEnvIfNeeded(output, outputPath)\n trace.complete()\n return\n }\n\n // The Dashboard is opt-in (no prompt): `--dashboard` swaps the scaffolded\n // `sanity.cli.*` over to `defineApplication` — the branded app is the sole\n // Dashboard opt-in.\n const workbench = flagOrDefault(options.dashboard, false)\n\n const sharedParams = {\n defaults,\n mcpConfigured,\n options,\n organizationId,\n output,\n outputPath,\n remoteTemplateInfo,\n sluggedName,\n trace,\n workbench,\n workDir,\n }\n\n await (isAppTemplate\n ? initApp({...sharedParams, datasetName, projectId})\n : initStudio({\n ...sharedParams,\n datasetName,\n displayName,\n isFirstProject,\n projectId,\n }))\n\n trace.complete()\n}\n\nfunction checkFlagsInUnattendedMode(\n options: InitOptions,\n {\n isAppTemplate,\n isMediaLibraryTemplate,\n isNextJs,\n }: {isAppTemplate: boolean; isMediaLibraryTemplate: boolean; isNextJs: boolean},\n): void {\n debug('Unattended mode, validating required options')\n\n const errors: string[] = []\n\n if (isAppTemplate) {\n if (!options.outputPath) {\n errors.push(\n 'Output path is required in unattended mode. Pass it with `--output-path <path>`.',\n )\n }\n\n // The media-library config is organization-only, so project flags can't\n // stand in for --organization the way they can for other app templates.\n if (isMediaLibraryTemplate && !options.organization) {\n errors.push(\n 'Organization is required for the media-library-config template in unattended mode. ' +\n 'Pass it with `--organization <id>`.',\n )\n } else if (options.projectName && !options.organization) {\n errors.push(\n 'Organization is required when creating a project in unattended mode. Pass it with `--organization <id>`.',\n )\n } else if (!options.project && !options.organization) {\n errors.push(\n 'Project or organization is required for app templates in unattended mode. ' +\n 'Pass `--project <id>` or `--organization <id>`. To create a project, pass ' +\n '`--project-name <name>` with `--organization <id>`.',\n )\n }\n } else {\n if (!isNextJs && !options.bare && !options.outputPath) {\n errors.push(\n 'Output path is required in unattended mode. Pass it with `--output-path <path>`.',\n )\n }\n\n if (!options.project && !options.projectName) {\n errors.push(\n 'Project is required in unattended mode. Pass it with `--project <id>` or `--project-name <name>`.',\n )\n }\n\n if (!options.project && !options.organization) {\n errors.push(\n 'Organization is required when creating a project in unattended mode. Pass it with `--organization <id>`.',\n )\n }\n }\n\n if (errors.length > 0) {\n throw new InitError(formatCliErrorMessages(errors), exitCodes.USAGE_ERROR)\n }\n}\n\nasync function ensureAuthenticated(\n options: InitOptions,\n output: InitContext['output'],\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>,\n): Promise<{user: SanityOrgUser}> {\n const user = await validateSession()\n\n if (user) {\n trace.log({alreadyLoggedIn: true, step: 'login'})\n output.log(\n `${logSymbols.success} You are logged in as ${getUserDisplayName(user)} using ${getProviderName(user.provider)}`,\n )\n return {user}\n }\n\n if (options.unattended) {\n throw new InitError(LOGIN_REQUIRED_MESSAGE, exitCodes.RUNTIME_ERROR)\n }\n\n trace.log({step: 'login'})\n output.warn(LOGIN_REQUIRED_MESSAGE)\n\n try {\n await login({\n output,\n telemetry: trace.newContext('login'),\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new InitError(`Login failed: ${message}`, 1)\n }\n\n const loggedInUser = await getCliUser()\n\n output.log(\n `${logSymbols.success} You are logged in as ${getUserDisplayName(loggedInUser)} using ${getProviderName(loggedInUser.provider)}`,\n )\n return {user: loggedInUser}\n}\n"],"names":["styleText","exitCodes","subdebug","logSymbols","spinner","frameworks","deburr","promptForConfigFiles","getCliUser","CLIInitStepCompleted","detectFrameworkRecord","formatCliErrorMessages","getProjectDefaults","validateSession","getProviderName","getUserDisplayName","login","LOGIN_REQUIRED_MESSAGE","detectAvailableEditors","setupMCP","setupSkills","checkNextJsReactCompatibility","determineAppTemplate","determineMediaLibraryTemplate","createOrAppendEnvVars","initApp","InitError","flagOrDefault","shouldPrompt","writeStagingEnvIfNeeded","initNextJs","initStudio","getPlan","createProjectFromName","getProjectDetails","getProjectOutputPath","checkIsRemoteTemplate","getGitHubRepoInfo","debug","initAction","options","context","output","workDir","argType","trace","telemetry","reconfigure","isMediaLibraryTemplate","template","project","organization","defaultConfig","datasetDefault","showDefaultConfigPrompt","dataset","visibility","unattended","detectedFramework","frameworkList","rootPath","isNextJs","slug","remoteTemplateInfo","templateToken","dashboard","warn","name","isAppTemplate","checkFlagsInUnattendedMode","start","log","flags","bare","coupon","Boolean","env","git","plan","projectPlan","step","planId","envFilenameDefault","envFilename","user","ensureAuthenticated","success","newProject","projectName","createProjectName","datasetName","displayName","isFirstProject","organizationId","projectId","complete","detectedEditors","mcpMode","skillsMode","mcpResult","editors","mode","configuredEditors","skipped","error","mcpConfigured","installSkills","skillsToInstall","length","skillsResult","agents","installedAgents","err","Error","String","message","alreadyConfiguredEditors","label","succeed","initNext","nextjsAddConfigFiles","selectedOption","sluggedName","toLowerCase","replaceAll","initFramework","defaults","isPlugin","outputPath","useEnv","envVars","DATASET","PROJECT_ID","filename","framework","workbench","sharedParams","errors","push","USAGE_ERROR","alreadyLoggedIn","provider","RUNTIME_ERROR","newContext","loggedInUser"],"mappings":"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"}
@@ -20,7 +20,6 @@ export async function verifyCoupon(intendedCoupon, unattended, output, trace) {
20
20
  output.warn(`Coupon "${intendedCoupon}" is not available - using default plan`);
21
21
  }
22
22
  trace.log({
23
- coupon: intendedCoupon,
24
23
  selectedOption: useDefaultPlan ? 'yes' : 'no',
25
24
  step: 'useDefaultPlanCoupon'
26
25
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/actions/init/plan/verifyCoupon.ts"],"sourcesContent":["import {type TelemetryUserProperties} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {isHttpError} from '@sanity/client'\nimport {type TelemetryTrace} from '@sanity/telemetry'\n\nimport {getPlanIdFromCoupon} from '../../../services/plans.js'\nimport {type InitStepResult} from '../../../telemetry/init.telemetry.js'\nimport {InitError} from '../initError.js'\nimport {type InitContext} from '../types.js'\n\nexport async function verifyCoupon(\n intendedCoupon: string,\n unattended: boolean,\n output: InitContext['output'],\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>,\n): Promise<string | undefined> {\n try {\n const planId = await getPlanIdFromCoupon(intendedCoupon)\n output.log(`Coupon \"${intendedCoupon}\" validated!\\n`)\n return planId\n } catch (err: unknown) {\n if (!isHttpError(err) || err.statusCode !== 404) {\n const message = err instanceof Error ? err.message : `${err}`\n throw new InitError(`Unable to validate coupon, please try again later:\\n\\n${message}`, 1)\n }\n\n const useDefaultPlan =\n unattended ||\n (await confirm({\n default: true,\n message: `Coupon \"${intendedCoupon}\" is not available, use default plan instead?`,\n }))\n\n if (unattended) {\n output.warn(`Coupon \"${intendedCoupon}\" is not available - using default plan`)\n }\n\n trace.log({\n coupon: intendedCoupon,\n selectedOption: useDefaultPlan ? 'yes' : 'no',\n step: 'useDefaultPlanCoupon',\n })\n\n if (useDefaultPlan) {\n output.log('Using default plan.')\n return undefined\n }\n\n throw new InitError(`Coupon \"${intendedCoupon}\" does not exist`, 1)\n }\n}\n"],"names":["confirm","isHttpError","getPlanIdFromCoupon","InitError","verifyCoupon","intendedCoupon","unattended","output","trace","planId","log","err","statusCode","message","Error","useDefaultPlan","default","warn","coupon","selectedOption","step","undefined"],"mappings":"AACA,SAAQA,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,WAAW,QAAO,iBAAgB;AAG1C,SAAQC,mBAAmB,QAAO,6BAA4B;AAE9D,SAAQC,SAAS,QAAO,kBAAiB;AAGzC,OAAO,eAAeC,aACpBC,cAAsB,EACtBC,UAAmB,EACnBC,MAA6B,EAC7BC,KAA8D;IAE9D,IAAI;QACF,MAAMC,SAAS,MAAMP,oBAAoBG;QACzCE,OAAOG,GAAG,CAAC,CAAC,QAAQ,EAAEL,eAAe,cAAc,CAAC;QACpD,OAAOI;IACT,EAAE,OAAOE,KAAc;QACrB,IAAI,CAACV,YAAYU,QAAQA,IAAIC,UAAU,KAAK,KAAK;YAC/C,MAAMC,UAAUF,eAAeG,QAAQH,IAAIE,OAAO,GAAG,GAAGF,KAAK;YAC7D,MAAM,IAAIR,UAAU,CAAC,sDAAsD,EAAEU,SAAS,EAAE;QAC1F;QAEA,MAAME,iBACJT,cACC,MAAMN,QAAQ;YACbgB,SAAS;YACTH,SAAS,CAAC,QAAQ,EAAER,eAAe,6CAA6C,CAAC;QACnF;QAEF,IAAIC,YAAY;YACdC,OAAOU,IAAI,CAAC,CAAC,QAAQ,EAAEZ,eAAe,uCAAuC,CAAC;QAChF;QAEAG,MAAME,GAAG,CAAC;YACRQ,QAAQb;YACRc,gBAAgBJ,iBAAiB,QAAQ;YACzCK,MAAM;QACR;QAEA,IAAIL,gBAAgB;YAClBR,OAAOG,GAAG,CAAC;YACX,OAAOW;QACT;QAEA,MAAM,IAAIlB,UAAU,CAAC,QAAQ,EAAEE,eAAe,gBAAgB,CAAC,EAAE;IACnE;AACF"}
1
+ {"version":3,"sources":["../../../../src/actions/init/plan/verifyCoupon.ts"],"sourcesContent":["import {type TelemetryUserProperties} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {isHttpError} from '@sanity/client'\nimport {type TelemetryTrace} from '@sanity/telemetry'\n\nimport {getPlanIdFromCoupon} from '../../../services/plans.js'\nimport {type InitStepResult} from '../../../telemetry/init.telemetry.js'\nimport {InitError} from '../initError.js'\nimport {type InitContext} from '../types.js'\n\nexport async function verifyCoupon(\n intendedCoupon: string,\n unattended: boolean,\n output: InitContext['output'],\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>,\n): Promise<string | undefined> {\n try {\n const planId = await getPlanIdFromCoupon(intendedCoupon)\n output.log(`Coupon \"${intendedCoupon}\" validated!\\n`)\n return planId\n } catch (err: unknown) {\n if (!isHttpError(err) || err.statusCode !== 404) {\n const message = err instanceof Error ? err.message : `${err}`\n throw new InitError(`Unable to validate coupon, please try again later:\\n\\n${message}`, 1)\n }\n\n const useDefaultPlan =\n unattended ||\n (await confirm({\n default: true,\n message: `Coupon \"${intendedCoupon}\" is not available, use default plan instead?`,\n }))\n\n if (unattended) {\n output.warn(`Coupon \"${intendedCoupon}\" is not available - using default plan`)\n }\n\n trace.log({\n selectedOption: useDefaultPlan ? 'yes' : 'no',\n step: 'useDefaultPlanCoupon',\n })\n\n if (useDefaultPlan) {\n output.log('Using default plan.')\n return undefined\n }\n\n throw new InitError(`Coupon \"${intendedCoupon}\" does not exist`, 1)\n }\n}\n"],"names":["confirm","isHttpError","getPlanIdFromCoupon","InitError","verifyCoupon","intendedCoupon","unattended","output","trace","planId","log","err","statusCode","message","Error","useDefaultPlan","default","warn","selectedOption","step","undefined"],"mappings":"AACA,SAAQA,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,WAAW,QAAO,iBAAgB;AAG1C,SAAQC,mBAAmB,QAAO,6BAA4B;AAE9D,SAAQC,SAAS,QAAO,kBAAiB;AAGzC,OAAO,eAAeC,aACpBC,cAAsB,EACtBC,UAAmB,EACnBC,MAA6B,EAC7BC,KAA8D;IAE9D,IAAI;QACF,MAAMC,SAAS,MAAMP,oBAAoBG;QACzCE,OAAOG,GAAG,CAAC,CAAC,QAAQ,EAAEL,eAAe,cAAc,CAAC;QACpD,OAAOI;IACT,EAAE,OAAOE,KAAc;QACrB,IAAI,CAACV,YAAYU,QAAQA,IAAIC,UAAU,KAAK,KAAK;YAC/C,MAAMC,UAAUF,eAAeG,QAAQH,IAAIE,OAAO,GAAG,GAAGF,KAAK;YAC7D,MAAM,IAAIR,UAAU,CAAC,sDAAsD,EAAEU,SAAS,EAAE;QAC1F;QAEA,MAAME,iBACJT,cACC,MAAMN,QAAQ;YACbgB,SAAS;YACTH,SAAS,CAAC,QAAQ,EAAER,eAAe,6CAA6C,CAAC;QACnF;QAEF,IAAIC,YAAY;YACdC,OAAOU,IAAI,CAAC,CAAC,QAAQ,EAAEZ,eAAe,uCAAuC,CAAC;QAChF;QAEAG,MAAME,GAAG,CAAC;YACRQ,gBAAgBH,iBAAiB,QAAQ;YACzCI,MAAM;QACR;QAEA,IAAIJ,gBAAgB;YAClBR,OAAOG,GAAG,CAAC;YACX,OAAOU;QACT;QAEA,MAAM,IAAIjB,UAAU,CAAC,QAAQ,EAAEE,eAAe,gBAAgB,CAAC,EAAE;IACnE;AACF"}
@@ -45,7 +45,7 @@ export async function selectTemplate({ options, remoteTemplateInfo, trace }) {
45
45
  unattended
46
46
  });
47
47
  trace.log({
48
- selectedOption: templateName,
48
+ selectedOption: Object.hasOwn(templates, templateName) ? templateName : 'custom',
49
49
  step: 'selectProjectTemplate'
50
50
  });
51
51
  const resolvedTemplate = templates[templateName];
@@ -1 +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 {\n getInstallCommand,\n installDeclaredPackages,\n} from '../../util/packageManager/installPackages.js'\nimport {type PackageManager} from '../../util/packageManager/packageManagerChoice.js'\nimport {bootstrapTemplate} from './bootstrapTemplate.js'\nimport {tryGitInit} from './git.js'\nimport {flagOrDefault, shouldPrompt, writeStagingEnvIfNeeded} from './initHelpers.js'\nimport {type RepoInfo} from './remoteTemplate.js'\nimport {resolvePackageManager} from './resolvePackageManager.js'\nimport templates from './templates/index.js'\nimport {type InitOptions, type ProjectTemplate} from './types.js'\n\ninterface SelectedTemplate {\n template: ProjectTemplate | undefined\n templateName: string\n useTypeScript: boolean\n}\n\ninterface TemplateChoice {\n name: string\n value: string\n}\n\nexport const templateChoices: TemplateChoice[] = [\n {name: 'Clean project with no predefined schema types', value: 'clean'},\n {name: 'Blog (schema)', value: 'blog'},\n {name: 'E-commerce (Shopify)', value: 'shopify'},\n {name: 'Movie project (schema + sample data)', value: 'moviedb'},\n {name: 'Page Builder (presets)', value: 'page-builder'},\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: templateChoices,\n message: 'Select project template',\n })\n}\n\nexport async function selectTemplate({\n options,\n remoteTemplateInfo,\n trace,\n}: {\n options: InitOptions\n remoteTemplateInfo: RepoInfo | undefined\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>\n}): Promise<SelectedTemplate> {\n const {template, typescript, unattended} = options\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 = flagOrDefault(typescript, true)\n if (!remoteTemplateInfo && resolvedTemplate && resolvedTemplate.typescriptOnly === true) {\n useTypeScript = true\n } else if (shouldPrompt(unattended, typescript)) {\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 datasetName,\n defaults,\n displayName,\n options,\n organizationId,\n output,\n outputPath,\n projectId,\n remoteTemplateInfo,\n sluggedName,\n templateName,\n trace,\n useTypeScript,\n workbench,\n workDir,\n}: {\n datasetName: string\n defaults: {projectName: string}\n displayName: string\n options: InitOptions\n organizationId: string | undefined\n output: Output\n outputPath: string\n projectId: string\n remoteTemplateInfo: RepoInfo | undefined\n sluggedName: string\n templateName: string\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>\n useTypeScript: boolean\n workbench: boolean\n workDir: string\n}): Promise<{pkgManager: PackageManager}> {\n const {autoUpdates, git, install, overwriteFiles, packageManager, templateToken, unattended} =\n options\n const noGit = typeof git === 'boolean' && !git ? true : undefined\n\n await bootstrapTemplate({\n autoUpdates,\n bearerToken: templateToken,\n dataset: datasetName,\n organizationId,\n output,\n outputPath,\n overwriteFiles,\n packageName: sluggedName,\n projectId,\n projectName: displayName || defaults.projectName,\n remoteTemplateInfo,\n templateName,\n useTypeScript,\n workbench,\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 if (install) {\n await installDeclaredPackages(outputPath, pkgManager, {\n output,\n workDir,\n })\n } else {\n output.log(`Skipped dependency install. Run ${getInstallCommand(pkgManager)} to install them.`)\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","getInstallCommand","installDeclaredPackages","bootstrapTemplate","tryGitInit","flagOrDefault","shouldPrompt","writeStagingEnvIfNeeded","resolvePackageManager","templates","templateChoices","name","value","promptForTemplate","params","defaultTemplate","unattended","template","choices","message","selectTemplate","options","remoteTemplateInfo","trace","typescript","templateName","log","selectedOption","step","resolvedTemplate","useTypeScript","typescriptOnly","scaffoldAndInstall","datasetName","defaults","displayName","organizationId","output","outputPath","projectId","sluggedName","workbench","workDir","autoUpdates","git","install","overwriteFiles","packageManager","templateToken","noGit","undefined","bearerToken","dataset","packageName","projectName","pkgManager","interactive","targetDir","useGit","Boolean","commitMessage"],"mappings":"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"}
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 {\n getInstallCommand,\n installDeclaredPackages,\n} from '../../util/packageManager/installPackages.js'\nimport {type PackageManager} from '../../util/packageManager/packageManagerChoice.js'\nimport {bootstrapTemplate} from './bootstrapTemplate.js'\nimport {tryGitInit} from './git.js'\nimport {flagOrDefault, shouldPrompt, writeStagingEnvIfNeeded} from './initHelpers.js'\nimport {type RepoInfo} from './remoteTemplate.js'\nimport {resolvePackageManager} from './resolvePackageManager.js'\nimport templates from './templates/index.js'\nimport {type InitOptions, type ProjectTemplate} from './types.js'\n\ninterface SelectedTemplate {\n template: ProjectTemplate | undefined\n templateName: string\n useTypeScript: boolean\n}\n\ninterface TemplateChoice {\n name: string\n value: string\n}\n\nexport const templateChoices: TemplateChoice[] = [\n {name: 'Clean project with no predefined schema types', value: 'clean'},\n {name: 'Blog (schema)', value: 'blog'},\n {name: 'E-commerce (Shopify)', value: 'shopify'},\n {name: 'Movie project (schema + sample data)', value: 'moviedb'},\n {name: 'Page Builder (presets)', value: 'page-builder'},\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: templateChoices,\n message: 'Select project template',\n })\n}\n\nexport async function selectTemplate({\n options,\n remoteTemplateInfo,\n trace,\n}: {\n options: InitOptions\n remoteTemplateInfo: RepoInfo | undefined\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>\n}): Promise<SelectedTemplate> {\n const {template, typescript, unattended} = options\n const templateName = await promptForTemplate({template, unattended})\n trace.log({\n selectedOption: Object.hasOwn(templates, templateName) ? templateName : 'custom',\n step: 'selectProjectTemplate',\n })\n\n const resolvedTemplate = templates[templateName]\n\n let useTypeScript = flagOrDefault(typescript, true)\n if (!remoteTemplateInfo && resolvedTemplate && resolvedTemplate.typescriptOnly === true) {\n useTypeScript = true\n } else if (shouldPrompt(unattended, typescript)) {\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 datasetName,\n defaults,\n displayName,\n options,\n organizationId,\n output,\n outputPath,\n projectId,\n remoteTemplateInfo,\n sluggedName,\n templateName,\n trace,\n useTypeScript,\n workbench,\n workDir,\n}: {\n datasetName: string\n defaults: {projectName: string}\n displayName: string\n options: InitOptions\n organizationId: string | undefined\n output: Output\n outputPath: string\n projectId: string\n remoteTemplateInfo: RepoInfo | undefined\n sluggedName: string\n templateName: string\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>\n useTypeScript: boolean\n workbench: boolean\n workDir: string\n}): Promise<{pkgManager: PackageManager}> {\n const {autoUpdates, git, install, overwriteFiles, packageManager, templateToken, unattended} =\n options\n const noGit = typeof git === 'boolean' && !git ? true : undefined\n\n await bootstrapTemplate({\n autoUpdates,\n bearerToken: templateToken,\n dataset: datasetName,\n organizationId,\n output,\n outputPath,\n overwriteFiles,\n packageName: sluggedName,\n projectId,\n projectName: displayName || defaults.projectName,\n remoteTemplateInfo,\n templateName,\n useTypeScript,\n workbench,\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 if (install) {\n await installDeclaredPackages(outputPath, pkgManager, {\n output,\n workDir,\n })\n } else {\n output.log(`Skipped dependency install. Run ${getInstallCommand(pkgManager)} to install them.`)\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","getInstallCommand","installDeclaredPackages","bootstrapTemplate","tryGitInit","flagOrDefault","shouldPrompt","writeStagingEnvIfNeeded","resolvePackageManager","templates","templateChoices","name","value","promptForTemplate","params","defaultTemplate","unattended","template","choices","message","selectTemplate","options","remoteTemplateInfo","trace","typescript","templateName","log","selectedOption","Object","hasOwn","step","resolvedTemplate","useTypeScript","typescriptOnly","scaffoldAndInstall","datasetName","defaults","displayName","organizationId","output","outputPath","projectId","sluggedName","workbench","workDir","autoUpdates","git","install","overwriteFiles","packageManager","templateToken","noGit","undefined","bearerToken","dataset","packageName","projectName","pkgManager","interactive","targetDir","useGit","Boolean","commitMessage"],"mappings":"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"}
@@ -11,6 +11,7 @@ import { apiRoutes } from '../generated/apiRoutes.js';
11
11
  import { promptForProject } from '../prompts/promptForProject.js';
12
12
  import { performApiRequest } from '../services/api.js';
13
13
  import { getDatasetFlag, getProjectIdFlag } from '../util/sharedFlags.js';
14
+ import { defineCommandTelemetry } from '../util/telemetry/commandTelemetry.js';
14
15
  const apiDebug = subdebug('api');
15
16
  const METHOD_RE = /^[a-z]+$/i;
16
17
  const BODYLESS_METHODS = new Set([
@@ -152,6 +153,15 @@ specific token instead - for example in CI or when the CLI is not logged in
152
153
  helpValue: '<token>'
153
154
  })
154
155
  };
156
+ static telemetry = defineCommandTelemetry(this.flags, {
157
+ redact: [
158
+ 'token',
159
+ 'header',
160
+ 'field',
161
+ 'raw-field',
162
+ 'input'
163
+ ]
164
+ });
155
165
  /**
156
166
  * Read the raw body for `--input`, or the content referenced by a `@-`
157
167
  * field value. Returns raw bytes so binary bodies survive unmodified.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/api.ts"],"sourcesContent":["import {readFileSync} from 'node:fs'\nimport {readFile} from 'node:fs/promises'\nimport {buffer} from 'node:stream/consumers'\nimport {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {colorizeJson, exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {ApiUsageError, ProjectIdRequiredError} from '../actions/api/errors.js'\nimport {fieldsToQuery, type FieldValue, parseFields} from '../actions/api/parseFields.js'\nimport {type ResolvedEndpoint, resolveEndpoint} from '../actions/api/resolveEndpoint.js'\nimport {apiRoutes} from '../generated/apiRoutes.js'\nimport {promptForProject} from '../prompts/promptForProject.js'\nimport {type ApiResponse, performApiRequest} from '../services/api.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../util/sharedFlags.js'\n\nconst apiDebug = subdebug('api')\n\nconst METHOD_RE = /^[a-z]+$/i\n\nconst BODYLESS_METHODS = new Set(['GET', 'HEAD'])\n\nexport class ApiCommand extends SanityCommand<typeof ApiCommand> {\n static override args = {\n endpoint: Args.string({\n description:\n 'API path (eg \"projects\" or \"data/query/{dataset}\"), optionally with placeholders, or a full https://*.api.sanity.io URL',\n required: true,\n }),\n }\n\n static override description = `Make an authenticated HTTP request to a Sanity API\n\nThe endpoint argument is an API path as documented in the published OpenAPI\nspecifications - list them with \"sanity openapi list\" and inspect one with\n\"sanity openapi get <slug>\". Paths can be copied verbatim from the specs:\n{projectId} and {dataset} placeholders are filled in from flags or the CLI\nconfiguration, and the API host (api.sanity.io or <projectId>.api.sanity.io)\nis chosen based on the specs' routing information.\n\nThe default request method is GET, or POST when fields or --input are\nprovided. For GET/HEAD requests, fields are sent as query parameters;\notherwise they are combined into a JSON request body sent with\n\"Content-Type: application/json\". Raw --input bodies are sent without a\ndefault Content-Type - provide one with -H when the API requires it. The\nresponse body is written to stdout.\n\nRequests are authenticated with the token from \"sanity login\". To use a\nspecific token instead - for example in CI or when the CLI is not logged in\n- pass --token or set the SANITY_AUTH_TOKEN environment variable. Pass\n--anonymous to send no token at all.`\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> users/me',\n description: 'Get the current user',\n },\n {\n command: '<%= config.bin %> <%= command.id %> projects/{projectId}',\n description: 'Get the current project (placeholder filled from CLI config)',\n },\n {\n command: `<%= config.bin %> <%= command.id %> 'data/query/{dataset}' -f query='*[_type == \"movie\"][0..2]'`,\n description: 'Run a GROQ query against the project host',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> projects/{projectId} -X PATCH -F displayName=\"My project\"',\n description: 'Send a JSON body built from typed fields',\n },\n {\n command: `echo '{\"mutations\": []}' | <%= config.bin %> <%= command.id %> 'data/mutate/{dataset}' --input - -H 'Content-Type: application/json'`,\n description: 'Send a raw request body from stdin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> jobs/123 --include --api-version v2025-02-19',\n description: 'Include the response status and headers, pinning the API version',\n },\n {\n command: 'SANITY_AUTH_TOKEN=<token> <%= config.bin %> <%= command.id %> users/me',\n description: 'Authenticate with a specific token instead of the logged-in session',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID for {projectId} placeholders and project-hosted APIs',\n semantics: 'override',\n }),\n ...getDatasetFlag({\n description: 'Dataset for {dataset} placeholders',\n semantics: 'override',\n }),\n anonymous: Flags.boolean({\n default: false,\n description: 'Send the request without an authorization token',\n }),\n 'api-version': Flags.string({\n description:\n 'API version to use (eg v2025-02-19). Defaults to a version embedded in the endpoint path, or the version from the matching OpenAPI spec',\n helpValue: '<version>',\n }),\n field: Flags.string({\n char: 'F',\n description:\n 'Add a typed parameter (key=value): true/false/null and numbers are converted, @file reads the value from a file, @- from stdin',\n helpValue: '<key=value>',\n multiple: true,\n }),\n global: Flags.boolean({\n description: 'Force the request to the global API host (api.sanity.io)',\n exclusive: ['project-hosted'],\n }),\n header: Flags.string({\n char: 'H',\n description: 'Add an HTTP request header (key: value)',\n helpValue: '<key:value>',\n multiple: true,\n }),\n include: Flags.boolean({\n char: 'i',\n default: false,\n description: 'Include the HTTP response status and headers in the output',\n }),\n input: Flags.string({\n description:\n 'Read the raw request body from a file (use \"-\" for stdin). Sent without a default Content-Type - provide one with -H when the API requires it',\n exclusive: ['field', 'raw-field'],\n helpValue: '<file>',\n }),\n method: Flags.string({\n char: 'X',\n description: 'HTTP method to use (default GET, or POST when fields or --input are provided)',\n helpValue: '<method>',\n }),\n pretty: Flags.boolean({\n default: false,\n description: 'Colorize JSON output',\n }),\n 'project-hosted': Flags.boolean({\n description: 'Force the request to the project API host (<projectId>.api.sanity.io)',\n exclusive: ['global'],\n }),\n 'raw-field': Flags.string({\n char: 'f',\n description: 'Add a string parameter (key=value)',\n helpValue: '<key=value>',\n multiple: true,\n }),\n token: Flags.string({\n char: 't',\n description: 'API token to authenticate with, instead of the logged-in user token',\n exclusive: ['anonymous'],\n helpValue: '<token>',\n }),\n }\n\n /**\n * Read the raw body for `--input`, or the content referenced by a `@-`\n * field value. Returns raw bytes so binary bodies survive unmodified.\n * Extracted so tests can substitute stdin.\n */\n protected readStdin(): Promise<Buffer> {\n return buffer(process.stdin)\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(ApiCommand)\n\n try {\n await this.performRequest(args.endpoint, flags)\n } catch (error) {\n if (error instanceof ApiUsageError) {\n this.error(error.message, {exit: exitCodes.USAGE_ERROR})\n }\n throw error\n }\n }\n\n private async performRequest(\n endpoint: string,\n flags: (typeof ApiCommand.prototype)['flags'],\n ): Promise<void> {\n const stdin = await this.resolveStdin(flags)\n\n const fields = parseFields({\n fields: flags.field,\n rawFields: flags['raw-field'],\n readFile: (path) => readFileSync(path, 'utf8'),\n stdin: stdin?.toString('utf8'),\n })\n const hasFields = Object.keys(fields).length > 0\n\n const method = this.resolveMethod(flags.method, hasFields || flags.input !== undefined)\n const useQueryFields = BODYLESS_METHODS.has(method)\n\n const body = await this.resolveBody(flags, fields, hasFields, useQueryFields, stdin)\n const query = useQueryFields && hasFields ? fieldsToQuery(fields) : {}\n\n const resolved = await this.resolveTarget(endpoint, flags)\n apiDebug('Resolved endpoint', resolved)\n\n const response = await performApiRequest({\n ...(body === undefined ? {} : {body}),\n headers: parseHeaders(flags.header ?? []),\n method,\n query,\n resolved,\n token: flags.token,\n unauthenticated: flags.anonymous,\n })\n\n this.printResponse(response, flags)\n\n if (response.statusCode >= 400) {\n const statusLine = `HTTP ${response.statusCode}${\n response.statusMessage ? ` ${response.statusMessage}` : ''\n }`\n const loginHint =\n response.statusCode === 401 && !flags.anonymous\n ? `. You may need to login again with ${styleText('cyan', 'sanity login')}`\n : ''\n this.error(`${statusLine}${loginHint}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n private printResponse(response: ApiResponse, flags: {include: boolean; pretty: boolean}): void {\n if (flags.include) {\n this.log(\n `HTTP ${response.statusCode}${response.statusMessage ? ` ${response.statusMessage}` : ''}`,\n )\n for (const [key, value] of Object.entries(response.headers)) {\n this.log(`${key}: ${value}`)\n }\n this.log('')\n }\n\n if (!response.jsonBody) {\n if (response.rawBody !== '') this.log(response.rawBody)\n return\n }\n\n this.log(flags.pretty ? colorizeJson(response.body) : JSON.stringify(response.body, null, 2))\n }\n\n private async resolveBody(\n flags: {input?: string},\n fields: Record<string, FieldValue>,\n hasFields: boolean,\n useQueryFields: boolean,\n stdin: Buffer | undefined,\n ): Promise<Buffer | unknown | undefined> {\n if (flags.input !== undefined) {\n if (flags.input === '-') return stdin\n try {\n // Read raw bytes - `--input` bodies may be binary (eg asset uploads)\n return await readFile(flags.input)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new ApiUsageError(`Failed to read --input file \"${flags.input}\": ${message}`)\n }\n }\n\n return hasFields && !useQueryFields ? fields : undefined\n }\n\n private resolveMethod(methodFlag: string | undefined, hasBody: boolean): string {\n if (methodFlag === undefined) {\n return hasBody ? 'POST' : 'GET'\n }\n if (!METHOD_RE.test(methodFlag)) {\n throw new ApiUsageError(`Invalid HTTP method \"${methodFlag}\"`)\n }\n return methodFlag.toUpperCase()\n }\n\n private async resolveStdin(flags: {\n field?: string[]\n input?: string\n }): Promise<Buffer | undefined> {\n const needsStdin =\n flags.input === '-' || (flags.field ?? []).some((field) => field.endsWith('=@-'))\n return needsStdin ? this.readStdin() : undefined\n }\n\n private async resolveTarget(\n endpoint: string,\n flags: {\n 'api-version'?: string\n dataset?: string\n global?: boolean\n project?: string\n 'project-hosted'?: boolean\n },\n ): Promise<ResolvedEndpoint> {\n const cliConfig = await this.tryGetCliConfig()\n\n const baseOptions = {\n apiVersion: flags['api-version'],\n dataset: flags.dataset ?? cliConfig.api?.dataset,\n endpoint,\n forceHost: flags.global ? ('global' as const) : undefined,\n routes: apiRoutes,\n }\n const forceHost = flags['project-hosted'] ? ('project' as const) : baseOptions.forceHost\n\n try {\n return resolveEndpoint({\n ...baseOptions,\n forceHost,\n projectId: flags.project ?? cliConfig.api?.projectId,\n })\n } catch (error) {\n if (!(error instanceof ProjectIdRequiredError)) throw error\n\n // The request needs a project ID that flags/config didn't provide -\n // resolve one interactively (or fail with actionable suggestions).\n const projectId = await this.getProjectId({fallback: () => promptForProject({})})\n return resolveEndpoint({...baseOptions, forceHost, projectId})\n }\n }\n}\n\nfunction parseHeaders(headerFlags: string[]): Record<string, string> {\n // Null-prototype for the same reason as the field containers in parseFields\n const headers: Record<string, string> = Object.create(null)\n\n for (const header of headerFlags) {\n const separatorIndex = header.indexOf(':')\n if (separatorIndex < 1) {\n throw new ApiUsageError(`Invalid --header \"${header}\": expected \"key: value\" format`)\n }\n headers[header.slice(0, separatorIndex).trim()] = header.slice(separatorIndex + 1).trim()\n }\n\n return headers\n}\n"],"names":["readFileSync","readFile","buffer","styleText","Args","Flags","colorizeJson","exitCodes","SanityCommand","subdebug","ApiUsageError","ProjectIdRequiredError","fieldsToQuery","parseFields","resolveEndpoint","apiRoutes","promptForProject","performApiRequest","getDatasetFlag","getProjectIdFlag","apiDebug","METHOD_RE","BODYLESS_METHODS","Set","ApiCommand","args","endpoint","string","description","required","examples","command","flags","semantics","anonymous","boolean","default","helpValue","field","char","multiple","global","exclusive","header","include","input","method","pretty","token","readStdin","process","stdin","run","parse","performRequest","error","message","exit","USAGE_ERROR","resolveStdin","fields","rawFields","path","toString","hasFields","Object","keys","length","resolveMethod","undefined","useQueryFields","has","body","resolveBody","query","resolved","resolveTarget","response","headers","parseHeaders","unauthenticated","printResponse","statusCode","statusLine","statusMessage","loginHint","RUNTIME_ERROR","log","key","value","entries","jsonBody","rawBody","JSON","stringify","Error","String","methodFlag","hasBody","test","toUpperCase","needsStdin","some","endsWith","cliConfig","tryGetCliConfig","baseOptions","apiVersion","dataset","api","forceHost","routes","projectId","project","getProjectId","fallback","headerFlags","create","separatorIndex","indexOf","slice","trim"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/commands/api.ts"],"sourcesContent":["import {readFileSync} from 'node:fs'\nimport {readFile} from 'node:fs/promises'\nimport {buffer} from 'node:stream/consumers'\nimport {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {colorizeJson, exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {ApiUsageError, ProjectIdRequiredError} from '../actions/api/errors.js'\nimport {fieldsToQuery, type FieldValue, parseFields} from '../actions/api/parseFields.js'\nimport {type ResolvedEndpoint, resolveEndpoint} from '../actions/api/resolveEndpoint.js'\nimport {apiRoutes} from '../generated/apiRoutes.js'\nimport {promptForProject} from '../prompts/promptForProject.js'\nimport {type ApiResponse, performApiRequest} from '../services/api.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../util/sharedFlags.js'\nimport {defineCommandTelemetry} from '../util/telemetry/commandTelemetry.js'\n\nconst apiDebug = subdebug('api')\n\nconst METHOD_RE = /^[a-z]+$/i\n\nconst BODYLESS_METHODS = new Set(['GET', 'HEAD'])\n\nexport class ApiCommand extends SanityCommand<typeof ApiCommand> {\n static override args = {\n endpoint: Args.string({\n description:\n 'API path (eg \"projects\" or \"data/query/{dataset}\"), optionally with placeholders, or a full https://*.api.sanity.io URL',\n required: true,\n }),\n }\n\n static override description = `Make an authenticated HTTP request to a Sanity API\n\nThe endpoint argument is an API path as documented in the published OpenAPI\nspecifications - list them with \"sanity openapi list\" and inspect one with\n\"sanity openapi get <slug>\". Paths can be copied verbatim from the specs:\n{projectId} and {dataset} placeholders are filled in from flags or the CLI\nconfiguration, and the API host (api.sanity.io or <projectId>.api.sanity.io)\nis chosen based on the specs' routing information.\n\nThe default request method is GET, or POST when fields or --input are\nprovided. For GET/HEAD requests, fields are sent as query parameters;\notherwise they are combined into a JSON request body sent with\n\"Content-Type: application/json\". Raw --input bodies are sent without a\ndefault Content-Type - provide one with -H when the API requires it. The\nresponse body is written to stdout.\n\nRequests are authenticated with the token from \"sanity login\". To use a\nspecific token instead - for example in CI or when the CLI is not logged in\n- pass --token or set the SANITY_AUTH_TOKEN environment variable. Pass\n--anonymous to send no token at all.`\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> users/me',\n description: 'Get the current user',\n },\n {\n command: '<%= config.bin %> <%= command.id %> projects/{projectId}',\n description: 'Get the current project (placeholder filled from CLI config)',\n },\n {\n command: `<%= config.bin %> <%= command.id %> 'data/query/{dataset}' -f query='*[_type == \"movie\"][0..2]'`,\n description: 'Run a GROQ query against the project host',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> projects/{projectId} -X PATCH -F displayName=\"My project\"',\n description: 'Send a JSON body built from typed fields',\n },\n {\n command: `echo '{\"mutations\": []}' | <%= config.bin %> <%= command.id %> 'data/mutate/{dataset}' --input - -H 'Content-Type: application/json'`,\n description: 'Send a raw request body from stdin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> jobs/123 --include --api-version v2025-02-19',\n description: 'Include the response status and headers, pinning the API version',\n },\n {\n command: 'SANITY_AUTH_TOKEN=<token> <%= config.bin %> <%= command.id %> users/me',\n description: 'Authenticate with a specific token instead of the logged-in session',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID for {projectId} placeholders and project-hosted APIs',\n semantics: 'override',\n }),\n ...getDatasetFlag({\n description: 'Dataset for {dataset} placeholders',\n semantics: 'override',\n }),\n anonymous: Flags.boolean({\n default: false,\n description: 'Send the request without an authorization token',\n }),\n 'api-version': Flags.string({\n description:\n 'API version to use (eg v2025-02-19). Defaults to a version embedded in the endpoint path, or the version from the matching OpenAPI spec',\n helpValue: '<version>',\n }),\n field: Flags.string({\n char: 'F',\n description:\n 'Add a typed parameter (key=value): true/false/null and numbers are converted, @file reads the value from a file, @- from stdin',\n helpValue: '<key=value>',\n multiple: true,\n }),\n global: Flags.boolean({\n description: 'Force the request to the global API host (api.sanity.io)',\n exclusive: ['project-hosted'],\n }),\n header: Flags.string({\n char: 'H',\n description: 'Add an HTTP request header (key: value)',\n helpValue: '<key:value>',\n multiple: true,\n }),\n include: Flags.boolean({\n char: 'i',\n default: false,\n description: 'Include the HTTP response status and headers in the output',\n }),\n input: Flags.string({\n description:\n 'Read the raw request body from a file (use \"-\" for stdin). Sent without a default Content-Type - provide one with -H when the API requires it',\n exclusive: ['field', 'raw-field'],\n helpValue: '<file>',\n }),\n method: Flags.string({\n char: 'X',\n description: 'HTTP method to use (default GET, or POST when fields or --input are provided)',\n helpValue: '<method>',\n }),\n pretty: Flags.boolean({\n default: false,\n description: 'Colorize JSON output',\n }),\n 'project-hosted': Flags.boolean({\n description: 'Force the request to the project API host (<projectId>.api.sanity.io)',\n exclusive: ['global'],\n }),\n 'raw-field': Flags.string({\n char: 'f',\n description: 'Add a string parameter (key=value)',\n helpValue: '<key=value>',\n multiple: true,\n }),\n token: Flags.string({\n char: 't',\n description: 'API token to authenticate with, instead of the logged-in user token',\n exclusive: ['anonymous'],\n helpValue: '<token>',\n }),\n }\n\n static telemetry = defineCommandTelemetry(this.flags, {\n redact: ['token', 'header', 'field', 'raw-field', 'input'],\n })\n\n /**\n * Read the raw body for `--input`, or the content referenced by a `@-`\n * field value. Returns raw bytes so binary bodies survive unmodified.\n * Extracted so tests can substitute stdin.\n */\n protected readStdin(): Promise<Buffer> {\n return buffer(process.stdin)\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(ApiCommand)\n\n try {\n await this.performRequest(args.endpoint, flags)\n } catch (error) {\n if (error instanceof ApiUsageError) {\n this.error(error.message, {exit: exitCodes.USAGE_ERROR})\n }\n throw error\n }\n }\n\n private async performRequest(\n endpoint: string,\n flags: (typeof ApiCommand.prototype)['flags'],\n ): Promise<void> {\n const stdin = await this.resolveStdin(flags)\n\n const fields = parseFields({\n fields: flags.field,\n rawFields: flags['raw-field'],\n readFile: (path) => readFileSync(path, 'utf8'),\n stdin: stdin?.toString('utf8'),\n })\n const hasFields = Object.keys(fields).length > 0\n\n const method = this.resolveMethod(flags.method, hasFields || flags.input !== undefined)\n const useQueryFields = BODYLESS_METHODS.has(method)\n\n const body = await this.resolveBody(flags, fields, hasFields, useQueryFields, stdin)\n const query = useQueryFields && hasFields ? fieldsToQuery(fields) : {}\n\n const resolved = await this.resolveTarget(endpoint, flags)\n apiDebug('Resolved endpoint', resolved)\n\n const response = await performApiRequest({\n ...(body === undefined ? {} : {body}),\n headers: parseHeaders(flags.header ?? []),\n method,\n query,\n resolved,\n token: flags.token,\n unauthenticated: flags.anonymous,\n })\n\n this.printResponse(response, flags)\n\n if (response.statusCode >= 400) {\n const statusLine = `HTTP ${response.statusCode}${\n response.statusMessage ? ` ${response.statusMessage}` : ''\n }`\n const loginHint =\n response.statusCode === 401 && !flags.anonymous\n ? `. You may need to login again with ${styleText('cyan', 'sanity login')}`\n : ''\n this.error(`${statusLine}${loginHint}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n private printResponse(response: ApiResponse, flags: {include: boolean; pretty: boolean}): void {\n if (flags.include) {\n this.log(\n `HTTP ${response.statusCode}${response.statusMessage ? ` ${response.statusMessage}` : ''}`,\n )\n for (const [key, value] of Object.entries(response.headers)) {\n this.log(`${key}: ${value}`)\n }\n this.log('')\n }\n\n if (!response.jsonBody) {\n if (response.rawBody !== '') this.log(response.rawBody)\n return\n }\n\n this.log(flags.pretty ? colorizeJson(response.body) : JSON.stringify(response.body, null, 2))\n }\n\n private async resolveBody(\n flags: {input?: string},\n fields: Record<string, FieldValue>,\n hasFields: boolean,\n useQueryFields: boolean,\n stdin: Buffer | undefined,\n ): Promise<Buffer | unknown | undefined> {\n if (flags.input !== undefined) {\n if (flags.input === '-') return stdin\n try {\n // Read raw bytes - `--input` bodies may be binary (eg asset uploads)\n return await readFile(flags.input)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new ApiUsageError(`Failed to read --input file \"${flags.input}\": ${message}`)\n }\n }\n\n return hasFields && !useQueryFields ? fields : undefined\n }\n\n private resolveMethod(methodFlag: string | undefined, hasBody: boolean): string {\n if (methodFlag === undefined) {\n return hasBody ? 'POST' : 'GET'\n }\n if (!METHOD_RE.test(methodFlag)) {\n throw new ApiUsageError(`Invalid HTTP method \"${methodFlag}\"`)\n }\n return methodFlag.toUpperCase()\n }\n\n private async resolveStdin(flags: {\n field?: string[]\n input?: string\n }): Promise<Buffer | undefined> {\n const needsStdin =\n flags.input === '-' || (flags.field ?? []).some((field) => field.endsWith('=@-'))\n return needsStdin ? this.readStdin() : undefined\n }\n\n private async resolveTarget(\n endpoint: string,\n flags: {\n 'api-version'?: string\n dataset?: string\n global?: boolean\n project?: string\n 'project-hosted'?: boolean\n },\n ): Promise<ResolvedEndpoint> {\n const cliConfig = await this.tryGetCliConfig()\n\n const baseOptions = {\n apiVersion: flags['api-version'],\n dataset: flags.dataset ?? cliConfig.api?.dataset,\n endpoint,\n forceHost: flags.global ? ('global' as const) : undefined,\n routes: apiRoutes,\n }\n const forceHost = flags['project-hosted'] ? ('project' as const) : baseOptions.forceHost\n\n try {\n return resolveEndpoint({\n ...baseOptions,\n forceHost,\n projectId: flags.project ?? cliConfig.api?.projectId,\n })\n } catch (error) {\n if (!(error instanceof ProjectIdRequiredError)) throw error\n\n // The request needs a project ID that flags/config didn't provide -\n // resolve one interactively (or fail with actionable suggestions).\n const projectId = await this.getProjectId({fallback: () => promptForProject({})})\n return resolveEndpoint({...baseOptions, forceHost, projectId})\n }\n }\n}\n\nfunction parseHeaders(headerFlags: string[]): Record<string, string> {\n // Null-prototype for the same reason as the field containers in parseFields\n const headers: Record<string, string> = Object.create(null)\n\n for (const header of headerFlags) {\n const separatorIndex = header.indexOf(':')\n if (separatorIndex < 1) {\n throw new ApiUsageError(`Invalid --header \"${header}\": expected \"key: value\" format`)\n }\n headers[header.slice(0, separatorIndex).trim()] = header.slice(separatorIndex + 1).trim()\n }\n\n return headers\n}\n"],"names":["readFileSync","readFile","buffer","styleText","Args","Flags","colorizeJson","exitCodes","SanityCommand","subdebug","ApiUsageError","ProjectIdRequiredError","fieldsToQuery","parseFields","resolveEndpoint","apiRoutes","promptForProject","performApiRequest","getDatasetFlag","getProjectIdFlag","defineCommandTelemetry","apiDebug","METHOD_RE","BODYLESS_METHODS","Set","ApiCommand","args","endpoint","string","description","required","examples","command","flags","semantics","anonymous","boolean","default","helpValue","field","char","multiple","global","exclusive","header","include","input","method","pretty","token","telemetry","redact","readStdin","process","stdin","run","parse","performRequest","error","message","exit","USAGE_ERROR","resolveStdin","fields","rawFields","path","toString","hasFields","Object","keys","length","resolveMethod","undefined","useQueryFields","has","body","resolveBody","query","resolved","resolveTarget","response","headers","parseHeaders","unauthenticated","printResponse","statusCode","statusLine","statusMessage","loginHint","RUNTIME_ERROR","log","key","value","entries","jsonBody","rawBody","JSON","stringify","Error","String","methodFlag","hasBody","test","toUpperCase","needsStdin","some","endsWith","cliConfig","tryGetCliConfig","baseOptions","apiVersion","dataset","api","forceHost","routes","projectId","project","getProjectId","fallback","headerFlags","create","separatorIndex","indexOf","slice","trim"],"mappings":"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"}
@@ -26,6 +26,7 @@ import { listDatasets } from '../../services/datasets.js';
26
26
  import { humanFileSize } from '../../util/humanFileSize.js';
27
27
  import { isPathDirName } from '../../util/isPathDirName.js';
28
28
  import { getProjectIdFlag } from '../../util/sharedFlags.js';
29
+ import { defineCommandTelemetry } from '../../util/telemetry/commandTelemetry.js';
29
30
  const DEFAULT_DOWNLOAD_CONCURRENCY = 10;
30
31
  const MAX_DOWNLOAD_CONCURRENCY = 24;
31
32
  export class DownloadBackupCommand extends SanityCommand {
@@ -77,6 +78,11 @@ export class DownloadBackupCommand extends SanityCommand {
77
78
  static hiddenAliases = [
78
79
  'backup:download'
79
80
  ];
81
+ static telemetry = defineCommandTelemetry(this.flags, {
82
+ redact: [
83
+ 'out'
84
+ ]
85
+ });
80
86
  async run() {
81
87
  const { args } = await this.parse(DownloadBackupCommand);
82
88
  let { dataset } = args;