@sanity/cli 7.8.0 → 7.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/deploy/deployApp.js +13 -8
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployChecks.js +9 -8
- package/dist/actions/deploy/deployChecks.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +12 -9
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/resolveDeployTarget.js +3 -2
- package/dist/actions/deploy/resolveDeployTarget.js.map +1 -1
- package/dist/actions/deploy/urlUtils.js +0 -4
- package/dist/actions/deploy/urlUtils.js.map +1 -1
- package/dist/actions/documents/types.js.map +1 -1
- package/dist/actions/documents/validate.js +2 -1
- package/dist/actions/documents/validate.js.map +1 -1
- package/dist/actions/undeploy/adapters.js +3 -3
- package/dist/actions/undeploy/adapters.js.map +1 -1
- package/dist/actions/undeploy/runUndeploy.js +20 -6
- package/dist/actions/undeploy/runUndeploy.js.map +1 -1
- package/dist/actions/undeploy/undeployPlan.js +18 -3
- package/dist/actions/undeploy/undeployPlan.js.map +1 -1
- package/dist/commands/documents/validate.js +18 -17
- package/dist/commands/documents/validate.js.map +1 -1
- package/dist/commands/undeploy.js +13 -1
- package/dist/commands/undeploy.js.map +1 -1
- package/dist/server/devServer.js.map +1 -1
- package/oclif.manifest.json +990 -990
- package/package.json +6 -6
|
@@ -3,8 +3,9 @@ import { styleText } from 'node:util';
|
|
|
3
3
|
import { createGzip } from 'node:zlib';
|
|
4
4
|
import { exitCodes } from '@sanity/cli-core';
|
|
5
5
|
import { getErrorMessage } from '@sanity/cli-core/errors';
|
|
6
|
+
import { getCoreAppUrl } from '@sanity/cli-core/util';
|
|
6
7
|
import { spinner } from '@sanity/cli-core/ux';
|
|
7
|
-
import { buildExposes, deployConfig, deployCoreApp as deployWorkbenchCoreApp, getWorkbench, resolveInstallationId, summarizeConfig } from '@sanity/workbench-cli/deploy';
|
|
8
|
+
import { buildExposes, deployConfig, deployCoreApp as deployWorkbenchCoreApp, getApplicationUrl, getWorkbench, resolveInstallationId, summarizeConfig } from '@sanity/workbench-cli/deploy';
|
|
8
9
|
import { pack } from 'tar-fs';
|
|
9
10
|
import { createDeployment, updateUserApplication } from '../../services/userApplications.js';
|
|
10
11
|
import { getAppId } from '../../util/appId.js';
|
|
@@ -17,7 +18,6 @@ import { deployDebug } from './deployDebug.js';
|
|
|
17
18
|
import { listDeploymentFiles, reportExposes } from './deploymentPlan.js';
|
|
18
19
|
import { runDeploy } from './deployRunner.js';
|
|
19
20
|
import { findUserApplication } from './findUserApplication.js';
|
|
20
|
-
import { getCoreAppUrl } from './urlUtils.js';
|
|
21
21
|
const APP_PACKAGE = '@sanity/sdk-react';
|
|
22
22
|
export function deployApp(options) {
|
|
23
23
|
return runDeploy(options, {
|
|
@@ -90,7 +90,6 @@ export function deployApp(options) {
|
|
|
90
90
|
status: 'fail'
|
|
91
91
|
});
|
|
92
92
|
} else if (deployApplication && workbench) {
|
|
93
|
-
// Both modes, so a bad appId fails before the build rather than at the POST.
|
|
94
93
|
await checkAppTarget(reporter, {
|
|
95
94
|
appId,
|
|
96
95
|
isWorkbenchApp: true,
|
|
@@ -169,10 +168,11 @@ export function deployApp(options) {
|
|
|
169
168
|
}
|
|
170
169
|
// Dry run stops here — everything below mutates.
|
|
171
170
|
if (dryRun) return;
|
|
172
|
-
if (installationId && version && configAppType) {
|
|
171
|
+
if (installationId && version && configAppType && organizationId) {
|
|
173
172
|
await deployConfig({
|
|
174
173
|
appType: configAppType,
|
|
175
174
|
installationId,
|
|
175
|
+
organizationId,
|
|
176
176
|
output,
|
|
177
177
|
sourceDir,
|
|
178
178
|
version
|
|
@@ -215,13 +215,19 @@ export function deployApp(options) {
|
|
|
215
215
|
title: appTitle,
|
|
216
216
|
version
|
|
217
217
|
});
|
|
218
|
+
const url = getApplicationUrl({
|
|
219
|
+
id: applicationId,
|
|
220
|
+
organizationId,
|
|
221
|
+
type: 'coreApp'
|
|
222
|
+
});
|
|
218
223
|
logAppDeployed({
|
|
219
224
|
applicationId,
|
|
220
225
|
cliConfig,
|
|
221
226
|
created: !appId,
|
|
222
227
|
organizationId,
|
|
223
228
|
output,
|
|
224
|
-
title: appTitle
|
|
229
|
+
title: appTitle,
|
|
230
|
+
url
|
|
225
231
|
});
|
|
226
232
|
return {
|
|
227
233
|
applicationType: 'coreApp',
|
|
@@ -240,7 +246,7 @@ export function deployApp(options) {
|
|
|
240
246
|
slug
|
|
241
247
|
},
|
|
242
248
|
title: appTitle,
|
|
243
|
-
url
|
|
249
|
+
url
|
|
244
250
|
}
|
|
245
251
|
};
|
|
246
252
|
}
|
|
@@ -367,8 +373,7 @@ async function shipAppDeployment({ application, isAutoUpdating, manifest, source
|
|
|
367
373
|
}
|
|
368
374
|
spin.succeed();
|
|
369
375
|
}
|
|
370
|
-
export function logAppDeployed({ applicationId, cliConfig, created, organizationId, output, title }) {
|
|
371
|
-
const url = getCoreAppUrl(organizationId, applicationId);
|
|
376
|
+
export function logAppDeployed({ applicationId, cliConfig, created, organizationId, output, title, url = getCoreAppUrl(organizationId, applicationId) }) {
|
|
372
377
|
const named = title ? ` — "${title}"` : '';
|
|
373
378
|
output.log(`\nSuccess! Application deployed to ${styleText('cyan', url)}${named}`);
|
|
374
379
|
output.log(created ? 'Created a new application.' : 'Updated the existing application.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/deploy/deployApp.ts"],"sourcesContent":["import {basename, dirname} from 'node:path'\nimport {styleText} from 'node:util'\nimport {createGzip} from 'node:zlib'\n\nimport {exitCodes} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {\n buildExposes,\n deployConfig,\n deployCoreApp as deployWorkbenchCoreApp,\n getWorkbench,\n resolveInstallationId,\n summarizeConfig,\n} from '@sanity/workbench-cli/deploy'\nimport {pack} from 'tar-fs'\n\nimport {\n createDeployment,\n updateUserApplication,\n type UserApplication,\n type UserApplicationResolved,\n} from '../../services/userApplications.js'\nimport {getAppId} from '../../util/appId.js'\nimport {EXTERNAL_APP_NOT_SUPPORTED, NO_ORGANIZATION_ID} from '../../util/errorMessages.js'\nimport {buildApp} from '../build/buildApp.js'\nimport {extractCoreAppManifest, resolveTitleUpdate} from '../manifest/extractCoreAppManifest.js'\nimport {type CoreAppManifest} from '../manifest/types.js'\nimport {createUserApplication, generateAppSlug} from './createUserApplication.js'\nimport {\n checkAppId,\n checkAppTarget,\n checkAutoUpdates,\n checkBuild,\n checkPackageVersion,\n type DeployCheckReporter,\n verifyOutputDir,\n} from './deployChecks.js'\nimport {deployDebug} from './deployDebug.js'\nimport {listDeploymentFiles, reportExposes} from './deploymentPlan.js'\nimport {type DeployResult, runDeploy} from './deployRunner.js'\nimport {findUserApplication} from './findUserApplication.js'\nimport {type DeployAppOptions} from './types.js'\nimport {getCoreAppUrl} from './urlUtils.js'\n\nconst APP_PACKAGE = '@sanity/sdk-react'\n\nexport function deployApp(options: DeployAppOptions): Promise<void> {\n return runDeploy(options, {\n listFiles: ({projectRoot, sourceDir}) => listDeploymentFiles(sourceDir, projectRoot.directory),\n run: runAppDeployment,\n type: 'coreApp',\n })\n}\n\n/** Validates the deploy, syncs the title from the manifest, and ships the build. */\nasync function runAppDeployment(\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 organizationId = cliConfig.app?.organizationId\n const appId = getAppId(cliConfig)\n const workbench = getWorkbench(cliConfig)\n const dryRun = !!flags['dry-run']\n\n // A singleton (the Media Library) persists its config instead of hosting an\n // application; anything that exposes a view or service still ships one.\n const deploySingletonConfig = workbench?.deploySingletonConfig ?? false\n const deployApplication = !workbench || workbench.hasInterfaces\n\n const appTitle = workbench\n ? flags.title?.trim() || cliConfig.app?.title?.trim() || workbench.name\n : ''\n\n // A federated app with no entry, view or service would ship a remote with\n // nothing to load — reported first so it fails before any prompt or API call.\n if (workbench) {\n try {\n workbench.assertDeployable()\n } catch (err) {\n reporter.report({\n exitCode: exitCodes.USAGE_ERROR,\n message: getErrorMessage(err),\n solution: 'Declare at least one entry, view, or service in the app',\n status: 'fail',\n })\n }\n }\n\n const isAutoUpdating = checkAutoUpdates(reporter, {cliConfig, flags})\n\n // An application ships the SDK runtime; a media-library config stamps its\n // `sanity` version instead.\n let version: string | null = null\n if (deployApplication) {\n version = await checkPackageVersion(reporter, {moduleName: APP_PACKAGE, workDir})\n } else if (deploySingletonConfig) {\n version = await checkPackageVersion(reporter, {moduleName: 'sanity', workDir})\n }\n\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\n checkAppId(reporter, {cliConfig})\n\n let application: UserApplicationResolved | null = null\n let appCreated = false\n if (flags.external) {\n reporter.report({\n message: EXTERNAL_APP_NOT_SUPPORTED,\n solution: 'Remove the --external flag — apps deploy to Sanity hosting',\n status: 'fail',\n })\n } else if (deployApplication && workbench) {\n // Both modes, so a bad appId fails before the build rather than at the POST.\n await checkAppTarget(reporter, {\n appId,\n isWorkbenchApp: true,\n slug: workbench.slug,\n title: appTitle,\n })\n } else if (deployApplication) {\n ;({application, created: appCreated} = await resolveAppApplication(options, {dryRun, reporter}))\n }\n\n await checkBuild(reporter, {\n build: () =>\n buildApp({\n autoUpdatesEnabled: isAutoUpdating,\n calledFromDeploy: true,\n cliConfig,\n flags,\n outDir: sourceDir,\n output,\n workDir,\n }),\n skipReason: flags.build\n ? undefined\n : 'Build skipped (--no-build) — validating existing output directory',\n successMessage: 'App built',\n })\n\n await verifyOutputDir({isWorkbenchApp: workbench !== null, reporter, sourceDir})\n\n // Manifests aren't strictly essential, so a failure warns and continues\n let manifest: CoreAppManifest | undefined\n try {\n manifest = await extractCoreAppManifest({workDir})\n } catch (err) {\n deployDebug('Error extracting app manifest', err)\n reporter.report({\n message: `Error extracting app manifest: ${getErrorMessage(err)}`,\n status: 'warn',\n })\n }\n\n // Resolve the installation in both modes so the report — dry-run and real —\n // shows whether the config is deployable; a missing one fails the deploy here.\n let installationId: string | undefined\n let config: string | undefined\n const configAppType = workbench?.config?.appType\n if (deploySingletonConfig && organizationId && workbench?.config && configAppType) {\n installationId = await resolveInstallationId({appType: configAppType, organizationId})\n config = summarizeConfig(workbench.config)\n reporter.report(\n installationId\n ? {config, message: config, status: 'pass'}\n : {\n exitCode: exitCodes.USAGE_ERROR,\n message: `No active \"${configAppType}\" installation for organization \"${organizationId}\"`,\n solution: 'Install the Media Library for the organization before deploying its config',\n status: 'fail',\n },\n )\n }\n\n // Report the exposes deploying with the application, both modes.\n const exposes = deployApplication && workbench ? reportExposes(reporter, workbench) : []\n\n // Surface the app's explicit singleton flag when set, both modes.\n if (deployApplication && workbench?.isSingleton !== undefined) {\n reporter.report({\n isSingleton: workbench.isSingleton,\n message: `Singleton: ${workbench.isSingleton}`,\n status: 'pass',\n })\n }\n\n // Dry run stops here — everything below mutates.\n if (dryRun) return\n\n if (installationId && version && configAppType) {\n await deployConfig({\n appType: configAppType,\n installationId,\n output,\n sourceDir,\n version,\n })\n }\n\n // A config-only singleton ships no application, only its config.\n if (!deployApplication) {\n if (installationId && version) {\n return {\n applicationType: 'coreApp',\n applicationVersion: version,\n ...(config ? {config} : {}),\n installationId,\n target: null,\n }\n }\n return\n }\n\n // A real deploy already exited on a version-resolution failure; this narrows the type.\n if (!version) return\n\n // Workbench apps deploy to Brett; plain coreApps use user-applications.\n if (workbench && organizationId) {\n const appId = getAppId(cliConfig)\n const slug = workbench.slug ?? generateAppSlug()\n const {applicationId} = await deployWorkbenchCoreApp({\n appId,\n interfaces: buildExposes(workbench, {\n appName: workbench.name,\n appTitle,\n exposesAppView: workbench.entry !== undefined,\n version,\n }),\n isAutoUpdating,\n isSingleton: workbench.isSingleton,\n organizationId,\n slug,\n sourceDir,\n title: appTitle,\n version,\n })\n logAppDeployed({\n applicationId,\n cliConfig,\n created: !appId,\n organizationId,\n output,\n title: appTitle,\n })\n return {\n applicationType: 'coreApp',\n applicationVersion: version,\n ...(exposes.length > 0 ? {exposes} : {}),\n ...(workbench.isSingleton === undefined ? {} : {isSingleton: workbench.isSingleton}),\n target: {\n action: appId ? 'update' : 'create',\n applicationId,\n // A redeploy ignores the slug, so only a create reports the one it used.\n ...(appId ? {} : {slug}),\n title: appTitle,\n url: getCoreAppUrl(organizationId, applicationId),\n },\n }\n }\n\n // A real deploy has already exited if anything failed; landing here without a\n // resolved application means the deploy target was never resolved.\n if (!application) return\n\n application = await syncApplicationTitle({application, manifest, output})\n await shipAppDeployment({application, isAutoUpdating, manifest, sourceDir, version})\n logAppDeployed({\n applicationId: application.id,\n cliConfig,\n created: appCreated,\n organizationId: application.organizationId,\n output,\n title: application.title,\n })\n return {\n applicationType: 'coreApp',\n applicationVersion: version,\n target: {\n action: appCreated ? 'create' : 'update',\n applicationId: application.id,\n title: application.title ?? null,\n url: getCoreAppUrl(application.organizationId, application.id),\n },\n }\n}\n\n/**\n * Finds the application a real deploy targets, creating one when none is\n * configured. A dry run resolves and reports the target read-only instead.\n */\nasync function resolveAppApplication(\n options: DeployAppOptions,\n {dryRun, reporter}: {dryRun: boolean; reporter: DeployCheckReporter},\n): Promise<{application: UserApplicationResolved | null; created: boolean}> {\n const {cliConfig, flags, output} = options\n const organizationId = cliConfig.app?.organizationId ?? ''\n // Create name from --title or `app.title` config; blank falls back to the prompt\n const title = flags.title?.trim() || cliConfig.app?.title?.trim() || undefined\n\n if (dryRun) {\n await checkAppTarget(reporter, {appId: getAppId(cliConfig), organizationId, title})\n return {application: null, created: false}\n }\n\n let application = await findUserApplication({\n cliConfig,\n organizationId,\n output,\n title,\n unattended: !!flags.yes,\n })\n deployDebug('User application found', application)\n\n if (!application) {\n deployDebug('No user application found. Creating a new one')\n application = await createUserApplication(organizationId, title)\n deployDebug('User application created', application)\n return {application, created: true}\n }\n\n return {application, created: false}\n}\n\n/** Syncs the application title from the manifest when it has changed. */\nasync function syncApplicationTitle({\n application,\n manifest,\n output,\n}: {\n application: UserApplicationResolved\n manifest: CoreAppManifest | undefined\n output: DeployAppOptions['output']\n}): Promise<UserApplicationResolved> {\n const titleUpdate = resolveTitleUpdate(manifest, application)\n if (!titleUpdate) return application\n\n deployDebug('Updating application title from manifest', titleUpdate)\n output.log(\n titleUpdate.from\n ? `Updating title from \"${titleUpdate.from}\" to \"${titleUpdate.to}\"`\n : `Setting application title to \"${titleUpdate.to}\"`,\n )\n const spin = spinner('Updating application title').start()\n try {\n const updated = await updateUserApplication({\n applicationId: application.id,\n appType: 'coreApp',\n body: {title: titleUpdate.to},\n })\n spin.succeed()\n return updated\n } catch (err) {\n spin.fail()\n const message = getErrorMessage(err)\n deployDebug('Error updating application title', {message})\n output.warn(`Error updating application title: ${message}`)\n return application\n }\n}\n\nasync function shipAppDeployment({\n application,\n isAutoUpdating,\n manifest,\n sourceDir,\n version,\n}: {\n application: UserApplication\n isAutoUpdating: boolean\n manifest: CoreAppManifest | undefined\n sourceDir: string\n version: string\n}): Promise<void> {\n const tarball = pack(dirname(sourceDir), {entries: [basename(sourceDir)]}).pipe(createGzip())\n\n const spin = spinner('Deploying...').start()\n try {\n await createDeployment({\n applicationId: application.id,\n isApp: true,\n isAutoUpdating,\n manifest,\n tarball,\n version,\n })\n } catch (error) {\n spin.clear()\n throw error\n }\n spin.succeed()\n}\n\nexport function logAppDeployed({\n applicationId,\n cliConfig,\n created,\n organizationId,\n output,\n title,\n}: {\n applicationId: string\n cliConfig: DeployAppOptions['cliConfig']\n created: boolean\n organizationId: string\n output: DeployAppOptions['output']\n title: string | null\n}): void {\n const url = getCoreAppUrl(organizationId, applicationId)\n const named = title ? ` — \"${title}\"` : ''\n output.log(`\\nSuccess! Application deployed to ${styleText('cyan', url)}${named}`)\n output.log(created ? 'Created a new application.' : 'Updated the existing application.')\n\n if (getAppId(cliConfig)) return\n\n output.log(`\\n════ ${styleText('bold', 'Next step:')} ════`)\n if (created) {\n output.log(\n styleText(\n 'yellow',\n '\\nDeploying again without `deployment.appId` creates another new application.',\n ),\n )\n }\n output.log(\n styleText('bold', '\\nAdd the deployment.appId to your sanity.cli.js or sanity.cli.ts file:'),\n )\n output.log(`\n${styleText(\n 'dim',\n `app: {\n // your application config here…\n}`,\n)},\n${styleText(\n ['bold', 'green'],\n `deployment: {\n appId: '${applicationId}',\n}\\n`,\n)}`)\n}\n"],"names":["basename","dirname","styleText","createGzip","exitCodes","getErrorMessage","spinner","buildExposes","deployConfig","deployCoreApp","deployWorkbenchCoreApp","getWorkbench","resolveInstallationId","summarizeConfig","pack","createDeployment","updateUserApplication","getAppId","EXTERNAL_APP_NOT_SUPPORTED","NO_ORGANIZATION_ID","buildApp","extractCoreAppManifest","resolveTitleUpdate","createUserApplication","generateAppSlug","checkAppId","checkAppTarget","checkAutoUpdates","checkBuild","checkPackageVersion","verifyOutputDir","deployDebug","listDeploymentFiles","reportExposes","runDeploy","findUserApplication","getCoreAppUrl","APP_PACKAGE","deployApp","options","listFiles","projectRoot","sourceDir","directory","run","runAppDeployment","type","reporter","cliConfig","flags","output","workDir","organizationId","app","appId","workbench","dryRun","deploySingletonConfig","deployApplication","hasInterfaces","appTitle","title","trim","name","assertDeployable","err","report","exitCode","USAGE_ERROR","message","solution","status","isAutoUpdating","version","moduleName","application","appCreated","external","isWorkbenchApp","slug","created","resolveAppApplication","build","autoUpdatesEnabled","calledFromDeploy","outDir","skipReason","undefined","successMessage","manifest","installationId","config","configAppType","appType","exposes","isSingleton","applicationType","applicationVersion","target","applicationId","interfaces","appName","exposesAppView","entry","logAppDeployed","length","action","url","syncApplicationTitle","shipAppDeployment","id","unattended","yes","titleUpdate","log","from","to","spin","start","updated","body","succeed","fail","warn","tarball","entries","pipe","isApp","error","clear","named"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/deploy/deployApp.ts"],"sourcesContent":["import {basename, dirname} from 'node:path'\nimport {styleText} from 'node:util'\nimport {createGzip} from 'node:zlib'\n\nimport {exitCodes} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {getCoreAppUrl} from '@sanity/cli-core/util'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {\n buildExposes,\n deployConfig,\n deployCoreApp as deployWorkbenchCoreApp,\n getApplicationUrl,\n getWorkbench,\n resolveInstallationId,\n summarizeConfig,\n} from '@sanity/workbench-cli/deploy'\nimport {pack} from 'tar-fs'\n\nimport {\n createDeployment,\n updateUserApplication,\n type UserApplication,\n type UserApplicationResolved,\n} from '../../services/userApplications.js'\nimport {getAppId} from '../../util/appId.js'\nimport {EXTERNAL_APP_NOT_SUPPORTED, NO_ORGANIZATION_ID} from '../../util/errorMessages.js'\nimport {buildApp} from '../build/buildApp.js'\nimport {extractCoreAppManifest, resolveTitleUpdate} from '../manifest/extractCoreAppManifest.js'\nimport {type CoreAppManifest} from '../manifest/types.js'\nimport {createUserApplication, generateAppSlug} from './createUserApplication.js'\nimport {\n checkAppId,\n checkAppTarget,\n checkAutoUpdates,\n checkBuild,\n checkPackageVersion,\n type DeployCheckReporter,\n verifyOutputDir,\n} from './deployChecks.js'\nimport {deployDebug} from './deployDebug.js'\nimport {listDeploymentFiles, reportExposes} from './deploymentPlan.js'\nimport {type DeployResult, runDeploy} from './deployRunner.js'\nimport {findUserApplication} from './findUserApplication.js'\nimport {type DeployAppOptions} from './types.js'\n\nconst APP_PACKAGE = '@sanity/sdk-react'\n\nexport function deployApp(options: DeployAppOptions): Promise<void> {\n return runDeploy(options, {\n listFiles: ({projectRoot, sourceDir}) => listDeploymentFiles(sourceDir, projectRoot.directory),\n run: runAppDeployment,\n type: 'coreApp',\n })\n}\n\n/** Validates the deploy, syncs the title from the manifest, and ships the build. */\nasync function runAppDeployment(\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 organizationId = cliConfig.app?.organizationId\n const appId = getAppId(cliConfig)\n const workbench = getWorkbench(cliConfig)\n const dryRun = !!flags['dry-run']\n\n // A singleton (the Media Library) persists its config instead of hosting an\n // application; anything that exposes a view or service still ships one.\n const deploySingletonConfig = workbench?.deploySingletonConfig ?? false\n const deployApplication = !workbench || workbench.hasInterfaces\n\n const appTitle = workbench\n ? flags.title?.trim() || cliConfig.app?.title?.trim() || workbench.name\n : ''\n\n // A federated app with no entry, view or service would ship a remote with\n // nothing to load — reported first so it fails before any prompt or API call.\n if (workbench) {\n try {\n workbench.assertDeployable()\n } catch (err) {\n reporter.report({\n exitCode: exitCodes.USAGE_ERROR,\n message: getErrorMessage(err),\n solution: 'Declare at least one entry, view, or service in the app',\n status: 'fail',\n })\n }\n }\n\n const isAutoUpdating = checkAutoUpdates(reporter, {cliConfig, flags})\n\n // An application ships the SDK runtime; a media-library config stamps its\n // `sanity` version instead.\n let version: string | null = null\n if (deployApplication) {\n version = await checkPackageVersion(reporter, {moduleName: APP_PACKAGE, workDir})\n } else if (deploySingletonConfig) {\n version = await checkPackageVersion(reporter, {moduleName: 'sanity', workDir})\n }\n\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\n checkAppId(reporter, {cliConfig})\n\n let application: UserApplicationResolved | null = null\n let appCreated = false\n if (flags.external) {\n reporter.report({\n message: EXTERNAL_APP_NOT_SUPPORTED,\n solution: 'Remove the --external flag — apps deploy to Sanity hosting',\n status: 'fail',\n })\n } else if (deployApplication && workbench) {\n await checkAppTarget(reporter, {\n appId,\n isWorkbenchApp: true,\n slug: workbench.slug,\n title: appTitle,\n })\n } else if (deployApplication) {\n ;({application, created: appCreated} = await resolveAppApplication(options, {dryRun, reporter}))\n }\n\n await checkBuild(reporter, {\n build: () =>\n buildApp({\n autoUpdatesEnabled: isAutoUpdating,\n calledFromDeploy: true,\n cliConfig,\n flags,\n outDir: sourceDir,\n output,\n workDir,\n }),\n skipReason: flags.build\n ? undefined\n : 'Build skipped (--no-build) — validating existing output directory',\n successMessage: 'App built',\n })\n\n await verifyOutputDir({isWorkbenchApp: workbench !== null, reporter, sourceDir})\n\n // Manifests aren't strictly essential, so a failure warns and continues\n let manifest: CoreAppManifest | undefined\n try {\n manifest = await extractCoreAppManifest({workDir})\n } catch (err) {\n deployDebug('Error extracting app manifest', err)\n reporter.report({\n message: `Error extracting app manifest: ${getErrorMessage(err)}`,\n status: 'warn',\n })\n }\n\n // Resolve the installation in both modes so the report — dry-run and real —\n // shows whether the config is deployable; a missing one fails the deploy here.\n let installationId: string | undefined\n let config: string | undefined\n const configAppType = workbench?.config?.appType\n if (deploySingletonConfig && organizationId && workbench?.config && configAppType) {\n installationId = await resolveInstallationId({appType: configAppType, organizationId})\n config = summarizeConfig(workbench.config)\n reporter.report(\n installationId\n ? {config, message: config, status: 'pass'}\n : {\n exitCode: exitCodes.USAGE_ERROR,\n message: `No active \"${configAppType}\" installation for organization \"${organizationId}\"`,\n solution: 'Install the Media Library for the organization before deploying its config',\n status: 'fail',\n },\n )\n }\n\n // Report the exposes deploying with the application, both modes.\n const exposes = deployApplication && workbench ? reportExposes(reporter, workbench) : []\n\n // Surface the app's explicit singleton flag when set, both modes.\n if (deployApplication && workbench?.isSingleton !== undefined) {\n reporter.report({\n isSingleton: workbench.isSingleton,\n message: `Singleton: ${workbench.isSingleton}`,\n status: 'pass',\n })\n }\n\n // Dry run stops here — everything below mutates.\n if (dryRun) return\n\n if (installationId && version && configAppType && organizationId) {\n await deployConfig({\n appType: configAppType,\n installationId,\n organizationId,\n output,\n sourceDir,\n version,\n })\n }\n\n // A config-only singleton ships no application, only its config.\n if (!deployApplication) {\n if (installationId && version) {\n return {\n applicationType: 'coreApp',\n applicationVersion: version,\n ...(config ? {config} : {}),\n installationId,\n target: null,\n }\n }\n return\n }\n\n // A real deploy already exited on a version-resolution failure; this narrows the type.\n if (!version) return\n\n // Workbench apps deploy to Brett; plain coreApps use user-applications.\n if (workbench && organizationId) {\n const appId = getAppId(cliConfig)\n const slug = workbench.slug ?? generateAppSlug()\n const {applicationId} = await deployWorkbenchCoreApp({\n appId,\n interfaces: buildExposes(workbench, {\n appName: workbench.name,\n appTitle,\n exposesAppView: workbench.entry !== undefined,\n version,\n }),\n isAutoUpdating,\n isSingleton: workbench.isSingleton,\n organizationId,\n slug,\n sourceDir,\n title: appTitle,\n version,\n })\n const url = getApplicationUrl({id: applicationId, organizationId, type: 'coreApp'})\n logAppDeployed({\n applicationId,\n cliConfig,\n created: !appId,\n organizationId,\n output,\n title: appTitle,\n url,\n })\n return {\n applicationType: 'coreApp',\n applicationVersion: version,\n ...(exposes.length > 0 ? {exposes} : {}),\n ...(workbench.isSingleton === undefined ? {} : {isSingleton: workbench.isSingleton}),\n target: {\n action: appId ? 'update' : 'create',\n applicationId,\n // A redeploy ignores the slug, so only a create reports the one it used.\n ...(appId ? {} : {slug}),\n title: appTitle,\n url,\n },\n }\n }\n\n // A real deploy has already exited if anything failed; landing here without a\n // resolved application means the deploy target was never resolved.\n if (!application) return\n\n application = await syncApplicationTitle({application, manifest, output})\n await shipAppDeployment({application, isAutoUpdating, manifest, sourceDir, version})\n logAppDeployed({\n applicationId: application.id,\n cliConfig,\n created: appCreated,\n organizationId: application.organizationId,\n output,\n title: application.title,\n })\n return {\n applicationType: 'coreApp',\n applicationVersion: version,\n target: {\n action: appCreated ? 'create' : 'update',\n applicationId: application.id,\n title: application.title ?? null,\n url: getCoreAppUrl(application.organizationId, application.id),\n },\n }\n}\n\n/**\n * Finds the application a real deploy targets, creating one when none is\n * configured. A dry run resolves and reports the target read-only instead.\n */\nasync function resolveAppApplication(\n options: DeployAppOptions,\n {dryRun, reporter}: {dryRun: boolean; reporter: DeployCheckReporter},\n): Promise<{application: UserApplicationResolved | null; created: boolean}> {\n const {cliConfig, flags, output} = options\n const organizationId = cliConfig.app?.organizationId ?? ''\n // Create name from --title or `app.title` config; blank falls back to the prompt\n const title = flags.title?.trim() || cliConfig.app?.title?.trim() || undefined\n\n if (dryRun) {\n await checkAppTarget(reporter, {appId: getAppId(cliConfig), organizationId, title})\n return {application: null, created: false}\n }\n\n let application = await findUserApplication({\n cliConfig,\n organizationId,\n output,\n title,\n unattended: !!flags.yes,\n })\n deployDebug('User application found', application)\n\n if (!application) {\n deployDebug('No user application found. Creating a new one')\n application = await createUserApplication(organizationId, title)\n deployDebug('User application created', application)\n return {application, created: true}\n }\n\n return {application, created: false}\n}\n\n/** Syncs the application title from the manifest when it has changed. */\nasync function syncApplicationTitle({\n application,\n manifest,\n output,\n}: {\n application: UserApplicationResolved\n manifest: CoreAppManifest | undefined\n output: DeployAppOptions['output']\n}): Promise<UserApplicationResolved> {\n const titleUpdate = resolveTitleUpdate(manifest, application)\n if (!titleUpdate) return application\n\n deployDebug('Updating application title from manifest', titleUpdate)\n output.log(\n titleUpdate.from\n ? `Updating title from \"${titleUpdate.from}\" to \"${titleUpdate.to}\"`\n : `Setting application title to \"${titleUpdate.to}\"`,\n )\n const spin = spinner('Updating application title').start()\n try {\n const updated = await updateUserApplication({\n applicationId: application.id,\n appType: 'coreApp',\n body: {title: titleUpdate.to},\n })\n spin.succeed()\n return updated\n } catch (err) {\n spin.fail()\n const message = getErrorMessage(err)\n deployDebug('Error updating application title', {message})\n output.warn(`Error updating application title: ${message}`)\n return application\n }\n}\n\nasync function shipAppDeployment({\n application,\n isAutoUpdating,\n manifest,\n sourceDir,\n version,\n}: {\n application: UserApplication\n isAutoUpdating: boolean\n manifest: CoreAppManifest | undefined\n sourceDir: string\n version: string\n}): Promise<void> {\n const tarball = pack(dirname(sourceDir), {entries: [basename(sourceDir)]}).pipe(createGzip())\n\n const spin = spinner('Deploying...').start()\n try {\n await createDeployment({\n applicationId: application.id,\n isApp: true,\n isAutoUpdating,\n manifest,\n tarball,\n version,\n })\n } catch (error) {\n spin.clear()\n throw error\n }\n spin.succeed()\n}\n\nexport function logAppDeployed({\n applicationId,\n cliConfig,\n created,\n organizationId,\n output,\n title,\n url = getCoreAppUrl(organizationId, applicationId),\n}: {\n applicationId: string\n cliConfig: DeployAppOptions['cliConfig']\n created: boolean\n organizationId: string\n output: DeployAppOptions['output']\n title: string | null\n url?: string\n}): void {\n const named = title ? ` — \"${title}\"` : ''\n output.log(`\\nSuccess! Application deployed to ${styleText('cyan', url)}${named}`)\n output.log(created ? 'Created a new application.' : 'Updated the existing application.')\n\n if (getAppId(cliConfig)) return\n\n output.log(`\\n════ ${styleText('bold', 'Next step:')} ════`)\n if (created) {\n output.log(\n styleText(\n 'yellow',\n '\\nDeploying again without `deployment.appId` creates another new application.',\n ),\n )\n }\n output.log(\n styleText('bold', '\\nAdd the deployment.appId to your sanity.cli.js or sanity.cli.ts file:'),\n )\n output.log(`\n${styleText(\n 'dim',\n `app: {\n // your application config here…\n}`,\n)},\n${styleText(\n ['bold', 'green'],\n `deployment: {\n appId: '${applicationId}',\n}\\n`,\n)}`)\n}\n"],"names":["basename","dirname","styleText","createGzip","exitCodes","getErrorMessage","getCoreAppUrl","spinner","buildExposes","deployConfig","deployCoreApp","deployWorkbenchCoreApp","getApplicationUrl","getWorkbench","resolveInstallationId","summarizeConfig","pack","createDeployment","updateUserApplication","getAppId","EXTERNAL_APP_NOT_SUPPORTED","NO_ORGANIZATION_ID","buildApp","extractCoreAppManifest","resolveTitleUpdate","createUserApplication","generateAppSlug","checkAppId","checkAppTarget","checkAutoUpdates","checkBuild","checkPackageVersion","verifyOutputDir","deployDebug","listDeploymentFiles","reportExposes","runDeploy","findUserApplication","APP_PACKAGE","deployApp","options","listFiles","projectRoot","sourceDir","directory","run","runAppDeployment","type","reporter","cliConfig","flags","output","workDir","organizationId","app","appId","workbench","dryRun","deploySingletonConfig","deployApplication","hasInterfaces","appTitle","title","trim","name","assertDeployable","err","report","exitCode","USAGE_ERROR","message","solution","status","isAutoUpdating","version","moduleName","application","appCreated","external","isWorkbenchApp","slug","created","resolveAppApplication","build","autoUpdatesEnabled","calledFromDeploy","outDir","skipReason","undefined","successMessage","manifest","installationId","config","configAppType","appType","exposes","isSingleton","applicationType","applicationVersion","target","applicationId","interfaces","appName","exposesAppView","entry","url","id","logAppDeployed","length","action","syncApplicationTitle","shipAppDeployment","unattended","yes","titleUpdate","log","from","to","spin","start","updated","body","succeed","fail","warn","tarball","entries","pipe","isApp","error","clear","named"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { exitCodes, getLocalPackageVersion } from '@sanity/cli-core';
|
|
2
2
|
import { getErrorMessage } from '@sanity/cli-core/errors';
|
|
3
|
+
import { getCoreAppUrl } from '@sanity/cli-core/util';
|
|
3
4
|
import { spinner } from '@sanity/cli-core/ux';
|
|
4
5
|
import { checkBuiltOutput } from '@sanity/workbench-cli/deploy';
|
|
5
6
|
import { resolveAppIdIssue } from '../../util/appId.js';
|
|
@@ -9,7 +10,6 @@ import { getAutoUpdateIssueMessage, getAutoUpdateMigrationHint, resolveAutoUpdat
|
|
|
9
10
|
import { checkDir } from './checkDir.js';
|
|
10
11
|
import { deployDebug } from './deployDebug.js';
|
|
11
12
|
import { resolveAppDeployTarget, resolveStudioDeployTarget, resolveWorkbenchApp, resolveWorkbenchStudio } from './resolveDeployTarget.js';
|
|
12
|
-
import { getCoreAppUrl } from './urlUtils.js';
|
|
13
13
|
export async function checkPackageVersion(reporter, { moduleName, workDir }) {
|
|
14
14
|
const version = await getLocalPackageVersion(moduleName, workDir);
|
|
15
15
|
reporter.report(version ? {
|
|
@@ -123,7 +123,7 @@ export async function checkBuild(reporter, { build, skipReason, successMessage }
|
|
|
123
123
|
{
|
|
124
124
|
const { application } = resolution;
|
|
125
125
|
const title = application.title ?? application.appHost;
|
|
126
|
-
const url = getCoreAppUrl(application.organizationId, application.id);
|
|
126
|
+
const url = application.url ?? getCoreAppUrl(application.organizationId, application.id);
|
|
127
127
|
return {
|
|
128
128
|
message: `Deploys to existing application "${title}" at ${url}`,
|
|
129
129
|
status: 'pass',
|
|
@@ -222,7 +222,7 @@ export function describeAppTargetError(err, organizationId) {
|
|
|
222
222
|
}
|
|
223
223
|
});
|
|
224
224
|
}
|
|
225
|
-
/** Same contract as {@link describeAppTarget}, for the studio verdicts. */ export function describeStudioTarget(resolution, { isExternal, title }) {
|
|
225
|
+
/** Same contract as {@link describeAppTarget}, for the studio verdicts. */ export function describeStudioTarget(resolution, { isExternal, isWorkbench, title }) {
|
|
226
226
|
const studioUrl = (host)=>isExternal ? host : `https://${host}.sanity.studio`;
|
|
227
227
|
switch(resolution.type){
|
|
228
228
|
case 'blocked':
|
|
@@ -234,7 +234,7 @@ export function describeAppTargetError(err, organizationId) {
|
|
|
234
234
|
}
|
|
235
235
|
case 'found':
|
|
236
236
|
{
|
|
237
|
-
const url = studioUrl(resolution.application.appHost);
|
|
237
|
+
const url = resolution.application.url ?? studioUrl(resolution.application.appHost);
|
|
238
238
|
return {
|
|
239
239
|
message: `Deploys to existing studio ${url}`,
|
|
240
240
|
status: 'pass',
|
|
@@ -267,10 +267,11 @@ export function describeAppTargetError(err, organizationId) {
|
|
|
267
267
|
}
|
|
268
268
|
case 'would-create':
|
|
269
269
|
{
|
|
270
|
-
|
|
270
|
+
// A workbench studio's URL needs the application id, which only exists after the create.
|
|
271
|
+
const url = isWorkbench ? null : studioUrl(resolution.appHost);
|
|
271
272
|
const titled = title ? ` titled "${title}"` : '';
|
|
272
273
|
return {
|
|
273
|
-
message: isExternal ? `Would register external studio at ${resolution.appHost}${titled}` : `Would create studio hostname ${url}${titled} (name availability is checked on deploy)`,
|
|
274
|
+
message: isExternal ? `Would register external studio at ${resolution.appHost}${titled}` : `Would create studio hostname ${url ?? resolution.appHost}${titled} (name availability is checked on deploy)`,
|
|
274
275
|
status: 'pass',
|
|
275
276
|
// `title || null`, not `?? null`, so target.title tracks the same
|
|
276
277
|
// truthiness the message's `titled` suffix uses (an empty title is no title)
|
|
@@ -287,8 +288,7 @@ export function describeAppTargetError(err, organizationId) {
|
|
|
287
288
|
/**
|
|
288
289
|
* Reports the studio deploy target as a check and returns the resolved target;
|
|
289
290
|
* `isWorkbenchApp` selects the backend. Both modes run it — a real deploy uses
|
|
290
|
-
*
|
|
291
|
-
* studio URL from the resolved slug.
|
|
291
|
+
* it to reject a bad `appId` before building.
|
|
292
292
|
*/ export async function checkStudioTarget(reporter, options) {
|
|
293
293
|
const { title } = options;
|
|
294
294
|
const resolve = options.isWorkbenchApp ? resolveWorkbenchStudio({
|
|
@@ -304,6 +304,7 @@ export function describeAppTargetError(err, organizationId) {
|
|
|
304
304
|
work: async ()=>{
|
|
305
305
|
const check = describeStudioTarget(await resolve, {
|
|
306
306
|
isExternal,
|
|
307
|
+
isWorkbench: !!options.isWorkbenchApp,
|
|
307
308
|
title
|
|
308
309
|
});
|
|
309
310
|
reporter.report(check);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/deploy/deployChecks.ts"],"sourcesContent":["import {type CliConfig, exitCodes, getLocalPackageVersion} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {checkBuiltOutput, type DeployedExpose} from '@sanity/workbench-cli/deploy'\n\nimport {resolveAppIdIssue} from '../../util/appId.js'\nimport {type Check, type CheckReporter, runStep} from '../../util/checks.js'\nimport {APP_ID_NOT_FOUND_IN_ORGANIZATION} from '../../util/errorMessages.js'\nimport {\n getAutoUpdateIssueMessage,\n getAutoUpdateMigrationHint,\n resolveAutoUpdates,\n} from '../build/shouldAutoUpdate.js'\nimport {checkDir} from './checkDir.js'\nimport {deployDebug} from './deployDebug.js'\nimport {\n type AppDeployTargetResolution,\n resolveAppDeployTarget,\n resolveStudioDeployTarget,\n resolveWorkbenchApp,\n resolveWorkbenchStudio,\n type StudioDeployTargetResolution,\n} from './resolveDeployTarget.js'\nimport {type DeployFlags} from './types.js'\nimport {getCoreAppUrl} from './urlUtils.js'\n\n/**\n * Where a deploy resolves to, computed once from the deploy-target verdict. The\n * dry-run report and its JSON both read this, so the human and machine outputs\n * can't drift.\n */\nexport interface DeployTarget {\n /** Whether the deploy creates a new application/studio or updates an existing one. */\n action: 'create' | 'update'\n /** The application the deploy targets; `null` when a deploy would create one. */\n applicationId: string | null\n /** The application's title; `null` when it has none (or isn't created yet). */\n title: string | null\n /** Where the deployed studio/app is reachable; `null` when it can't be resolved yet. */\n url: string | null\n\n /**\n * Slug the deploy creates the application at. Omitted on redeploys, and in a\n * dry run when no slug is configured (it's generated on deploy).\n */\n slug?: string\n}\n\nexport interface DeployCheck extends Check {\n /** Set on the config check with its summary both reporters read. */\n config?: string\n /** Set on the exposes check with the workbench exposes both reporters read. */\n exposes?: DeployedExpose[]\n /** Set on the singleton check when the app declares the flag explicitly. */\n isSingleton?: boolean\n /** Set on the deploy-target check with the resolved target both reporters read. */\n target?: DeployTarget\n /** Set on the package-version check with the version both reporters read. */\n version?: string\n}\n\nexport type DeployCheckReporter = CheckReporter<DeployCheck>\n\nexport async function checkPackageVersion(\n reporter: DeployCheckReporter,\n {moduleName, workDir}: {moduleName: string; workDir: string},\n): Promise<string | null> {\n const version = await getLocalPackageVersion(moduleName, workDir)\n reporter.report(\n version\n ? {message: `Using ${moduleName} ${version}`, status: 'pass', version}\n : {\n message: `Failed to find installed ${moduleName} version`,\n solution: `Install ${moduleName} in this project`,\n status: 'fail',\n },\n )\n return version\n}\n\nexport function checkAutoUpdates(\n reporter: DeployCheckReporter,\n {cliConfig, flags}: {cliConfig: CliConfig; flags: DeployFlags},\n): boolean {\n const {enabled, issue} = resolveAutoUpdates({cliConfig, flags})\n\n if (issue) {\n reporter.report({\n message: getAutoUpdateIssueMessage(issue),\n // A config conflict makes a real deploy refuse to run; deprecations only warn\n status: issue.type === 'conflicting-config' ? 'fail' : 'warn',\n })\n\n // The deprecated top-level config also gets the styled migration edit, the\n // same second warning the build/dev path prints through shouldAutoUpdate.\n if (issue.type === 'deprecated-config') {\n reporter.report({\n message: getAutoUpdateMigrationHint(cliConfig.autoUpdates),\n status: 'warn',\n })\n }\n }\n\n return enabled\n}\n\n/**\n * The dry-run form of the `app.id` config check a real deploy runs in\n * `findUserApplication`: a conflict fails (both `app.id` and `deployment.appId`\n * set), the deprecated config alone warns.\n */\nexport function checkAppId(\n reporter: DeployCheckReporter,\n {cliConfig}: {cliConfig: CliConfig},\n): void {\n const issue = resolveAppIdIssue(cliConfig)\n if (issue === 'conflicting-config') {\n reporter.report({\n message: 'Both `app.id` (deprecated) and `deployment.appId` are set',\n solution: 'Remove `app.id` from sanity.cli.ts',\n status: 'fail',\n })\n } else if (issue === 'deprecated-config') {\n reporter.report({\n message: 'The `app.id` config is deprecated',\n solution: 'Move it to `deployment.appId` in sanity.cli.ts',\n status: 'warn',\n })\n }\n}\n\nexport async function checkBuild(\n reporter: DeployCheckReporter,\n {\n build,\n skipReason,\n successMessage,\n }: {build: () => Promise<void>; skipReason: string | undefined; successMessage: string},\n): Promise<void> {\n if (skipReason) {\n reporter.report({message: skipReason, status: 'skip'})\n return\n }\n\n await runStep(reporter, {\n debug: deployDebug,\n formatError: (err) => `Build failed: ${getErrorMessage(err)}`,\n name: 'build',\n solution: 'Fix the build error above, then retry',\n work: async () => {\n await build()\n reporter.report({message: successMessage, status: 'pass'})\n },\n })\n}\n\n/**\n * The deploy directory must exist and hold the right build output: a federation\n * remote for a workbench app, an `index.html` SPA otherwise.\n */\nexport async function verifyOutputDir({\n isWorkbenchApp,\n reporter,\n sourceDir,\n}: {\n isWorkbenchApp: boolean\n reporter: DeployCheckReporter\n sourceDir: string\n}): Promise<void> {\n const spin = spinner('Verifying local content...').start()\n const verifyBuild = isWorkbenchApp ? checkBuiltOutput : checkDir\n try {\n await verifyBuild(sourceDir)\n spin.succeed()\n } catch (err) {\n spin.fail()\n deployDebug('Error checking directory', err)\n reporter.report({\n message: getErrorMessage(err),\n solution: 'Run the build first, or check the output directory',\n status: 'fail',\n })\n }\n}\n\n/**\n * The single diagnosis for each app deploy-target verdict, shared by the\n * dry-run report and the real deploy's unattended error paths so message,\n * fix, and exit code can't drift between the two.\n */\nexport function describeAppTarget(\n resolution: AppDeployTargetResolution,\n {slug, title}: {slug?: string; title?: string} = {},\n): DeployCheck {\n switch (resolution.type) {\n case 'blocked': {\n return {message: `Deploy target not resolved — ${resolution.message}`, status: 'skip'}\n }\n case 'found': {\n const {application} = resolution\n const title = application.title ?? application.appHost\n const url = getCoreAppUrl(application.organizationId, application.id)\n return {\n message: `Deploys to existing application \"${title}\" at ${url}`,\n status: 'pass',\n target: {\n action: 'update',\n applicationId: application.id,\n title: application.title ?? null,\n url,\n },\n }\n }\n case 'invalid': {\n return {\n message: APP_ID_NOT_FOUND_IN_ORGANIZATION,\n solution: 'Check `deployment.appId` matches an app in your organization',\n status: 'fail',\n }\n }\n case 'needs-input': {\n return {\n exitCode: exitCodes.USAGE_ERROR,\n message: `No \\`deployment.appId\\` configured (${resolution.existing.length} existing ${resolution.existing.length === 1 ? 'application' : 'applications'} to choose from)`,\n solution: 'Add `deployment.appId` to sanity.cli.ts',\n status: 'fail',\n }\n }\n // Without --title, creating an app needs a prompt no unattended run can answer\n case 'would-create': {\n if (title) {\n return {\n message: `Would create a new application \"${title}\"${slug ? ` with slug \"${slug}\"` : ''}`,\n status: 'pass',\n target: {\n action: 'create',\n applicationId: null,\n ...(slug ? {slug} : {}),\n title,\n url: null,\n },\n }\n }\n return {\n exitCode: exitCodes.USAGE_ERROR,\n message: 'No application to deploy to — creating one needs a title',\n solution:\n 'Pass `--title \"<name>\"` or set `app.title` in sanity.cli.ts to create one, or set `deployment.appId` to deploy to an existing app',\n status: 'fail',\n }\n }\n }\n}\n\nexport function describeAppTargetError(err: unknown, organizationId: string | undefined): string {\n return (err as {statusCode?: number})?.statusCode === 403\n ? `You don’t have permission to view applications for the configured organization ID (\"${organizationId}\"). Verify the organization ID, or ask your organization’s admin for access.`\n : `Failed to resolve deploy target: ${getErrorMessage(err)}`\n}\n\n/**\n * Reports the app deploy target as a check and returns the resolved target;\n * `isWorkbenchApp` selects the backend. Both modes run it — a real deploy uses\n * it to reject a bad `appId` before building.\n */\nexport async function checkAppTarget(\n reporter: DeployCheckReporter,\n options:\n | {appId: string | undefined; isWorkbenchApp: true; slug?: string; title?: string}\n | {\n appId: string | undefined\n isWorkbenchApp?: false\n organizationId: string | undefined\n title?: string\n },\n): Promise<DeployTarget | null> {\n const {title} = options\n if (options.isWorkbenchApp) {\n const {appId, slug} = options\n return runStep(reporter, {\n debug: deployDebug,\n name: 'target',\n work: async () => {\n const check = describeAppTarget(await resolveWorkbenchApp({appId}), {slug, title})\n reporter.report(check)\n return check.target ?? null\n },\n })\n }\n\n const {appId, organizationId} = options\n return runStep(reporter, {\n debug: deployDebug,\n formatError: (err) => describeAppTargetError(err, organizationId),\n name: 'target',\n work: async () => {\n const check = describeAppTarget(await resolveAppDeployTarget({appId, organizationId}), {\n title,\n })\n reporter.report(check)\n return check.target ?? null\n },\n })\n}\n\n/** Same contract as {@link describeAppTarget}, for the studio verdicts. */\nexport function describeStudioTarget(\n resolution: StudioDeployTargetResolution,\n {isExternal, title}: {isExternal: boolean; title?: string},\n): DeployCheck {\n const studioUrl = (host: string) => (isExternal ? host : `https://${host}.sanity.studio`)\n\n switch (resolution.type) {\n case 'blocked': {\n return {message: `Deploy target not resolved — ${resolution.message}`, status: 'skip'}\n }\n case 'found': {\n const url = studioUrl(resolution.application.appHost)\n return {\n message: `Deploys to existing studio ${url}`,\n status: 'pass',\n target: {\n action: 'update',\n applicationId: resolution.application.id,\n title: resolution.application.title ?? null,\n url,\n },\n }\n }\n case 'invalid': {\n return {\n // A bad host is a usage error; other invalid targets exit 1\n exitCode: resolution.reason === 'invalid-host' ? exitCodes.USAGE_ERROR : 1,\n message: resolution.message,\n solution: 'Check `studioHost` and `deployment.appId` in sanity.cli.ts',\n status: 'fail',\n }\n }\n case 'needs-input': {\n return {\n exitCode: exitCodes.USAGE_ERROR,\n message: isExternal ? 'No external studio URL configured' : 'No studio hostname configured',\n solution: isExternal\n ? 'Set `studioHost` in sanity.cli.ts, or pass the full URL with --url'\n : 'Set `studioHost` in sanity.cli.ts, or pass a hostname with --url',\n status: 'fail',\n }\n }\n case 'would-create': {\n const url = studioUrl(resolution.appHost)\n const titled = title ? ` titled \"${title}\"` : ''\n return {\n message: isExternal\n ? `Would register external studio at ${resolution.appHost}${titled}`\n : `Would create studio hostname ${url}${titled} (name availability is checked on deploy)`,\n status: 'pass',\n // `title || null`, not `?? null`, so target.title tracks the same\n // truthiness the message's `titled` suffix uses (an empty title is no title)\n target: {action: 'create', applicationId: null, title: title || null, url},\n }\n }\n }\n}\n\n/**\n * Reports the studio deploy target as a check and returns the resolved target;\n * `isWorkbenchApp` selects the backend. Both modes run it — a real deploy uses\n * the returned target to reject a bad `appId` before building and to report the\n * studio URL from the resolved slug.\n */\nexport async function checkStudioTarget(\n reporter: DeployCheckReporter,\n options:\n | {\n appId: string | undefined\n isExternal: boolean\n isWorkbenchApp?: false\n projectId: string | undefined\n studioHost: string | undefined\n title: string | undefined\n urlFlag: string | undefined\n }\n | {\n appId: string | undefined\n isWorkbenchApp: true\n studioHost: string | undefined\n title?: string\n },\n): Promise<DeployTarget | null> {\n const {title} = options\n const resolve = options.isWorkbenchApp\n ? resolveWorkbenchStudio({appId: options.appId, studioHost: options.studioHost})\n : resolveStudioDeployTarget(options)\n // Workbench studios always deploy to Sanity hosting, never an external URL.\n const isExternal = options.isWorkbenchApp ? false : options.isExternal\n\n return runStep(reporter, {\n debug: deployDebug,\n formatError: (err) => `Failed to resolve deploy target: ${getErrorMessage(err)}`,\n name: 'target',\n work: async () => {\n const check = describeStudioTarget(await resolve, {isExternal, title})\n reporter.report(check)\n return check.target ?? null\n },\n })\n}\n"],"names":["exitCodes","getLocalPackageVersion","getErrorMessage","spinner","checkBuiltOutput","resolveAppIdIssue","runStep","APP_ID_NOT_FOUND_IN_ORGANIZATION","getAutoUpdateIssueMessage","getAutoUpdateMigrationHint","resolveAutoUpdates","checkDir","deployDebug","resolveAppDeployTarget","resolveStudioDeployTarget","resolveWorkbenchApp","resolveWorkbenchStudio","getCoreAppUrl","checkPackageVersion","reporter","moduleName","workDir","version","report","message","status","solution","checkAutoUpdates","cliConfig","flags","enabled","issue","type","autoUpdates","checkAppId","checkBuild","build","skipReason","successMessage","debug","formatError","err","name","work","verifyOutputDir","isWorkbenchApp","sourceDir","spin","start","verifyBuild","succeed","fail","describeAppTarget","resolution","slug","title","application","appHost","url","organizationId","id","target","action","applicationId","exitCode","USAGE_ERROR","existing","length","describeAppTargetError","statusCode","checkAppTarget","options","appId","check","describeStudioTarget","isExternal","studioUrl","host","reason","titled","checkStudioTarget","resolve","studioHost"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/deploy/deployChecks.ts"],"sourcesContent":["import {type CliConfig, exitCodes, getLocalPackageVersion} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {getCoreAppUrl} from '@sanity/cli-core/util'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {checkBuiltOutput, type DeployedExpose} from '@sanity/workbench-cli/deploy'\n\nimport {resolveAppIdIssue} from '../../util/appId.js'\nimport {type Check, type CheckReporter, runStep} from '../../util/checks.js'\nimport {APP_ID_NOT_FOUND_IN_ORGANIZATION} from '../../util/errorMessages.js'\nimport {\n getAutoUpdateIssueMessage,\n getAutoUpdateMigrationHint,\n resolveAutoUpdates,\n} from '../build/shouldAutoUpdate.js'\nimport {checkDir} from './checkDir.js'\nimport {deployDebug} from './deployDebug.js'\nimport {\n type AppDeployTargetResolution,\n resolveAppDeployTarget,\n resolveStudioDeployTarget,\n resolveWorkbenchApp,\n resolveWorkbenchStudio,\n type StudioDeployTargetResolution,\n} from './resolveDeployTarget.js'\nimport {type DeployFlags} from './types.js'\n\n/**\n * Where a deploy resolves to, computed once from the deploy-target verdict. The\n * dry-run report and its JSON both read this, so the human and machine outputs\n * can't drift.\n */\nexport interface DeployTarget {\n /** Whether the deploy creates a new application/studio or updates an existing one. */\n action: 'create' | 'update'\n /** The application the deploy targets; `null` when a deploy would create one. */\n applicationId: string | null\n /** The application's title; `null` when it has none (or isn't created yet). */\n title: string | null\n /** Where the deployed studio/app is reachable; `null` when it can't be resolved yet. */\n url: string | null\n\n /**\n * Slug the deploy creates the application at. Omitted on redeploys, and in a\n * dry run when no slug is configured (it's generated on deploy).\n */\n slug?: string\n}\n\nexport interface DeployCheck extends Check {\n /** Set on the config check with its summary both reporters read. */\n config?: string\n /** Set on the exposes check with the workbench exposes both reporters read. */\n exposes?: DeployedExpose[]\n /** Set on the singleton check when the app declares the flag explicitly. */\n isSingleton?: boolean\n /** Set on the deploy-target check with the resolved target both reporters read. */\n target?: DeployTarget\n /** Set on the package-version check with the version both reporters read. */\n version?: string\n}\n\nexport type DeployCheckReporter = CheckReporter<DeployCheck>\n\nexport async function checkPackageVersion(\n reporter: DeployCheckReporter,\n {moduleName, workDir}: {moduleName: string; workDir: string},\n): Promise<string | null> {\n const version = await getLocalPackageVersion(moduleName, workDir)\n reporter.report(\n version\n ? {message: `Using ${moduleName} ${version}`, status: 'pass', version}\n : {\n message: `Failed to find installed ${moduleName} version`,\n solution: `Install ${moduleName} in this project`,\n status: 'fail',\n },\n )\n return version\n}\n\nexport function checkAutoUpdates(\n reporter: DeployCheckReporter,\n {cliConfig, flags}: {cliConfig: CliConfig; flags: DeployFlags},\n): boolean {\n const {enabled, issue} = resolveAutoUpdates({cliConfig, flags})\n\n if (issue) {\n reporter.report({\n message: getAutoUpdateIssueMessage(issue),\n // A config conflict makes a real deploy refuse to run; deprecations only warn\n status: issue.type === 'conflicting-config' ? 'fail' : 'warn',\n })\n\n // The deprecated top-level config also gets the styled migration edit, the\n // same second warning the build/dev path prints through shouldAutoUpdate.\n if (issue.type === 'deprecated-config') {\n reporter.report({\n message: getAutoUpdateMigrationHint(cliConfig.autoUpdates),\n status: 'warn',\n })\n }\n }\n\n return enabled\n}\n\n/**\n * The dry-run form of the `app.id` config check a real deploy runs in\n * `findUserApplication`: a conflict fails (both `app.id` and `deployment.appId`\n * set), the deprecated config alone warns.\n */\nexport function checkAppId(\n reporter: DeployCheckReporter,\n {cliConfig}: {cliConfig: CliConfig},\n): void {\n const issue = resolveAppIdIssue(cliConfig)\n if (issue === 'conflicting-config') {\n reporter.report({\n message: 'Both `app.id` (deprecated) and `deployment.appId` are set',\n solution: 'Remove `app.id` from sanity.cli.ts',\n status: 'fail',\n })\n } else if (issue === 'deprecated-config') {\n reporter.report({\n message: 'The `app.id` config is deprecated',\n solution: 'Move it to `deployment.appId` in sanity.cli.ts',\n status: 'warn',\n })\n }\n}\n\nexport async function checkBuild(\n reporter: DeployCheckReporter,\n {\n build,\n skipReason,\n successMessage,\n }: {build: () => Promise<void>; skipReason: string | undefined; successMessage: string},\n): Promise<void> {\n if (skipReason) {\n reporter.report({message: skipReason, status: 'skip'})\n return\n }\n\n await runStep(reporter, {\n debug: deployDebug,\n formatError: (err) => `Build failed: ${getErrorMessage(err)}`,\n name: 'build',\n solution: 'Fix the build error above, then retry',\n work: async () => {\n await build()\n reporter.report({message: successMessage, status: 'pass'})\n },\n })\n}\n\n/**\n * The deploy directory must exist and hold the right build output: a federation\n * remote for a workbench app, an `index.html` SPA otherwise.\n */\nexport async function verifyOutputDir({\n isWorkbenchApp,\n reporter,\n sourceDir,\n}: {\n isWorkbenchApp: boolean\n reporter: DeployCheckReporter\n sourceDir: string\n}): Promise<void> {\n const spin = spinner('Verifying local content...').start()\n const verifyBuild = isWorkbenchApp ? checkBuiltOutput : checkDir\n try {\n await verifyBuild(sourceDir)\n spin.succeed()\n } catch (err) {\n spin.fail()\n deployDebug('Error checking directory', err)\n reporter.report({\n message: getErrorMessage(err),\n solution: 'Run the build first, or check the output directory',\n status: 'fail',\n })\n }\n}\n\n/**\n * The single diagnosis for each app deploy-target verdict, shared by the\n * dry-run report and the real deploy's unattended error paths so message,\n * fix, and exit code can't drift between the two.\n */\nexport function describeAppTarget(\n resolution: AppDeployTargetResolution,\n {slug, title}: {slug?: string; title?: string} = {},\n): DeployCheck {\n switch (resolution.type) {\n case 'blocked': {\n return {message: `Deploy target not resolved — ${resolution.message}`, status: 'skip'}\n }\n case 'found': {\n const {application} = resolution\n const title = application.title ?? application.appHost\n const url = application.url ?? getCoreAppUrl(application.organizationId, application.id)\n return {\n message: `Deploys to existing application \"${title}\" at ${url}`,\n status: 'pass',\n target: {\n action: 'update',\n applicationId: application.id,\n title: application.title ?? null,\n url,\n },\n }\n }\n case 'invalid': {\n return {\n message: APP_ID_NOT_FOUND_IN_ORGANIZATION,\n solution: 'Check `deployment.appId` matches an app in your organization',\n status: 'fail',\n }\n }\n case 'needs-input': {\n return {\n exitCode: exitCodes.USAGE_ERROR,\n message: `No \\`deployment.appId\\` configured (${resolution.existing.length} existing ${resolution.existing.length === 1 ? 'application' : 'applications'} to choose from)`,\n solution: 'Add `deployment.appId` to sanity.cli.ts',\n status: 'fail',\n }\n }\n // Without --title, creating an app needs a prompt no unattended run can answer\n case 'would-create': {\n if (title) {\n return {\n message: `Would create a new application \"${title}\"${slug ? ` with slug \"${slug}\"` : ''}`,\n status: 'pass',\n target: {\n action: 'create',\n applicationId: null,\n ...(slug ? {slug} : {}),\n title,\n url: null,\n },\n }\n }\n return {\n exitCode: exitCodes.USAGE_ERROR,\n message: 'No application to deploy to — creating one needs a title',\n solution:\n 'Pass `--title \"<name>\"` or set `app.title` in sanity.cli.ts to create one, or set `deployment.appId` to deploy to an existing app',\n status: 'fail',\n }\n }\n }\n}\n\nexport function describeAppTargetError(err: unknown, organizationId: string | undefined): string {\n return (err as {statusCode?: number})?.statusCode === 403\n ? `You don’t have permission to view applications for the configured organization ID (\"${organizationId}\"). Verify the organization ID, or ask your organization’s admin for access.`\n : `Failed to resolve deploy target: ${getErrorMessage(err)}`\n}\n\n/**\n * Reports the app deploy target as a check and returns the resolved target;\n * `isWorkbenchApp` selects the backend. Both modes run it — a real deploy uses\n * it to reject a bad `appId` before building.\n */\nexport async function checkAppTarget(\n reporter: DeployCheckReporter,\n options:\n | {appId: string | undefined; isWorkbenchApp: true; slug?: string; title?: string}\n | {\n appId: string | undefined\n isWorkbenchApp?: false\n organizationId: string | undefined\n title?: string\n },\n): Promise<DeployTarget | null> {\n const {title} = options\n if (options.isWorkbenchApp) {\n const {appId, slug} = options\n return runStep(reporter, {\n debug: deployDebug,\n name: 'target',\n work: async () => {\n const check = describeAppTarget(await resolveWorkbenchApp({appId}), {slug, title})\n reporter.report(check)\n return check.target ?? null\n },\n })\n }\n\n const {appId, organizationId} = options\n return runStep(reporter, {\n debug: deployDebug,\n formatError: (err) => describeAppTargetError(err, organizationId),\n name: 'target',\n work: async () => {\n const check = describeAppTarget(await resolveAppDeployTarget({appId, organizationId}), {\n title,\n })\n reporter.report(check)\n return check.target ?? null\n },\n })\n}\n\n/** Same contract as {@link describeAppTarget}, for the studio verdicts. */\nexport function describeStudioTarget(\n resolution: StudioDeployTargetResolution,\n {isExternal, isWorkbench, title}: {isExternal: boolean; isWorkbench?: boolean; title?: string},\n): DeployCheck {\n const studioUrl = (host: string) => (isExternal ? host : `https://${host}.sanity.studio`)\n\n switch (resolution.type) {\n case 'blocked': {\n return {message: `Deploy target not resolved — ${resolution.message}`, status: 'skip'}\n }\n case 'found': {\n const url = resolution.application.url ?? studioUrl(resolution.application.appHost)\n return {\n message: `Deploys to existing studio ${url}`,\n status: 'pass',\n target: {\n action: 'update',\n applicationId: resolution.application.id,\n title: resolution.application.title ?? null,\n url,\n },\n }\n }\n case 'invalid': {\n return {\n // A bad host is a usage error; other invalid targets exit 1\n exitCode: resolution.reason === 'invalid-host' ? exitCodes.USAGE_ERROR : 1,\n message: resolution.message,\n solution: 'Check `studioHost` and `deployment.appId` in sanity.cli.ts',\n status: 'fail',\n }\n }\n case 'needs-input': {\n return {\n exitCode: exitCodes.USAGE_ERROR,\n message: isExternal ? 'No external studio URL configured' : 'No studio hostname configured',\n solution: isExternal\n ? 'Set `studioHost` in sanity.cli.ts, or pass the full URL with --url'\n : 'Set `studioHost` in sanity.cli.ts, or pass a hostname with --url',\n status: 'fail',\n }\n }\n case 'would-create': {\n // A workbench studio's URL needs the application id, which only exists after the create.\n const url = isWorkbench ? null : studioUrl(resolution.appHost)\n const titled = title ? ` titled \"${title}\"` : ''\n return {\n message: isExternal\n ? `Would register external studio at ${resolution.appHost}${titled}`\n : `Would create studio hostname ${url ?? resolution.appHost}${titled} (name availability is checked on deploy)`,\n status: 'pass',\n // `title || null`, not `?? null`, so target.title tracks the same\n // truthiness the message's `titled` suffix uses (an empty title is no title)\n target: {action: 'create', applicationId: null, title: title || null, url},\n }\n }\n }\n}\n\n/**\n * Reports the studio deploy target as a check and returns the resolved target;\n * `isWorkbenchApp` selects the backend. Both modes run it — a real deploy uses\n * it to reject a bad `appId` before building.\n */\nexport async function checkStudioTarget(\n reporter: DeployCheckReporter,\n options:\n | {\n appId: string | undefined\n isExternal: boolean\n isWorkbenchApp?: false\n projectId: string | undefined\n studioHost: string | undefined\n title: string | undefined\n urlFlag: string | undefined\n }\n | {\n appId: string | undefined\n isWorkbenchApp: true\n studioHost: string | undefined\n title?: string\n },\n): Promise<DeployTarget | null> {\n const {title} = options\n const resolve = options.isWorkbenchApp\n ? resolveWorkbenchStudio({appId: options.appId, studioHost: options.studioHost})\n : resolveStudioDeployTarget(options)\n // Workbench studios always deploy to Sanity hosting, never an external URL.\n const isExternal = options.isWorkbenchApp ? false : options.isExternal\n\n return runStep(reporter, {\n debug: deployDebug,\n formatError: (err) => `Failed to resolve deploy target: ${getErrorMessage(err)}`,\n name: 'target',\n work: async () => {\n const check = describeStudioTarget(await resolve, {\n isExternal,\n isWorkbench: !!options.isWorkbenchApp,\n title,\n })\n reporter.report(check)\n return check.target ?? null\n },\n })\n}\n"],"names":["exitCodes","getLocalPackageVersion","getErrorMessage","getCoreAppUrl","spinner","checkBuiltOutput","resolveAppIdIssue","runStep","APP_ID_NOT_FOUND_IN_ORGANIZATION","getAutoUpdateIssueMessage","getAutoUpdateMigrationHint","resolveAutoUpdates","checkDir","deployDebug","resolveAppDeployTarget","resolveStudioDeployTarget","resolveWorkbenchApp","resolveWorkbenchStudio","checkPackageVersion","reporter","moduleName","workDir","version","report","message","status","solution","checkAutoUpdates","cliConfig","flags","enabled","issue","type","autoUpdates","checkAppId","checkBuild","build","skipReason","successMessage","debug","formatError","err","name","work","verifyOutputDir","isWorkbenchApp","sourceDir","spin","start","verifyBuild","succeed","fail","describeAppTarget","resolution","slug","title","application","appHost","url","organizationId","id","target","action","applicationId","exitCode","USAGE_ERROR","existing","length","describeAppTargetError","statusCode","checkAppTarget","options","appId","check","describeStudioTarget","isExternal","isWorkbench","studioUrl","host","reason","titled","checkStudioTarget","resolve","studioHost"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { createGzip } from 'node:zlib';
|
|
|
4
4
|
import { formatSchemaValidation, SchemaExtractionError } from '@sanity/cli-build/_internal/extract';
|
|
5
5
|
import { exitCodes } from '@sanity/cli-core';
|
|
6
6
|
import { spinner } from '@sanity/cli-core/ux';
|
|
7
|
-
import { buildExposes, deployStudio as deployWorkbenchStudio, getWorkbench } from '@sanity/workbench-cli/deploy';
|
|
7
|
+
import { buildExposes, deployStudio as deployWorkbenchStudio, getApplicationUrl, getWorkbench } from '@sanity/workbench-cli/deploy';
|
|
8
8
|
import { pack } from 'tar-fs';
|
|
9
9
|
import { createDeployment } from '../../services/userApplications.js';
|
|
10
10
|
import { getAppId } from '../../util/appId.js';
|
|
@@ -66,7 +66,6 @@ export function deployStudio(options) {
|
|
|
66
66
|
// resolve/create on user-applications, unchanged.
|
|
67
67
|
let application = null;
|
|
68
68
|
let studioCreated = false;
|
|
69
|
-
let studioTarget = null;
|
|
70
69
|
if (workbench && !isExternal) {
|
|
71
70
|
reporter.report(organizationId ? {
|
|
72
71
|
message: `Organization: ${organizationId}`,
|
|
@@ -76,9 +75,7 @@ export function deployStudio(options) {
|
|
|
76
75
|
solution: 'Add `app.organizationId` to sanity.cli.ts',
|
|
77
76
|
status: 'fail'
|
|
78
77
|
});
|
|
79
|
-
|
|
80
|
-
// the deploy result.
|
|
81
|
-
studioTarget = await checkStudioTarget(reporter, {
|
|
78
|
+
await checkStudioTarget(reporter, {
|
|
82
79
|
appId,
|
|
83
80
|
isWorkbenchApp: true,
|
|
84
81
|
studioHost: cliConfig.studioHost,
|
|
@@ -145,10 +142,16 @@ export function deployStudio(options) {
|
|
|
145
142
|
version,
|
|
146
143
|
workspaces: toWorkspaces(studioManifest)
|
|
147
144
|
});
|
|
145
|
+
const url = getApplicationUrl({
|
|
146
|
+
id: applicationId,
|
|
147
|
+
organizationId,
|
|
148
|
+
type: 'studio'
|
|
149
|
+
});
|
|
148
150
|
logWorkbenchStudioDeployed({
|
|
149
151
|
applicationId,
|
|
150
152
|
cliConfig,
|
|
151
|
-
output
|
|
153
|
+
output,
|
|
154
|
+
url
|
|
152
155
|
});
|
|
153
156
|
return {
|
|
154
157
|
applicationType: 'studio',
|
|
@@ -160,7 +163,7 @@ export function deployStudio(options) {
|
|
|
160
163
|
action: appId ? 'update' : 'create',
|
|
161
164
|
applicationId,
|
|
162
165
|
title: appTitle,
|
|
163
|
-
url
|
|
166
|
+
url
|
|
164
167
|
}
|
|
165
168
|
};
|
|
166
169
|
}
|
|
@@ -332,8 +335,8 @@ function toWorkspaces(manifest) {
|
|
|
332
335
|
title: workspace.title
|
|
333
336
|
}));
|
|
334
337
|
}
|
|
335
|
-
/** Renders the workbench studio's deploy result; the appId hint shows only when none is configured. */ function logWorkbenchStudioDeployed({ applicationId, cliConfig, output }) {
|
|
336
|
-
output.log(`\nSuccess! Studio deployed`);
|
|
338
|
+
/** Renders the workbench studio's deploy result; the appId hint shows only when none is configured. */ function logWorkbenchStudioDeployed({ applicationId, cliConfig, output, url }) {
|
|
339
|
+
output.log(`\nSuccess! Studio deployed to ${styleText('cyan', url)}`);
|
|
337
340
|
if (getAppId(cliConfig)) return;
|
|
338
341
|
output.log(`\nAdd ${styleText('cyan', `appId: '${applicationId}'`)}`);
|
|
339
342
|
output.log(`to the \`deployment\` section in sanity.cli.js or sanity.cli.ts`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/deploy/deployStudio.ts"],"sourcesContent":["import {basename, dirname} 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 {exitCodes} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {\n type BrettWorkspace,\n buildExposes,\n deployStudio as deployWorkbenchStudio,\n getWorkbench,\n} from '@sanity/workbench-cli/deploy'\nimport {type StudioManifest} from 'sanity'\nimport {pack} from 'tar-fs'\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 {createStudioUserApplication} from './createUserApplication.js'\nimport {\n checkAutoUpdates,\n checkBuild,\n checkPackageVersion,\n checkStudioTarget,\n type DeployCheckReporter,\n type DeployTarget,\n verifyOutputDir,\n} from './deployChecks.js'\nimport {deployDebug} from './deployDebug.js'\nimport {listDeploymentFiles, reportExposes} from './deploymentPlan.js'\nimport {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\n // A federated app deploys through Sanity's build/hosting pipeline, which\n // --external skips — fail before doing any other work.\n if (isExternal && isWorkbenchApp) {\n reporter.report({\n exitCode: exitCodes.USAGE_ERROR,\n message: 'Deploying a federated application to an external host is not yet supported',\n solution: 'Remove the --external flag to deploy to Sanity hosting',\n status: 'fail',\n })\n }\n\n const appTitle = workbench\n ? flags.title?.trim() || cliConfig.app?.title?.trim() || workbench.name\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 // 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 studioTarget: DeployTarget | null = null\n if (workbench && !isExternal) {\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 // Both modes, so a bad appId fails before the build; its resolved URL feeds\n // the deploy result.\n studioTarget = await checkStudioTarget(reporter, {\n appId,\n isWorkbenchApp: true,\n studioHost: cliConfig.studioHost,\n title: appTitle,\n })\n } else {\n ;({application, created: studioCreated} = await resolveStudioApplication(options, {\n dryRun,\n reporter,\n }))\n }\n\n await checkBuild(reporter, {\n build: () =>\n buildStudio({\n autoUpdatesEnabled: isAutoUpdating,\n calledFromDeploy: true,\n cliConfig,\n flags,\n outDir: sourceDir,\n output,\n workDir,\n }),\n skipReason: studioBuildSkipReason({build: flags.build, isExternal}),\n successMessage: 'Studio built',\n })\n\n if (!isExternal) {\n await verifyOutputDir({isWorkbenchApp, reporter, sourceDir})\n }\n\n // Report the exposes deploying with the studio, both modes. External studios\n // host their own bundle, so nothing registers.\n const exposes = workbench && !isExternal ? reportExposes(reporter, workbench) : []\n\n // Dry run stops here — everything below mutates.\n if (dryRun) return\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, {isExternal})\n // Workbench studios deploy to Brett; plain studios use user-applications.\n if (workbench && !isExternal && organizationId) {\n const {applicationId} = await deployWorkbenchStudio({\n appId,\n interfaces: buildExposes(workbench, {\n appName: workbench.name,\n appTitle,\n exposesAppView: true,\n version,\n }),\n isAutoUpdating,\n organizationId,\n output,\n projectId,\n sourceDir,\n studioHost: cliConfig.studioHost,\n title: appTitle,\n version,\n workspaces: toWorkspaces(studioManifest),\n })\n logWorkbenchStudioDeployed({applicationId, cliConfig, output})\n return {\n applicationType: 'studio',\n applicationVersion: version,\n ...(exposes.length > 0 ? {exposes} : {}),\n target: {\n action: appId ? 'update' : 'create',\n applicationId,\n title: appTitle,\n url: studioTarget?.url ?? null,\n },\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 applicationType: 'studio',\n applicationVersion: version,\n target: {\n action: studioCreated ? 'create' : 'update',\n applicationId: application.id,\n title: application.title ?? null,\n url: location,\n },\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 {isExternal}: {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 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) {\n output.error(formatSchemaValidation(error.validation || []), {exit: 1})\n }\n output.error(`Error deploying studio schemas and manifests: ${error}`, {exit: 1})\n }\n\n if (!studioManifest) {\n output.error('Failed to generate studio manifest. Please check your schemas and manifests.', {\n exit: 1,\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 = pack(dirname(sourceDir), {entries: [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\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 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}: {\n applicationId: string\n cliConfig: DeployAppOptions['cliConfig']\n output: DeployAppOptions['output']\n}): void {\n output.log(`\\nSuccess! Studio deployed`)\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\nfunction studioBuildSkipReason({build, isExternal}: {build: boolean; isExternal: boolean}) {\n if (isExternal) 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","styleText","createGzip","formatSchemaValidation","SchemaExtractionError","exitCodes","spinner","buildExposes","deployStudio","deployWorkbenchStudio","getWorkbench","pack","createDeployment","getAppId","NO_ORGANIZATION_ID","NO_PROJECT_ID","buildStudio","createStudioUserApplication","checkAutoUpdates","checkBuild","checkPackageVersion","checkStudioTarget","verifyOutputDir","deployDebug","listDeploymentFiles","reportExposes","runDeploy","deployStudioSchemasAndManifests","findUserApplicationForStudio","STUDIO_PACKAGE","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","report","exitCode","USAGE_ERROR","message","solution","status","appTitle","title","trim","name","isAutoUpdating","version","moduleName","application","studioCreated","studioTarget","studioHost","created","resolveStudioApplication","build","autoUpdatesEnabled","calledFromDeploy","outDir","skipReason","studioBuildSkipReason","successMessage","exposes","studioManifest","uploadStudioSchema","applicationId","interfaces","appName","exposesAppView","workspaces","toWorkspaces","logWorkbenchStudioDeployed","applicationType","applicationVersion","length","target","action","url","location","shipStudioDeployment","id","undefined","urlFlag","unattended","yes","log","registered","urlType","configPath","path","outPath","schemaRequired","verbose","error","validation","exit","tarball","entries","pipe","spin","start","isApp","manifest","fail","succeed","named","example","map","workspace","basePath","dataset","icon","subtitle"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/deploy/deployStudio.ts"],"sourcesContent":["import {basename, dirname} 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 {exitCodes} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {\n type BrettWorkspace,\n buildExposes,\n deployStudio as deployWorkbenchStudio,\n getApplicationUrl,\n getWorkbench,\n} from '@sanity/workbench-cli/deploy'\nimport {type StudioManifest} from 'sanity'\nimport {pack} from 'tar-fs'\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 {createStudioUserApplication} from './createUserApplication.js'\nimport {\n checkAutoUpdates,\n checkBuild,\n checkPackageVersion,\n checkStudioTarget,\n type DeployCheckReporter,\n verifyOutputDir,\n} from './deployChecks.js'\nimport {deployDebug} from './deployDebug.js'\nimport {listDeploymentFiles, reportExposes} from './deploymentPlan.js'\nimport {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\n // A federated app deploys through Sanity's build/hosting pipeline, which\n // --external skips — fail before doing any other work.\n if (isExternal && isWorkbenchApp) {\n reporter.report({\n exitCode: exitCodes.USAGE_ERROR,\n message: 'Deploying a federated application to an external host is not yet supported',\n solution: 'Remove the --external flag to deploy to Sanity hosting',\n status: 'fail',\n })\n }\n\n const appTitle = workbench\n ? flags.title?.trim() || cliConfig.app?.title?.trim() || workbench.name\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 // 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 if (workbench && !isExternal) {\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 await checkStudioTarget(reporter, {\n appId,\n isWorkbenchApp: true,\n studioHost: cliConfig.studioHost,\n title: appTitle,\n })\n } else {\n ;({application, created: studioCreated} = await resolveStudioApplication(options, {\n dryRun,\n reporter,\n }))\n }\n\n await checkBuild(reporter, {\n build: () =>\n buildStudio({\n autoUpdatesEnabled: isAutoUpdating,\n calledFromDeploy: true,\n cliConfig,\n flags,\n outDir: sourceDir,\n output,\n workDir,\n }),\n skipReason: studioBuildSkipReason({build: flags.build, isExternal}),\n successMessage: 'Studio built',\n })\n\n if (!isExternal) {\n await verifyOutputDir({isWorkbenchApp, reporter, sourceDir})\n }\n\n // Report the exposes deploying with the studio, both modes. External studios\n // host their own bundle, so nothing registers.\n const exposes = workbench && !isExternal ? reportExposes(reporter, workbench) : []\n\n // Dry run stops here — everything below mutates.\n if (dryRun) return\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, {isExternal})\n // Workbench studios deploy to Brett; plain studios use user-applications.\n if (workbench && !isExternal && organizationId) {\n const {applicationId} = await deployWorkbenchStudio({\n appId,\n interfaces: buildExposes(workbench, {\n appName: workbench.name,\n appTitle,\n exposesAppView: true,\n version,\n }),\n isAutoUpdating,\n organizationId,\n output,\n projectId,\n sourceDir,\n studioHost: cliConfig.studioHost,\n title: appTitle,\n version,\n workspaces: toWorkspaces(studioManifest),\n })\n const url = getApplicationUrl({id: applicationId, organizationId, type: 'studio'})\n logWorkbenchStudioDeployed({applicationId, cliConfig, output, url})\n return {\n applicationType: 'studio',\n applicationVersion: version,\n ...(exposes.length > 0 ? {exposes} : {}),\n target: {\n action: appId ? 'update' : 'create',\n applicationId,\n title: appTitle,\n url,\n },\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 applicationType: 'studio',\n applicationVersion: version,\n target: {\n action: studioCreated ? 'create' : 'update',\n applicationId: application.id,\n title: application.title ?? null,\n url: location,\n },\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 {isExternal}: {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 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) {\n output.error(formatSchemaValidation(error.validation || []), {exit: 1})\n }\n output.error(`Error deploying studio schemas and manifests: ${error}`, {exit: 1})\n }\n\n if (!studioManifest) {\n output.error('Failed to generate studio manifest. Please check your schemas and manifests.', {\n exit: 1,\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 = pack(dirname(sourceDir), {entries: [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\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 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\nfunction studioBuildSkipReason({build, isExternal}: {build: boolean; isExternal: boolean}) {\n if (isExternal) 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","styleText","createGzip","formatSchemaValidation","SchemaExtractionError","exitCodes","spinner","buildExposes","deployStudio","deployWorkbenchStudio","getApplicationUrl","getWorkbench","pack","createDeployment","getAppId","NO_ORGANIZATION_ID","NO_PROJECT_ID","buildStudio","createStudioUserApplication","checkAutoUpdates","checkBuild","checkPackageVersion","checkStudioTarget","verifyOutputDir","deployDebug","listDeploymentFiles","reportExposes","runDeploy","deployStudioSchemasAndManifests","findUserApplicationForStudio","STUDIO_PACKAGE","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","report","exitCode","USAGE_ERROR","message","solution","status","appTitle","title","trim","name","isAutoUpdating","version","moduleName","application","studioCreated","studioHost","created","resolveStudioApplication","build","autoUpdatesEnabled","calledFromDeploy","outDir","skipReason","studioBuildSkipReason","successMessage","exposes","studioManifest","uploadStudioSchema","applicationId","interfaces","appName","exposesAppView","workspaces","toWorkspaces","url","id","logWorkbenchStudioDeployed","applicationType","applicationVersion","length","target","action","location","shipStudioDeployment","undefined","urlFlag","unattended","yes","log","registered","urlType","configPath","path","outPath","schemaRequired","verbose","error","validation","exit","tarball","entries","pipe","spin","start","isApp","manifest","fail","succeed","named","example","map","workspace","basePath","dataset","icon","subtitle"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getApplication } from '@sanity/workbench-cli/deploy';
|
|
1
|
+
import { getApplication, getApplicationUrl } from '@sanity/workbench-cli/deploy';
|
|
2
2
|
import { getUserApplication, getUserApplications } from '../../services/userApplications.js';
|
|
3
3
|
import { APP_ID_NOT_FOUND_IN_ORGANIZATION } from '../../util/errorMessages.js';
|
|
4
4
|
import { normalizeUrl, validateUrl } from './urlUtils.js';
|
|
@@ -170,7 +170,8 @@ async function resolveAppById(appId) {
|
|
|
170
170
|
appHost: application.slug ?? '',
|
|
171
171
|
id: application.id,
|
|
172
172
|
organizationId: application.organizationId,
|
|
173
|
-
title: application.title
|
|
173
|
+
title: application.title,
|
|
174
|
+
url: getApplicationUrl(application)
|
|
174
175
|
},
|
|
175
176
|
type: 'found'
|
|
176
177
|
} : {
|